audio标签无法直接设置播放时长,需用JavaScript通过currentTime跳转并监听timeupdate事件控制起止;duration初始为NaN,须等loadedmetadata事件触发后读取,且换源后需重新绑定该事件。

audio 标签本身不提供「设置播放时长」的能力——它只能播放完整音频,不能直接截取或限制播放区间。所谓“设置播放时长”,实际是两种常见需求的混淆:**读取真实时长**(只读)或**控制播放起止时间**(靠 JavaScript)。下面分场景说清楚。
为什么 audio.duration 初始是 NaN?
浏览器加载音频后,duration 不会立刻可用。它依赖音频头信息解析完成,而这个过程异步发生。loadedmetadata 事件才是可靠信号:
- 在
load或canplay事件里读duration,大概率还是NaN -
readyState === 1(即HAVE_METADATA)才表示元数据就绪,此时读duration才安全 - 流式资源(如无
Content-Length的 MP3、HLS)可能返回Infinity,不是 bug,是语义表达“总长未知”
如何用 JavaScript 控制播放起始和结束时间?
真正能“设置播放区间”的,是 currentTime 和手动暂停逻辑。浏览器不支持原生的 start/end 属性(HTML 属性或 DOM 属性均不存在)。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 用
audio.currentTime = 30跳转到第 30 秒开始播放 - 监听
timeupdate事件,持续检查当前时间是否超限:if (audio.currentTime >= 60) audio.pause() - 避免用
setTimeout模拟,因为播放可能卡顿、暂停、seek,导致时间判断失准 - 若需精确循环某一段(如 10–25 秒),应在
ended或timeupdate中重置currentTime并调用play()
动态换源后 duration 读不到?
每次改 audio.src,之前绑定的 loadedmetadata 事件不会复用,必须重新监听:
- 不要只绑一次事件;每次赋值新
src后,都要重新加addEventListener('loadedmetadata', ...) - 推荐用
{ once: true }避免重复绑定:audio.addEventListener('loadedmetadata', handler, { once: true }) - 跨域音频若没配
Access-Control-Allow-Origin,loadedmetadata根本不会触发,duration永远NaN—— 这时连错误都难捕获,只能靠服务端提前返回时长字段
loadedmetadata,后者靠 currentTime + 事件监听。两者混用时,最容易漏掉的是换源后未重绑事件,或者在非 HAVE_METADATA 状态下强行读 duration。


















