SourceBuffer
============

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

EventTarget

SourceBuffer属性
--

`SourceBuffer.appendWindowEnd` (en-US)

控制 append window 结束的时间戳。

`SourceBuffer.appendWindowStart` (en-US)

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

`SourceBuffer.audioTracks` (en-US) 只读 

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

`SourceBuffer.buffered` 只读 

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

`SourceBuffer.mode`

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

`SourceBuffer.textTracks` (en-US) 只读 

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

`SourceBuffer.timestampOffset`

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

`SourceBuffer.updating` 只读 

一个布尔值，表示 `SourceBuffer` 当前是否正在更新——即当前是否正在进行 `SourceBuffer.appendBuffer()`、`SourceBuffer.appendStream()` (en-US) 或 `SourceBuffer.remove()` 操作。

`SourceBuffer.videoTracks` (en-US) 只读 

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

方法
--

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

`SourceBuffer.abort()` (en-US)

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

`SourceBuffer.appendBuffer()`

将来自 `ArrayBuffer`、`TypedArray` 或 `DataView` 对象的媒体片段数据附加到 `SourceBuffer`。

`SourceBuffer.appendBufferAsync()` (en-US) 
实验性

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

`SourceBuffer.appendStream()` (en-US)

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

`SourceBuffer.changeType()` (en-US)

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

`SourceBuffer.remove()`

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

`SourceBuffer.removeAsync()` (en-US) 
实验性

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

事件
--

`abort`

当 `SourceBuffer.appendBuffer()` 或 `SourceBuffer.appendStream()` (en-US) 结束时通过调用 `SourceBuffer.abort()` (en-US) 触发。`SourceBuffer.updating` 从 `true` 改变为 `false`。

`error`

在 `SourceBuffer.appendBuffer()` 或 `SourceBuffer.appendStream()` (en-US) 期间发生错误时触发。`SourceBuffer.updating` 从 `true` 改变为 `false`。

`update`

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

`updateend`

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

`updatestart`

当 `SourceBuffer.updating` 从 `false` 改变为 `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 with JavaScript enabled. Enable JavaScript to view data.

参见
--

* `MediaSource`
* `SourceBufferList`