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

不使用JS库或Node.js 循环获取数组内MP3时长遇NaN如何解决

问题原因
  • 设置audio元素的src后,音频元数据加载是浏览器异步执行的,你同步读取duration时元数据还未加载完成,所以返回NaN。
  • 遍历数组时仅能拿到最后一个MP3的时长,是因为循环过程中你同步修改了同一个audio元素的src,循环执行完毕时src已经被覆盖为数组最后一项的地址,前面绑定的onloadedmetadata事件触发时,读取的都是最终的src对应的元数据。
修复方案

用Promise封装单条音频的元数据加载逻辑,配合async/await按顺序迭代数组,保证前一个音频加载完成、拿到时长后再处理下一个条目,示例代码如下:

// 你的歌曲数组,可根据实际格式调整
const songList = [
  { artistName: "示例歌手1", songName: "示例歌曲1" },
  { artistName: "示例歌手2", songName: "示例歌曲2" }
]
const getDuration = document.querySelector('.preload-audio')

// 封装单个音频元数据加载方法
function loadSingleAudio(artist, song) {
  return new Promise((resolve, reject) => {
    getDuration.src = `static/mp3/${artist} - ${song}.mp3`
    getDuration.onloadedmetadata = () => {
      resolve({
        artist: artist,
        song: song,
        duration: getDuration.duration // 单位为秒
      })
    }
    getDuration.onerror = (err) => {
      reject(new Error(`音频${artist} - ${song}加载失败: ${err.message}`))
    }
  })
}

// 按顺序批量获取所有音频时长
async function getAudioDurations() {
  const result = []
  // 用for of配合await保证顺序执行
  for (const songItem of songList) {
    try {
      const audioMeta = await loadSingleAudio(songItem.artistName, songItem.songName)
      result.push(audioMeta)
      // 此处可添加单条音频处理逻辑
      console.log(audioMeta)
    } catch (err) {
      console.error(err)
    }
  }
  // 所有条目处理完成后可拿到全部结果
  console.log('全部时长获取完成:', result)
}

// 启动执行
getAudioDurations()

如果不需要保留加载顺序,也可以给每个音频创建独立的audio元素并行加载,速度会更快,但会占用更多内存。

内容的提问来源于stack exchange,提问作者vvhitearmor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:54:07