Last active
August 16, 2018 16:23
-
-
Save tchakabam/228f9415fd1c1d1cc8537d768b114e61 to your computer and use it in GitHub Desktop.
Example / Benchmark for switching MSE SourceBuffers content while playing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
* | |
* Example / Benchmark for switching MSE SourceBuffers content while playing | |
* | |
* Logs time needed for operations to browser console | |
* | |
* Replace the MEDIA_LIST array with resources present in your environment (fragmented mp4s with video expected) | |
* | |
* | |
--> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Buffer switch between two streams</title> | |
</head> | |
<body> | |
<video height=720></video> | |
<center><button onclick="switchStream()" id="switch">Switch!</button></center> | |
<script type="text/javascript"> | |
var MEDIA_LIST = [ | |
'/media/car-20120827-85.mp4', | |
'/media/motion-20120802-85.mp4' | |
]; | |
var state = null; | |
var now = Date.now(); | |
var sourceBuffer = null; | |
function switchStream() { | |
console.log('stream switch requested after ' + nowDiffTime() + ' ms'); | |
state = 'REMOVING'; | |
sourceBuffer.remove(0, Infinity); | |
} | |
function nowDiffTime() { | |
var diff = Date.now() - now; | |
now = Date.now(); | |
return diff; | |
} | |
var dataList_ = null; | |
var video = null; | |
var mediaSource = null; | |
var currentTrack = 0; | |
(function() { | |
loadAllMedia(onMediaLoaded); | |
})(); | |
function nextTrackIndex() { | |
return currentTrack++ % dataList_.length; | |
} | |
function onMediaLoaded(dataList) { | |
mediaSource = new MediaSource(); | |
window.player = video = document.querySelector('video'); | |
video.src = URL.createObjectURL(mediaSource); | |
video.addEventListener('playing', onPlaying, false); | |
dataList_ = dataList; | |
console.log('loading data took: ' + nowDiffTime() + ' ms'); | |
mediaSource.addEventListener('sourceopen', onSourceOpen, false); | |
} | |
function onSourceOpen() { | |
sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E"'); | |
sourceBuffer.addEventListener('updateend', onSourceBufferUpdateEnd); | |
console.log('creating mediasource took: ' + nowDiffTime() + ' ms'); | |
appendData(nextTrackIndex()); | |
} | |
function onPlaying() { | |
switch(state) { | |
case 'APPENDED': | |
state = 'PLAYING'; | |
console.log('seeking/playing took: ' + nowDiffTime() + ' ms'); | |
break; | |
} | |
} | |
function onSourceBufferUpdateEnd() { | |
console.log('SourceBuffer update ended'); | |
switch(state) { | |
case 'APPENDING': | |
state = 'APPENDED'; | |
console.log('segment data appended, playing out'); | |
console.log('appending to buffer took ' + nowDiffTime() + ' ms'); | |
video.currentTime = 30; | |
video.play(); | |
break; | |
case 'REMOVING': | |
console.log('flushing buffer took ' + nowDiffTime() + ' ms'); | |
state = 'REMOVED'; | |
appendData(nextTrackIndex()); | |
break; | |
} | |
} | |
function appendData(index) { | |
state = 'APPENDING'; | |
sourceBuffer.timestampOffset = 0; | |
console.log('appending ' + dataList_[index].length + ' bytes'); | |
sourceBuffer.appendBuffer(dataList_[index]); | |
} | |
function loadAllMedia(done) { | |
var mediaList = MEDIA_LIST; | |
var dataList = []; | |
var mediaIndex = 0; | |
console.log('loading all media'); | |
var continueLoading = function() { | |
loadBinary(mediaList[mediaIndex], function(data) { | |
dataList.push(data); | |
mediaIndex++; | |
if (mediaIndex >= mediaList.length) { | |
done(dataList); | |
return; | |
} | |
continueLoading(); | |
}); | |
} | |
continueLoading(); | |
} | |
function loadBinary(url, done) { | |
var oReq = new XMLHttpRequest(); | |
oReq.open("GET", url, true); | |
oReq.responseType = "arraybuffer"; | |
oReq.onload = function (oEvent) { | |
var arrayBuffer = oReq.response; // Note: not oReq.responseText | |
if (arrayBuffer) { | |
var byteArray = new Uint8Array(arrayBuffer); | |
/* | |
for (var i = 0; i < byteArray.byteLength; i++) { | |
// do something with each byte in the array | |
} | |
*/ | |
done(byteArray); | |
} | |
}; | |
oReq.send(null); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment