Source code

Revision control

Copy as Markdown

Other Tools

// This is similar to mediasource-worker-play.js, except that the buffering is
// longer and done in tiny chunks to enable a better chance of the main thread
// detaching the element while interesting buffering work is still occurring. To
// assist the main thread understanding when the buffering has started already
// or has completed already, we also perform extra messaging.
importScripts("mediasource-worker-util.js");
onmessage = function(evt) {
postMessage({ subject: messageSubject.ERROR, info: "No message expected by Worker" });
};
let util = new MediaSourceWorkerUtil();
let sentStartedBufferingMessage = false;
util.mediaSource.addEventListener("sourceopen", () => {
let sourceBuffer;
try {
sourceBuffer = util.mediaSource.addSourceBuffer(util.mediaMetadata.type);
} catch(e) {
// Detachment may have already begun, so allow exception here.
// TODO(https://crbug.com/878133): Consider a distinct readyState for the case
// where exception occurs due to "Worker MediaSource attachment is closing".
// That would assist API users and narrow the exception handling here.
return;
}
sourceBuffer.onerror = (err) => {
postMessage({ subject: messageSubject.ERROR, info: err });
};
util.mediaLoadPromise.then(mediaData => bufferInto(sourceBuffer, mediaData, 100, 0),
err => { postMessage({ subject: messageSubject.ERROR, info: err }) } );
}, { once : true });
let handle = util.mediaSource.handle;
postMessage({ subject: messageSubject.HANDLE, info: handle }, { transfer: [handle] } );
// Append increasingly large pieces at a time, starting/continuing at |position|.
// This allows buffering the test media without timeout, but also with enough
// operations to gain coverage on detachment concurrency with append.
function bufferInto(sourceBuffer, mediaData, appendSize, position) {
if (position >= mediaData.byteLength) {
postMessage({ subject: messageSubject.FINISHED_BUFFERING });
try {
util.mediaSource.endOfStream();
} catch(e) {
// Detachment may have already begun, so allow exception here.
// TODO(https://crbug.com/878133): Consider a distinct readyState for the case
// where exception occurs due to "Worker MediaSource attachment is closing".
// That would assist API users and narrow the exception handling here.
// FALL-THROUGH - return.
}
return;
}
var nextPosition = position + appendSize;
const pieceToAppend = mediaData.slice(position, nextPosition);
position = nextPosition;
appendSize += 100;
sourceBuffer.addEventListener("updateend", () => {
if (!sentStartedBufferingMessage) {
postMessage({ subject: messageSubject.STARTED_BUFFERING});
sentStartedBufferingMessage = true;
}
bufferInto(sourceBuffer, mediaData, appendSize, position);
}, { once : true });
try {
sourceBuffer.appendBuffer(pieceToAppend);
} catch(e) {
// Detachment may have already begun, so allow exception here.
// TODO(https://crbug.com/878133): Consider a distinct readyState for the case
// where exception occurs due to "Worker MediaSource attachment is closing".
// That would assist API users and narrow the exception handling here.
// FALL-THROUGH - return.
}
}