web api interface
MediaSource
Available in workers
The MediaSource interface of the Media Source Extensions API represents a source of media data for an HTMLMediaElement object. A MediaSource object can be attached to a HTMLMediaElement to be played in the user agent.
Constructor
MediaSource()- : Constructs and returns a new
MediaSourceobject with no associated source buffers.
- : Constructs and returns a new
Instance properties
activeSourceBuffersRead only- : Returns a
SourceBufferListobject containing a subset of theSourceBufferobjects contained withinsourceBuffers— the list of objects providing the selected video track, enabled audio tracks, and shown/hidden text tracks.
- : Returns a
duration- : Gets and sets the duration of the current media being presented.
handleRead only- : Inside a dedicated worker, returns a
MediaSourceHandleobject, a proxy for theMediaSourcethat can be transferred from the worker back to the main thread and attached to a media element via itssrcObjectproperty.
- : Inside a dedicated worker, returns a
readyStateRead only- : Returns an enum representing the state of the current
MediaSource, whether it is not currently attached to a media element (closed), attached and ready to receiveSourceBufferobjects (open), or attached but the stream has been ended viaendOfStream()(ended.)
- : Returns an enum representing the state of the current
sourceBuffersRead only- : Returns a
SourceBufferListobject containing the list ofSourceBufferobjects associated with thisMediaSource.
- : Returns a
Static properties
MediaSource.canConstructInDedicatedWorkerRead only- : A boolean; returns
trueifMediaSourceworker support is implemented, providing a low-latency feature detection mechanism.
- : A boolean; returns
Instance methods
Inherits methods from its parent interface, EventTarget.
addSourceBuffer()- : Creates a new
SourceBufferof the given MIME type and adds it to thesourceBufferslist.
- : Creates a new
clearLiveSeekableRange()- : Clears a seekable range previously set with a call to
setLiveSeekableRange().
- : Clears a seekable range previously set with a call to
endOfStream()- : Signals the end of the stream.
removeSourceBuffer()- : Removes the given
SourceBufferfrom thesourceBufferslist.
- : Removes the given
setLiveSeekableRange()- : Sets the range that the user can seek to in the media element.
Static methods
MediaSource.isTypeSupported()- : Returns a boolean value indicating whether the current user agent supports the given MIME type — this is, if it can successfully create
SourceBufferobjects for that MIME type.
- : Returns a boolean value indicating whether the current user agent supports the given MIME type — this is, if it can successfully create
Events
sourceclose- : Fired when the
MediaSourceinstance is not attached to a media element anymore.
- : Fired when the
sourceended- : Fired when the
MediaSourceinstance is still attached to a media element, butendOfStream()has been called.
- : Fired when the
sourceopen- : Fired when a media element has opened the
MediaSourceinstance and it is ready for data to be appended to theSourceBufferobjects insourceBuffers.
- : Fired when a media element has opened the
Examples
Complete basic example
The following basic example loads a video using XMLHttpRequest and plays it as soon as it can. This example can be viewed live here (you can also download the source for further investigation).
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 = 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 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();
}
Constructing a MediaSource in a dedicated worker and passing it to the main thread
The handle property can be accessed inside a dedicated worker, and the resulting MediaSourceHandle object is then transferred over to the thread that created the worker (in this case, the main thread) via a postMessage() call:
// 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"
});
Over in the main thread, we receive the handle via a message event handler, attach it to a <video> via its srcObject property, and play the video:
worker.addEventListener("message", (msg) => {
let mediaSourceHandle = msg.data.arg;
video.srcObject = mediaSourceHandle;
video.play();
});
[!NOTE]
MediaSourceHandles cannot be successfully transferred into or via a shared worker or service worker.