MediaSource
注意:此功能在 專用 Web Workers 中可用。
MediaSource 介面是 Media Source Extensions API 的一部分,它代表了 HTMLMediaElement 物件的媒體資料來源。MediaSource 物件可以附加到 HTMLMediaElement 以在使用者代理中播放。
建構函式
MediaSource()-
構造並返回一個新的
MediaSource物件,不關聯任何源緩衝區(source buffers)。
例項屬性
MediaSource.activeSourceBuffers只讀-
返回一個
SourceBufferList物件,其中包含MediaSource.sourceBuffers中的SourceBuffer物件的一個子集 — 該列表提供了選定的影片軌道、啟用的音訊軌道以及顯示/隱藏的文字軌道。 MediaSource.duration-
獲取並設定當前正在呈現的媒體的時長。
MediaSource.handle只讀-
在專用工作執行緒(dedicated worker)中,返回一個
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例項已由媒體元素開啟,並且可以開始向SourceBuffer物件(位於sourceBuffers中)追加資料時觸發。
示例
完整的基本示例
以下簡單示例使用 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 屬性,然後透過 postMessage() 呼叫將生成的 MediaSourceHandle 物件傳輸回建立工作執行緒的執行緒(在此例中為主執行緒)。
// 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 事件處理器接收控制代碼,透過其 HTMLMediaElement.srcObject 屬性將其附加到 <video> 元素,然後 play 影片。
worker.addEventListener("message", (msg) => {
let mediaSourceHandle = msg.data.arg;
video.srcObject = mediaSourceHandle;
video.play();
});
注意: MediaSourceHandle 無法成功傳輸到共享工作執行緒或服務工作執行緒中,或透過它們進行傳輸。
規範
| 規範 |
|---|
| Media Source Extensions™ # mediasource |
瀏覽器相容性
載入中…