// 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. } }