MediaSource
MediaSource
是 媒体源扩展 API 的一个接口,它代表了 HTMLMediaElement
对象的媒体数据源。MediaSource
对象可以附加到 HTMLMediaElement
以便在用户代理中播放。
构造函数
MediaSource()
-
构造并返回一个新的
MediaSource
对象,没有关联的源缓冲区。
实例属性
MediaSource.activeSourceBuffers
只读-
返回一个
SourceBufferList
对象,它包含MediaSource.sourceBuffers
中包含的SourceBuffer
对象的子集 - 提供所选视频轨道的对象列表,已启用的音频轨道以及显示/隐藏的文本轨道。 MediaSource.duration
-
获取和设置当前呈现的媒体的时长。
MediaSource.handle
只读-
在专用工作线程中,返回一个
MediaSourceHandle
对象,它是MediaSource
的代理,可以从工作线程传输回主线程,并通过其HTMLMediaElement.srcObject
属性附加到媒体元素。 MediaSource.readyState
只读-
返回一个枚举,表示当前
MediaSource
的状态,无论是当前未附加到媒体元素 (closed
),附加并准备接收SourceBuffer
对象 (open
),还是附加但流已通过MediaSource.endOfStream()
结束 (ended
.)。 MediaSource.sourceBuffers
只读-
返回一个
SourceBufferList
对象,其中包含与该MediaSource
关联的SourceBuffer
对象列表。
静态属性
MediaSource.canConstructInDedicatedWorker
只读-
布尔值;如果实现了
MediaSource
工作线程支持,则返回true
,提供低延迟的功能检测机制。
实例方法
从其父接口 EventTarget
继承方法。
MediaSource.addSourceBuffer()
-
创建一个指定 MIME 类型的新的
SourceBuffer
,并将它添加到MediaSource.sourceBuffers
列表中。 MediaSource.clearLiveSeekableRange()
-
清除之前通过调用
setLiveSeekableRange()
设置的可搜索范围。 MediaSource.endOfStream()
-
发出流结束的信号。
MediaSource.removeSourceBuffer()
-
从
MediaSource.sourceBuffers
列表中移除给定的SourceBuffer
。 MediaSource.setLiveSeekableRange()
-
设置用户可以在媒体元素中搜索到的范围。
静态方法
MediaSource.isTypeSupported()
-
返回一个布尔值,指示当前用户代理是否支持给定的 MIME 类型 - 也就是说,它是否能够为该 MIME 类型成功创建
SourceBuffer
对象。
事件
sourceclose
-
当
MediaSource
实例不再附加到媒体元素时触发。 sourceended
-
当
MediaSource
实例仍然附加到媒体元素,但endOfStream()
已被调用时触发。 sourceopen
-
当
MediaSource
实例被媒体元素打开并准备接收数据附加到sourceBuffers
中的SourceBuffer
对象时触发。
示例
完整的基本示例
以下简单示例使用 XMLHttpRequest
加载视频,并在视频可用时立即播放它。此示例由 Nick Desaulniers 编写,可以 在此处查看 (您也可以 下载源代码 以供进一步研究)。函数 getMediaSource()
未在此定义,它返回一个 MediaSource
。
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"';
let mediaSource;
if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
mediaSource = getMediaSource();
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 sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, (buf) => {
sourceBuffer.addEventListener("updateend", () => {
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 = () => {
cb(xhr.response);
};
xhr.send();
}
在专用工作线程中构造 MediaSource
并将其传递给主线程
可以使用专用工作线程中的 handle
属性访问 MediaSourceHandle
对象,然后通过 postMessage()
调用将其传输到创建工作线程的线程(在本例中为主线程)。
// Inside dedicated worker
let mediaSource = new MediaSource();
let handle = mediaSource.handle;
// Transfer the handle to the context that created the worker
postMessage({ arg: handle }, [handle]);
mediaSource.addEventListener("sourceopen", () => {
// Await sourceopen on MediaSource before creating SourceBuffers
// and populating them with fetched media — MediaSource won't
// accept creation of SourceBuffers until it is attached to the
// HTMLMediaElement and its readyState is "open"
});
在主线程中,我们通过 message
事件处理程序接收句柄,将其附加到 <video>
的 HTMLMediaElement.srcObject
属性,并 play
视频。
worker.addEventListener("message", (msg) => {
let mediaSourceHandle = msg.data.arg;
video.srcObject = mediaSourceHandle;
video.play();
});
注意: MediaSourceHandle
不能成功传输到共享工作线程或服务工作线程中或通过它们传输。
规范
规范 |
---|
媒体源扩展™ # mediasource |
浏览器兼容性
BCD 表仅在浏览器中加载