Online demo: https://jsfiddle.net/sans_amour/t1ebfvnx/
var FILE = 'frag_bunny2.mp4'; var filesize = 0; var filetype = 'video/mp4; codecs="avc1.42C01E, mp4a.40.2' var fileduration = 0 var chunksize = 262144 var totalSegments = 0 var video = document.querySelector('video'); var currentChunk = 0 var maxBufferLength = 120 var tt, sourceBuffer window.MediaSource = window.MediaSource || window.WebKitMediaSource; if (!!!window.MediaSource) { alert('MediaSource API is not available'); } var mediaSource = new MediaSource(); video.src = window.URL.createObjectURL(mediaSource); video.addEventListener('loadedmetadata', function(a) { console.log(a) fileduration = a.target.duration }) function callback(e) { sourceBuffer = mediaSource.addSourceBuffer(filetype); var d = false, count = 0; (function readChunk_() { GET(FILE, function(uInt8Array) { var file = new Blob([uInt8Array], { type: filetype }); var reader = new FileReader(); reader.onload = function(e) { if (count++ == 0) { sourceBuffer.addEventListener('updateend', function(_) { var ranges = sourceBuffer.buffered; console.log("CURRENT TIME: " + video.currentTime); console.log("BUFFERED RANGES: " + ranges.length); tt = 0 for (var i = 0, len = ranges.length; i < len; i += 1) { console.log("RANGE: " + ranges.start(i) + " - " + ranges.end(i)); tt = Math.max(tt, ranges.end(i)) } tt = tt - video.currentTime if (file.size != chunksize) { mediaSource.endOfStream(); } else { if (video.paused) { video.play(); } if (tt > maxBufferLength) { var __ = setInterval(function() { var ranges = sourceBuffer.buffered; tt = 0 for (var i = 0, len = ranges.length; i < len; i += 1) { tt = Math.max(tt, ranges.end(i)) } tt = tt - video.currentTime if (tt <= maxBufferLength) { clearInterval(__) readChunk_(); } }, 500) } else readChunk_(); } }); } sourceBuffer.appendBuffer(new Uint8Array(e.target.result)); }; reader.readAsArrayBuffer(file); }) })() } mediaSource.addEventListener('sourceopen', callback, false); mediaSource.addEventListener('webkitsourceopen', callback, false); function GET(url, callback) { if (filesize && (currentChunk) * chunksize > filesize) return var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'arraybuffer'; xhr.setRequestHeader('Range', 'bytes=' + (currentChunk) * chunksize + '-' + ((currentChunk + 1) * chunksize - 1)); currentChunk++ xhr.send(); xhr.onload = function(e) { if (xhr.status != 200 && xhr.status != 206) { alert("Unexpected status code " + xhr.status + " for " + url); return false; } var range = xhr.getResponseHeader('Content-Range') filesize = parseInt(range.match(/\/(\d+)$/)[1]) totalSegments = Math.ceil(filesize / chunksize) - 1 callback(new Uint8Array(xhr.response)); }; }