MediaSource 的 duration 属性需在特定条件下安全设置:MediaSource 已连接且 readyState 为 "open" 或 "ended",所有 SourceBuffer 非 updating 状态,避免在 seeking 或 play 中修改;典型用于直播转点播或录制回放场景,须监听 updateend 后校验状态再赋值,不可自动推导,设小会截断播放,设大无副作用但需精度控制。

MediaSource 的 duration 属性不能直接“动态更新”流媒体总时长——它是一个可写属性,但必须在特定条件下安全设置,否则会抛出错误。 实际上,它的作用是显式告知浏览器媒体缓冲区的最终时长,主要用于 MSE(Media Source Extensions)场景中处理非标准或持续生成的流(如直播转点播、DASH/HLS 分片拼接、实时录制回放等)。关键在于“何时设、怎么设、设多少”。
必须满足的前提条件
在调用 mediaSource.duration = newDuration 前,需同时满足:
-
MediaSource 已连接到 ,且
readyState为"open"或"ended"; -
所有 SourceBuffer 都处于非
updating状态(即没有正在 append 的操作); -
未启用自动播放逻辑干扰:避免在
seeking或play过程中强行修改(易触发InvalidStateError)。
典型适用场景与设置时机
常见于以下两类动态流:
-
直播转点播(DVR)回放:服务端持续推送新分片,客户端按需扩展已缓存内容的逻辑终点。例如,当前已缓冲 0–128 秒,服务端通知“总可回看时长已达 150 秒”,此时可在追加完最新分片后、且
sourceBuffer.updating === false时执行:mediaSource.duration = 150; -
本地录制后生成可拖拽回放流:使用
MediaRecorder录制并分段写入SourceBuffer,录制结束前不知道总时长。待最后一段 append 完成、updateend触发后,再根据实际累计时长赋值:mediaSource.duration = recorderTotalTime;
安全修改 duration 的推荐流程
避免异常的核心是“守候 + 确认”:
- 监听每个
SourceBuffer的updateend事件; - 在该事件回调中检查所有
sourceBuffer.updating === false; - 确认
mediaSource.readyState === "open"; - 再执行赋值,例如:
if (!sourceBuffer.updating) { mediaSource.duration = Math.max(mediaSource.duration, newCalculatedDuration); }
注意事项与常见陷阱
duration 不是自动推导值:它不会根据已 append 的时间范围自动计算,必须由应用层主动维护和更新;
设小了会截断播放:若设为小于已缓冲最大时间戳的值(如已缓存到 120s 却设为 100s),后续 seek 到 100–120s 区间将失败;
设大了无副作用但无意义:只要不超出真实内容范围,浏览器仅用它做 UI(如进度条最大值)和 seek 边界判断;
不支持 fractional 秒以外的精度:建议保留 3 位小数(如 128.345),避免浮点误差导致 seek 卡顿。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











