ReactJS中如何从type为file的input输入框获取上传音乐文件的信息?
音频上传元数据提取方案
你当前编写的代码仅能获取音频文件的基础属性(大小、MIME类型),歌手、封面、专辑名这类信息存储在音频文件内置的ID3标签中,需要解析该标签才能提取。
完整实现代码
1. ID3标签解析工具函数
// 传入音频文件对象,返回解析后的元数据 const parseAudioMetadata = (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { const buffer = e.target.result; const dataView = new DataView(buffer); const metadata = { title: file.name.replace(/\.[^/.]+$/, ""), artist: "未知", album: "未知", year: "", cover: null }; // 解析ID3v1标签(位于文件末尾128字节) const id3v1Offset = dataView.byteLength - 128; if (dataView.getUint8(id3v1Offset) === 0x54 && dataView.getUint8(id3v1Offset+1) === 0x41 && dataView.getUint8(id3v1Offset+2) === 0x47) { metadata.title = decodeURIComponent(escape(String.fromCharCode(...new Uint8Array(buffer, id3v1Offset+3, 30)))).trim() || metadata.title; metadata.artist = decodeURIComponent(escape(String.fromCharCode(...new Uint8Array(buffer, id3v1Offset+33, 30)))).trim() || metadata.artist; metadata.album = decodeURIComponent(escape(String.fromCharCode(...new Uint8Array(buffer, id3v1Offset+63, 30)))).trim() || metadata.album; metadata.year = decodeURIComponent(escape(String.fromCharCode(...new Uint8Array(buffer, id3v1Offset+93, 4)))).trim(); } // 解析ID3v2标签(位于文件开头,用于提取封面) if (dataView.getUint8(0) === 0x49 && dataView.getUint8(1) === 0x44 && dataView.getUint8(2) === 0x33) { let pos = 10; while (pos < dataView.byteLength - 10) { const frameId = String.fromCharCode(dataView.getUint8(pos), dataView.getUint8(pos+1), dataView.getUint8(pos+2), dataView.getUint8(pos+3)); const frameSize = dataView.getUint32(pos + 4, false); if (frameId === 'APIC') { // APIC帧存储封面数据 const frameData = new Uint8Array(buffer, pos + 10, frameSize - 10); const mimeTypeEndIndex = frameData.indexOf(0); const mimeType = String.fromCharCode(...frameData.slice(0, mimeTypeEndIndex)); const coverData = frameData.slice(mimeTypeEndIndex + 2); metadata.cover = `data:${mimeType};base64,${btoa(String.fromCharCode(...coverData))}`; break; } pos += 10 + frameSize; } } resolve(metadata); }; reader.onerror = reject; reader.readAsArrayBuffer(file); }); };
2. 修改后的文件选择回调函数
const selectMusic = async (e, file) => { if(file.size < 10485760 && file.type.includes('audio/')){ const audioMeta = await parseAudioMetadata(file); // 直接使用解析后的字段即可 console.log('歌曲名:', audioMeta.title); console.log('歌手:', audioMeta.artist); console.log('封面链接:', audioMeta.cover); // 封面可直接赋值给img标签的src属性展示 } };
注意事项
- 上述代码支持解析主流MP3、FLAC等音频格式的ID3v1、ID3v2标签,覆盖绝大多数场景
- 若音频文件未内置ID3标签,会默认取文件名作为歌曲名,其余字段显示为未知
- 提取到的封面为base64格式,无需额外处理即可直接在页面渲染
内容的提问来源于stack exchange,提问作者Hodjaev Azamat
相关产品推荐
相关产品推荐

