项目环境:Vite + Vue3 +TypeScript

使用music-metadata-browser

Github地址:Borewit/music-metadata-browser: Browser version of music-metadata parser Supporting a wide range of audio and tag formats. (github.com)

music-metadata-browser is a metadata parser, supporting virtual any audio format and tag header around.

安装

cnpm install music-metadata-browser

引入

import * as musicMetadata from 'music-metadata-browser';

使用

  1. 提供BlobFile类型的对象: parseBlob function.
  2. 提供URLfetch the audio track from.

parseBlob function

Parse an audio file from a Blob or File.

let blob;

musicMetadata.parseBlob(blob).then(metadata => {
// metadata has all the metadata found in the blob or file
});

Or with async/await if you prefer:

(async () => {
let blob; // File or Blob

const metadata = await musicMetadata.parseBlob(blob);
// metadata has all the metadata found in the blob or file
});

fetchUrl function

(async () => {
const metadata = await musicMetadata.fetchFromUrl(audioTrackUrl, options);
});

踩坑实录

好了,官网的介绍很美好,使用看起来也很方便,可是我实际上使用的时候,就是各种undefined,包括buffer等等一些很底层的东西。。。。

首先我这里是通过element-uiupload拿到的文件,里面的raw本身就是File类型的,在log里面可以看到(此处没图),然后我试着转Blob类型,还是不行

然后看到这么一句:If you prefer to parse files or streams server (node.js) side, you should use music-metadata instead.

虽然好像不太符合,但好歹试试吧,结果还是不行

然后我又去找有没有其他方案,比如看到了jsmediatags,还是不行,而且配置和使用上更加复杂

然后我又去issues里面找找看有没有希望

解决

结果还真有,但是是已经close的issue:Can’t use this package with vite 3 · Issue #836 · Borewit/music-metadata-browser (github.com)

(所以为什么close掉呢,明明完全没解决,也没有在readme上注明 神金

just one plugin: https://github.com/grikomsn/vite-plugin-ngmi-polyfill

安装

cnpm install vite vite-plugin-ngmi-polyfill -D

使用

修改vite.config.ts

import { NgmiPolyfill } from "vite-plugin-ngmi-polyfill";

export default defineConfig({
plugins: [NgmiPolyfill()],
});

就可以了,就是这么简单

插播一下

拿到元数据后,可以发现里面的封面图片,是一个uint8array的数组,那么如何显示呢?(利用img标签,audiovideo同理)

网上方法不止一种,但是花里胡哨的感觉不如直接用Blob,虽然缺点是重启一下就没了,但是这里也只是一个小工具,一次性的用,管他呢

321上代码

// 创建一个 Blob 对象
const blob = new Blob([common?.picture?.[0].data], { type: 'image/jpeg' });
// 创建一个 Blob URL
const blobUrl = typeof common.picture==='undefined'?'':URL.createObjectURL(blob);

然后把这个url储存起来,后面直接调用即可

<el-table-column prop="cover" label="封面" align="center">
<!-- 图片的显示 -->
<template #default="scope">
<img :src="scope.row.cover" min-width="90" height="90" />
</template>
</el-table-column>

这里的img在创建时,cover已经存在了,直接显示没问题,不需要别的操作

那么如果是组件先出来的,src在后面才有的呢?其实也很简单,给组件绑定一个ref对象,通过ref对象赋src就可以了

321上代码

// 播放音频
const audioRef=ref()
const handlePlay=async (index:number,row:{name:string})=>{
const raw:File=audioList.value.find(obj=>obj.name===row.name)?.raw
const blob=await new Blob([raw],{type:raw.type})
audioRef.value.src=URL.createObjectURL(blob)
}
<audio ref="audioRef" controls autoplay style="height:40px; width:90%;">
</audio>

哈哈 没想到吧 又卡了这么久 真的很无语

下篇稍微没那么精彩 但是也很精彩((((