mediasource-worker-detach-element.js (3277B)
1 // This is similar to mediasource-worker-play.js, except that the buffering is 2 // longer and done in tiny chunks to enable a better chance of the main thread 3 // detaching the element while interesting buffering work is still occurring. To 4 // assist the main thread understanding when the buffering has started already 5 // or has completed already, we also perform extra messaging. 6 importScripts("mediasource-worker-util.js"); 7 8 onmessage = function(evt) { 9 postMessage({ subject: messageSubject.ERROR, info: "No message expected by Worker" }); 10 }; 11 12 let util = new MediaSourceWorkerUtil(); 13 14 let sentStartedBufferingMessage = false; 15 16 util.mediaSource.addEventListener("sourceopen", () => { 17 let sourceBuffer; 18 try { 19 sourceBuffer = util.mediaSource.addSourceBuffer(util.mediaMetadata.type); 20 } catch(e) { 21 // Detachment may have already begun, so allow exception here. 22 // TODO(https://crbug.com/878133): Consider a distinct readyState for the case 23 // where exception occurs due to "Worker MediaSource attachment is closing". 24 // That would assist API users and narrow the exception handling here. 25 return; 26 } 27 28 sourceBuffer.onerror = (err) => { 29 postMessage({ subject: messageSubject.ERROR, info: err }); 30 }; 31 util.mediaLoadPromise.then(mediaData => bufferInto(sourceBuffer, mediaData, 100, 0), 32 err => { postMessage({ subject: messageSubject.ERROR, info: err }) } ); 33 }, { once : true }); 34 35 let handle = util.mediaSource.handle; 36 37 postMessage({ subject: messageSubject.HANDLE, info: handle }, { transfer: [handle] } ); 38 39 // Append increasingly large pieces at a time, starting/continuing at |position|. 40 // This allows buffering the test media without timeout, but also with enough 41 // operations to gain coverage on detachment concurrency with append. 42 function bufferInto(sourceBuffer, mediaData, appendSize, position) { 43 if (position >= mediaData.byteLength) { 44 postMessage({ subject: messageSubject.FINISHED_BUFFERING }); 45 try { 46 util.mediaSource.endOfStream(); 47 } catch(e) { 48 // Detachment may have already begun, so allow exception here. 49 // TODO(https://crbug.com/878133): Consider a distinct readyState for the case 50 // where exception occurs due to "Worker MediaSource attachment is closing". 51 // That would assist API users and narrow the exception handling here. 52 // FALL-THROUGH - return. 53 } 54 return; 55 } 56 57 var nextPosition = position + appendSize; 58 const pieceToAppend = mediaData.slice(position, nextPosition); 59 position = nextPosition; 60 appendSize += 100; 61 62 sourceBuffer.addEventListener("updateend", () => { 63 if (!sentStartedBufferingMessage) { 64 postMessage({ subject: messageSubject.STARTED_BUFFERING}); 65 sentStartedBufferingMessage = true; 66 } 67 bufferInto(sourceBuffer, mediaData, appendSize, position); 68 }, { once : true }); 69 70 try { 71 sourceBuffer.appendBuffer(pieceToAppend); 72 } catch(e) { 73 // Detachment may have already begun, so allow exception here. 74 // TODO(https://crbug.com/878133): Consider a distinct readyState for the case 75 // where exception occurs due to "Worker MediaSource attachment is closing". 76 // That would assist API users and narrow the exception handling here. 77 // FALL-THROUGH - return. 78 } 79 }