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 属性指定媒体片段的播放顺序。它具有以下两个值之一:

  • 片段:每个片段的时间戳(可能已由 timestampOffset 修改)决定了播放顺序,无论片段附加的顺序如何。
  • sequence:媒体时间轴中缓冲的片段顺序取决于片段附加到 SourceBuffer 的顺序。

如果媒体片段在附加到 SourceBuffer 时具有从字节流数据解析的时间戳,则 SourceBuffermode 属性将设置为 segments。否则,mode 将设置为序列。请注意,时间戳不是可选项:对于大多数数据流类型,必须提供时间戳,而对于其他数据流类型,不能提供时间戳:带内时间戳是包含它们的数据流类型固有的。

设置 mode 属性是可选的。对于不包含时间戳的串流(audio/mpeg 和 audio/aac),mode 只能从 segments 更改为 sequence:如果您尝试将 modesequence 更改为 segments,系统会抛出错误。对于具有时间戳的流,可以在 segmentssequence 之间切换,但实际上,这可能会产生不理想、难以理解或难以预测的行为。

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

sourceBuffer.mode = 'sequence';

能够将 mode 值设置为序列可确保媒体片段时间戳不间断,无论视频混流是否存在问题,或者是否(出于任何原因)附加了不连续的片段。如果有正确的串流元数据,应用可以使用 timestampOffset 进行 polyfill 以确保连续播放,但序列模式可简化该过程并降低出错几率。

MSE 应用和演示

以下示例展示了 MSE 的运作方式,但未进行 SourceBuffer.mode 操作:

浏览器支持

  • 默认情况下,Chrome 50 及更高版本
  • 对于 Firefox,请参阅 MDN 如需了解详情

规范

API 信息