You need to enable JavaScript to run this app. 如何在React/TypeScript中获取音频文件的时长(以秒为单位)
优惠活动
大模型
产品
解决方案
定价
更多

如何在React/TypeScript中获取音频文件的时长(以秒为单位)

React/TypeScript 场景下获取音频File对象时长的实现

原生File对象仅携带文件名称、大小、MIME类型等基础元数据,不存在内置的音频时长属性,可通过浏览器原生Audio接口解析媒体元数据,最终获取以秒为单位的时长值。

实现核心逻辑

  • 将File对象通过URL.createObjectURL()转换为浏览器可识别的临时本地URL
  • 创建脱离DOM树的Audio实例,监听元数据加载完成事件获取时长
  • 拿到结果后及时调用URL.revokeObjectURL()释放临时URL,避免内存泄漏
  • 增加文件类型校验、解析失败的异常捕获逻辑

可复用工具函数实现

/**
 * 解析音频File的时长(单位:秒)
 * @param audioFile 选中的音频文件对象
 * @returns 解析成功返回时长秒数,失败抛出错误信息
 */
export const getAudioDuration = (audioFile: File): Promise<number> => {
  return new Promise((resolve, reject) => {
    // 前置校验文件类型
    if (!audioFile.type.startsWith('audio/')) {
      reject(new Error('传入文件不属于音频格式'))
      return
    }

    const tempAudioUrl = URL.createObjectURL(audioFile)
    const audioElement = new Audio()

    // 元数据加载完成时触发,此时可直接读取准确时长,无需等待全文件缓冲
    audioElement.onloadedmetadata = () => {
      URL.revokeObjectURL(tempAudioUrl)
      resolve(audioElement.duration)
    }

    // 解析异常分支处理
    audioElement.onerror = () => {
      URL.revokeObjectURL(tempAudioUrl)
      reject(new Error('音频解析失败,可能文件损坏或格式不受当前环境支持'))
    }

    audioElement.src = tempAudioUrl
  })
}

React组件内的使用示例

搭配原生文件选择输入框的处理逻辑,可直接在事件回调中调用上述工具函数:

const AudioUploader = () => {
  const handleFileSelect = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const targetFile = e.target.files?.[0]
    if (!targetFile) return

    try {
      const durationInSeconds = await getAudioDuration(targetFile)
      // 后续业务逻辑可直接使用秒数格式的时长
      console.log(`音频时长:${durationInSeconds.toFixed(2)} 秒`)
    } catch (error) {
      console.error('获取音频时长失败:', error)
    }
  }

  return <input type="file" accept="audio/*" onChange={handleFileSelect} />
}

常见注意事项

  • 不要依赖File上的自定义audio属性:该属性并非Web标准定义的原生属性,通常是第三方业务库给File对象挂载的扩展字段,原生运行环境下不存在,直接访问会触发类型或运行时报错
  • 优先监听onloadedmetadata事件获取时长:相比canplaythrough事件,该事件仅需浏览器加载完文件头部元数据即可触发,无需等待整个音频文件缓冲,大文件场景下响应速度更快
  • 必须释放临时URL:每次调用URL.createObjectURL()生成的临时链接都会占用内存,若不手动释放,在多文件上传、页面频繁切换场景下会累积造成内存泄漏
  • 特殊格式兼容:如果解析后返回的时长值为Infinity,说明当前音频是无固定总长度的流式格式(比如HLS直播流切片),属于正常返回,可根据业务场景做兼容判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 07:45:07