Media Source API - 自动确保媒体片段以附加顺序流畅播放

通过 HTML 音频和视频元素,您只需提供一个 src 网址,即可加载、解码和播放媒体:

    <video src='foo.webm'></video>

这在简单的使用情形下非常实用,但对于自适应流式传输等技术,Media Source Extensions API (MSE) 可提供更多控制。MSE 支持通过 JavaScript 构建来自音频或视频片段的直播。

您可以访问 simpl.info/mse 试用 MSE:

使用 MSE API 播放的视频的屏幕截图。

以下代码即来自该示例。

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 时从字节流数据中解析出时间戳,则 SourceBuffermode 属性设置为 segments。否则,mode 将设置为 sequence。请注意,时间戳并非可选项:大多数视频流类型必须有时间戳,其他流类型则不行:带内时间戳是包含它们的流类型固有的。

设置 mode 属性是可选的。对于不包含时间戳的流(音频/mpeg 和音频/aac),mode 只能从 segments 更改为 sequence:如果您尝试将 modesequence 更改为 segments,则会抛出错误。对于有时间戳的视频流,可以在“片段”和“序列”之间切换,但实际上这可能会产生不良、难以理解或难以预测的行为。

对于所有视频流类型,您可以将值从 segments 更改为 sequence。这意味着,片段将按附加顺序播放,并相应地生成新的时间戳:

sourceBuffer.mode = 'sequence';

mode 值设置为 sequence 可以确保媒体连续播放,无论媒体片段时间戳是否不连续 - 例如,视频是否多路复用出现问题,或者是否附加了不连续的片段(无论出于何种原因)。应用可以通过 polyfill timestampOffset确保连续播放(如果有正确的视频流元数据),而序列模式则可让流程更简单且更不易出错。

MSE 应用和演示

以下所示为 MSE 的实际运用,但未经过 SourceBuffer.mode 处理:

浏览器支持

  • 默认使用 Chrome 50 及更高版本
  • 对于 Firefox,请参阅 MDN 了解详情

规范

API 信息