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

JavaScript使用Audio构造器获取音频时长返回NaN如何解决

问题根因

你拿到NaN的核心原因是 音频元数据的加载是异步操作:调用new Audio(element)只是创建了音频实例、触发了资源加载请求,此时音频的时长、编码等元数据还没有完成拉取解析,直接读取duration属性就会返回NaN。

解决方案

可以监听音频的loadedmetadata事件,等元数据加载完成后再读取时长属性即可。如果需要批量拿到所有音频的时长,可以用Promise包装做批量异步处理:

基础事件监听写法

const audioArray = [
    '1.mp3',
    '2.mp3',
    '3.mp3',
    '4.mp3'
]

audioArray.forEach((element)=>{
    const audioElement = new Audio(element);
    // 元数据加载完成后触发回调
    audioElement.addEventListener('loadedmetadata', () => {
        console.log(`${element} 时长:`, audioElement.duration);
    })
    // 加载失败的异常兜底
    audioElement.addEventListener('error', (err) => {
        console.error(`${element} 加载失败:`, err)
    })
})

批量收集时长写法

如果需要把所有音频时长汇总后统一处理,可以用Promise.allSettled实现:

const audioArray = [
    '1.mp3',
    '2.mp3',
    '3.mp3',
    '4.mp3'
]

// 封装单个音频时长获取方法
const getAudioDuration = (audioSrc) => {
    return new Promise((resolve, reject) => {
        const audio = new Audio(audioSrc);
        audio.addEventListener('loadedmetadata', () => resolve({
            src: audioSrc,
            duration: audio.duration
        }))
        audio.addEventListener('error', (err) => reject({
            src: audioSrc,
            error: err
        }))
    })
}

// 批量获取所有音频时长
Promise.allSettled(audioArray.map(item => getAudioDuration(item)))
.then(results => {
    results.forEach(res => {
        if(res.status === 'fulfilled') {
            console.log(`${res.value.src} 时长:`, res.value.duration)
        } else {
            console.error(`${res.reason.src} 加载失败:`, res.reason.error)
        }
    })
})

注意事项

  • 本地调试如果直接用file://协议打开页面,部分浏览器会因为跨域限制无法正常加载本地音频资源,建议用本地服务启动调试
  • 返回的时长单位为秒,若需要转换为分秒格式可自行做数值换算

内容的提问来源于stack exchange,提问作者Harshu Prasad Shukla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:36:04