SourceBuffer

Limited availability

This feature is not Baseline because it does not work in some of the most widely-used browsers.

SourceBuffer 接口表示通过 MediaSource 对象传递到 HTMLMediaElement 并播放的媒体分块。它可以由一个或者多个媒体片段组成。

EventTarget SourceBuffer

属性

SourceBuffer.appendWindowEnd

控制 append window 结束的时间戳。

SourceBuffer.appendWindowStart

控制 append window 开始的时间戳。这是一个时间戳范围,可以用于过滤附加到 SourceBuffer 的媒体数据。此时间戳范围的编码媒体帧将被附加,而超出此范围的将被忽略。

SourceBuffer.audioTracks 只读

当前包含在 SourceBuffer 中的音轨列表。

SourceBuffer.buffered 只读

返回当前在 SourceBuffer 中缓冲的时间范围。

SourceBuffer.mode

控制如何处理 SourceBuffer 中媒体片段的顺序,即它们是否可以按任何顺序被加载,或者他们必须保持一个严格的顺序。

SourceBuffer.textTracks 只读

当前包含在 SourceBuffer 中的文本轨列表。

SourceBuffer.timestampOffset

控制应用于随后附加到 SourceBuffer 的媒体片段内的时间戳偏移量。

SourceBuffer.updating 只读

一个布尔值,表示 SourceBuffer 当前是否正在更新——即当前是否正在进行 SourceBuffer.appendBuffer()SourceBuffer.appendStream()SourceBuffer.remove() 操作。

SourceBuffer.videoTracks 只读

当前包含在 SourceBuffer 中的视频轨列表。

方法

从它的父接口 EventTarget 继承方法。

SourceBuffer.abort()

中止当前片段并且重置片段解析器。

SourceBuffer.appendBuffer()

将来自 ArrayBufferTypedArrayDataView 对象的媒体片段数据附加到 SourceBuffer

SourceBuffer.appendBufferAsync() 实验性

启动异步进程,将指定缓冲数据附加到 SourceBuffer。返回一个 Promise,一旦添加了缓冲数据,该 promise 将会兑现。

SourceBuffer.appendStream()

将来自 ReadableStream 对象的媒体片段数据附加到 SourceBuffer

SourceBuffer.changeType()

更改 MIME 类型,使其符合将来调用 appendBuffer() 附加的新数据的类型。

SourceBuffer.remove()

SourceBuffer 移除指定时间范围内的媒体片段。

SourceBuffer.removeAsync() 实验性

启动异步进程,从 SourceBuffer 移除指定时间范围的媒体片段。返回一个 Promise,一旦所有匹配的片段被删除,该 promise 将会兑现。

事件

abort

SourceBuffer.appendBuffer()SourceBuffer.appendStream() 结束时通过调用 SourceBuffer.abort() 触发。SourceBuffer.updatingtrue 改变为 false

error

SourceBuffer.appendBuffer()SourceBuffer.appendStream() 期间发生错误时触发。SourceBuffer.updatingtrue 改变为 false

update

SourceBuffer.appendBuffer()SourceBuffer.remove() 完成时触发。SourceBuffer.updatingtrue 改变为 false。这个事件在 updateend 之前触发。

updateend

SourceBuffer.appendBuffer()SourceBuffer.remove() 结束后触发。这个事件在 update 后触发。

updatestart

SourceBuffer.updatingfalse 改变为 true 时触发。

示例

这个例子尽可能快地逐块加载视频,并在加载好后立刻播放。以下片段基于 Nick Desaulniers 编写的一个简单示例(查看完整的在线演示,或者下载源代码进行进一步研究)。

js
const video = document.querySelector("video");

const assetURL = "frag_bunny.mp4";
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';

if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
  const mediaSource = new MediaSource();
  //console.log(mediaSource.readyState); // closed
  video.src = URL.createObjectURL(mediaSource);
  mediaSource.addEventListener("sourceopen", sourceOpen);
} else {
  console.error("Unsupported MIME type or codec: ", mimeCodec);
}

function sourceOpen(_) {
  //console.log(this.readyState); // open
  const mediaSource = this;
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
  fetchAB(assetURL, function (buf) {
    sourceBuffer.addEventListener("updateend", function (_) {
      mediaSource.endOfStream();
      video.play();
      //console.log(mediaSource.readyState); // ended
    });
    sourceBuffer.appendBuffer(buf);
  });
}

function fetchAB(url, cb) {
  console.log(url);
  const xhr = new XMLHttpRequest();
  xhr.open("get", url);
  xhr.responseType = "arraybuffer";
  xhr.onload = function () {
    cb(xhr.response);
  };
  xhr.send();
}

规范

Specification
Media Source Extensions™
# sourcebuffer

浏览器兼容性

BCD tables only load in the browser

参见