I'm trying to readStream an mp4 file and send chunks back to the client. I'm using the mediasource api. The code is failing on:
sourceBuffer.appendBuffer(new Uint8Array(mediaChunkBuffer));
with the error: This SourceBuffer has been removed from the parent media source
I'm able to append the first chunk this is done by calling initialMediaChunk(). for all subsequent chunks, i'm calling subsequentMediaChunk(). I get a MediaSource Api error.
I notice after the first chunk, the mediaSource sourceclose event is called, making the mediaSource.readystate set to false, for subsequent chunks.
let mediaSource;
let mediaQueue = [];
let mediaChunkBuffer;
function subsequentMediaChunk(dataObj)
{
mediaChunkBuffer = new Uint8Array(dataObj.data.dataChunk).buffer;
if (sourceBuffer.updating || mediaQueue.length > 0) {
mediaQueue.push(mediaChunkBuffer);
} else {
sourceBuffer.appendBuffer(new Uint8Array(mediaChunkBuffer)); // failing here
}
}
function initialMediaChunk(dataObj){
mediaChunkBuffer = new Uint8Array(dataObj.data.dataChunk).buffer;
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
mediaSource = new MediaSource();
mediaSource.addEventListener('error', function(e) {
console.log(e);
});
mediaSource.addEventListener('sourceclose', function(e) {
console.log(e);
})
mediaSource.addEventListener('sourceopen', function(e) {
var mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
sourceBuffer = mediaSource.addSourceBuffer(mime);
var file = new Blob([mediaChunkBuffer], {type: type});
var reader = new FileReader();
reader.onload = function(e) {
sourceBuffer.addEventListener('onupdate', function() { // Note: Have tried 'updateend'
if (mediaQueue.length > 0 && !sourceBuffer.updating) {
sourceBuffer.appendBuffer(new Uint8Array(mediaQueue.shift()));
}
});
sourceBuffer.appendBuffer(new Uint8Array(e.target.result));
}
reader.readAsArrayBuffer(file);
}, false);
let videoElement = $("#" + loadVideoFileName).find('video');
videoElement.attr("src",window.URL.createObjectURL(mediaSource));
}
}