在没有 javascript 库或 nodejs 的情况下获取 mp3 的持续时间

getting duration of mp3 without javascript library or nodejs

我的 html 中有一个音频元素,我为数组中的每个项目提供了一个 mp3 文件,效果很好。我想要发生的是它加载它的元数据并读取它的持续时间,然后继续到数组中的下一个项目。我尝试使用 `getDuartion.onloadedmetadata' 但那只得到数组中最后一个 mp3 文件的持续时间。使用下面的代码,它记录了正确的音频标签,但持续时间 returns 为 NaN。不确定该怎么做才能完成这项工作。

getDuration = document.querySelector('.preload-audio')
getDuration.src = `static/mp3/${artistName} - ${songName}.mp3`

console.log(getDuration)
console.log(getDuration.duration)

您必须等待它加载。一旦浏览器从文件加载元数据,持续时间就可用。

您可以使用 onloadeddata Event 来实现。

console.log("direct: audioexample.duration =",audioexample.duration);
audioexample.addEventListener('loadeddata', function(event) {
  if(event.target.readyState >= 2) {
    console.log("waiting: audioexample.duration =",event.target.duration);
  }
});
<audio id="audioexample" src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" controls></audio>

如果你想加载多个文件的数据,你必须在有数据后更改src。

这可以使用承诺来完成。

(async () => {
  const audio = document.createElement('audio');
  const list = [
    'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
    'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3',
    'some/404/mp3'
  ];
  audio.preload = "metadata";
  for (const item of list) {
      audio.src = item;
      let time = Date.now();
      // wait for it, but max 10 secs, this should skip 404 errors
      while (isNaN(audio.duration) && Date.now() - time < 10000) {
        await new Promise(r => setTimeout(r,50));
      }
      console.log(audio.src, audio.duration);
  }
})()

另一种方法是,为所有现有音频元素创建一个侦听器:

document.querySelectorAll("audio").forEach(audio => {
  audio.addEventListener('loadeddata', ({ target }) => {
    if (target.readyState >= 2) {
      console.log(target.src, target.duration);
    }
  });
  audio.addEventListener("error", ({ target, error }) => {
    console.error(target.src, error);
  });
})
<audio src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" preload="metadata" controls></audio>
<audio src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3" preload="metadata" controls></audio>