MediaSource.endOfStream()需手动调用以通知流结束;应在所有分片追加完成、sourceBuffer.updating为false且mediaSource.readyState为"open"时调用,调用后状态变为"ended"。

MediaSource.endOfStream() 用于通知浏览器媒体流已全部接收完毕,可开始播放或进入完成状态。它不是自动调用的,必须由开发者在确认所有媒体片段(如通过 sourceBuffer.appendBuffer())都成功追加后手动调用。
何时调用 endOfStream()?
该方法应在以下情况调用:
- 所有分片(如 MP4 fragments、WebM chunks)均已通过
sourceBuffer.appendBuffer()成功添加,且没有更多数据待加载; - 明确知道流已“自然结束”(例如点播视频全部加载完成),而非因网络中断或用户暂停导致暂停;
-
sourceBuffer.updating为false,且mediaSource.readyState为"open"(确保 MediaSource 处于可操作状态)。
常见调用方式与注意事项
典型流程如下:
- 监听
sourceBuffer的updateend事件,每次追加完成后检查是否还有剩余分片; - 当最后一个分片追加成功并触发
updateend后,立即调用mediaSource.endOfStream(); - 若调用前
mediaSource.readyState !== "open",会抛出InvalidStateError; - 调用后,
mediaSource.readyState变为"ended",HTMLMediaElement将停止等待新数据,可正常播放至结尾或触发ended事件。
错误处理与边界情况
实际使用中需防范以下问题:
立即学习“前端免费学习笔记(深入)”;
- 重复调用
endOfStream()会报错,建议加标志位控制仅执行一次; - 若流是直播或持续推流(非点播),不应调用此方法,否则媒体元素会提前终止;
- 加载失败时(如
sourceBuffer触发error或updateend后buffered无增长),应避免调用,并考虑调用mediaSource.abort()清理状态; - 某些浏览器对
endOfStream()后的 seek 行为支持不一,若需跳转,建议在调用前完成 seek 操作。
简单示例代码片段
假设已初始化 MediaSource 和 SourceBuffer:
let hasEnded = false;
function appendAndEnd(chunk) {
if (sourceBuffer.updating || mediaSource.readyState !== 'open') return;
sourceBuffer.addEventListener('updateend', () => {
if (!hasEnded && !moreChunksAvailable()) {
mediaSource.endOfStream();
hasEnded = true;
}
}, { once: true });
sourceBuffer.appendBuffer(chunk);
}



















