MENU
Media Source Extensions
The Media Source API, formally known as Media Source Extensions (MSE) API,provides functionality enabling plugin-free web-based streaming media. Using MSE, media streams can be created via JavaScript, and played using <audio> and <video> elements. MSE gives us finer-grained control over how much and how often content is fetched, and some control over memory usage details, such as when buffers are evicted. It lays the groundwork for adaptive bitrate streaming clients (such as those using DASH or HLS) to be built on its extensible API.
Understanding MSE is needed if you want to do:
- Adaptive streaming, ie. adapting to device capabilities and network conditions
- Adaptive splicing, such as ad insertion
- Time shifting
- Control of performance and download size
Dynamic Adaptive Streaming over HTTP (DASH) is a protocol for specifying how adaptive content should be fetched. It is effectively a layer built on top of MSE for building adaptive bitrate streaming clients. While there are other protocols available (such as HTTP Live Streaming (HLS)), DASH has the most platform support.
RESETRUNFULL
<!DOCTYPE html><html>
<body style="height:800px">
<button onclick="play()">PLAY</button><br/>
<video style="height:800px" controls></video>
<script>
function play(){
var baseUrl = 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/video/720_2400000/dash/';
var initUrl = baseUrl + 'init.mp4';
var templateUrl = baseUrl + 'segment_$Number$.m4s';
var sourceBuffer;
var index = 0;
var numberOfChunks = 52;
var video = document.querySelector('video');
if (!window.MediaSource){
console.error('No Media Source API available');
return;
}
var ms = new MediaSource();
video.src = window.URL.createObjectURL(ms);
ms.addEventListener('sourceopen', onMediaSourceOpen);
function onMediaSourceOpen() {
sourceBuffer = ms.addSourceBuffer('video/mp4; codecs="avc1.4d401f"');
sourceBuffer.addEventListener('updateend', nextSegment);
GET(initUrl, appendToBuffer);
video.play();
}
function nextSegment() {
var url = templateUrl.replace('$Number$', index);
GET(url, appendToBuffer);
index++;
if (index > numberOfChunks) sourceBuffer.removeEventListener('updateend', nextSegment);
}
function appendToBuffer(videoChunk) {
if (videoChunk) sourceBuffer.appendBuffer(new Uint8Array(videoChunk));
}
function GET(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (xhr.status != 200) {
console.warn('Unexpected status code ' + xhr.status + ' for ' + url);
return false;
}
callback(xhr.response);
};
xhr.send();
}
}
</script>
</body></html>