通过 HTML 音频和视频元素,您只需提供一个 src 网址,即可加载、解码和播放媒体:
<video src='foo.webm'></video>
这在简单的使用情形下非常实用,但对于自适应流式传输等技术,Media Source Extensions API (MSE) 可提供更多控制。MSE 支持通过 JavaScript 构建来自音频或视频片段的直播。
您可以访问 simpl.info/mse 试用 MSE:
以下代码即来自该示例。
MediaSource
表示音频或视频元素的媒体来源。实例化 MediaSource
对象且触发其 open
事件后,您可以向该对象添加 SourceBuffer
。它们将充当媒体段的缓冲区:
var mediaSource = new MediaSource();
video.src = window.URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', function() {
var sourceBuffer =
mediaSource.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
// Get video segments and append them to sourceBuffer.
}
通过使用 appendBuffer()
将媒体片段添加到 SourceBuffer
,可将媒体片段“流式传输”到音频或视频元素。在此例中,我们从服务器提取视频,然后使用 File API 进行存储:
reader.onload = function (e) {
sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
if (i === NUM_CHUNKS - 1) {
mediaSource.endOfStream();
} else {
if (video.paused) {
// start playing after first chunk is appended
video.play();
}
readChunk(++i);
}
};
设置播放顺序
Chrome 50 为 SourceBuffer
mode
属性添加了额外的支持,让您能够指定按照媒体片段的附加顺序连续播放媒体片段,无论媒体片段最初是否具有不连续的时间戳。
使用 mode
属性可指定媒体片段的播放顺序。它具有以下两个值之一:
- segments:每个片段的时间戳(可能已被
timestampOffset
修改)决定了播放顺序,无论片段附加的顺序如何。 - 序列:媒体时间轴中缓冲的片段顺序取决于将片段附加到
SourceBuffer
的顺序。
如果媒体段在附加到 SourceBuffer
时从字节流数据中解析出时间戳,则 SourceBuffer
的 mode
属性设置为 segments。否则,mode
将设置为 sequence。请注意,时间戳并非可选项:大多数视频流类型必须有时间戳,其他流类型则不行:带内时间戳是包含它们的流类型固有的。
设置 mode
属性是可选的。对于不包含时间戳的流(音频/mpeg 和音频/aac),mode
只能从 segments 更改为 sequence:如果您尝试将 mode
从 sequence 更改为 segments,则会抛出错误。对于有时间戳的视频流,可以在“片段”和“序列”之间切换,但实际上这可能会产生不良、难以理解或难以预测的行为。
对于所有视频流类型,您可以将值从 segments 更改为 sequence。这意味着,片段将按附加顺序播放,并相应地生成新的时间戳:
sourceBuffer.mode = 'sequence';
将 mode
值设置为 sequence 可以确保媒体连续播放,无论媒体片段时间戳是否不连续 - 例如,视频是否多路复用出现问题,或者是否附加了不连续的片段(无论出于何种原因)。应用可以通过 polyfill timestampOffset
确保连续播放(如果有正确的视频流元数据),而序列模式则可让流程更简单且更不易出错。
MSE 应用和演示
以下所示为 MSE 的实际运用,但未经过 SourceBuffer.mode
处理:
浏览器支持
- 默认使用 Chrome 50 及更高版本
- 对于 Firefox,请参阅 MDN 了解详情