在没有 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>
我的 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>