tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }