You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:30:02