tor-browser

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

script-transform-generateKeyFrame.js (2794B)


      1 onrtctransform = event => {
      2  const transformer = event.transformer;
      3  let keyFrameCount = 0;
      4  let gotFrame;
      5 
      6  transformer.options.port.onmessage = event => {
      7    const {method, rid} = event.data;
      8    // Maybe refactor to have transaction ids?
      9    if (method == 'generateKeyFrame') {
     10      generateKeyFrame(rid);
     11    } else if (method == 'generateKeyFrameDoesNotThrow') {
     12      generateKeyFrameDoesNothThrow(rid);
     13    } else if (method == 'waitForFrame') {
     14      waitForFrame();
     15    }
     16  }
     17 
     18  async function rejectInMs(timeout) {
     19    return new Promise((_, reject) => {
     20      const rejectWithTimeout = () => {
     21        reject(new DOMException(`Timed out after waiting for ${timeout} ms`,
     22          'TimeoutError'));
     23      };
     24      setTimeout(rejectWithTimeout, timeout);
     25    });
     26  }
     27 
     28  async function resolveInMs(timeout) {
     29    return new Promise((resolve) => {
     30      setTimeout(resolve, timeout);
     31    });
     32  }
     33 
     34  async function generateKeyFrame(rid) {
     35    try {
     36      const timestamp = await Promise.race([transformer.generateKeyFrame(rid), rejectInMs(8000)]);
     37      transformer.options.port.postMessage({result: 'success', value: timestamp, count: keyFrameCount});
     38    } catch (e) {
     39      // TODO: This does not work if we send e.name, why?
     40      transformer.options.port.postMessage({result: 'failure', value: `${e.name}`, message: `${e.message}`});
     41    }
     42  }
     43 
     44 
     45  async function generateKeyFrameDoesNothThrow(rid) {
     46    try {
     47      const timestamp = await Promise.race([transformer.generateKeyFrame(rid), resolveInMs(50)]);
     48      transformer.options.port.postMessage({result: 'success', value: timestamp, count: keyFrameCount});
     49    } catch (e) {
     50      transformer.options.port.postMessage({result: 'failure', value: `${e.name}`, message: `${e.message}`});
     51    }
     52  }
     53 
     54  async function waitForFrame() {
     55    try {
     56      await Promise.race([new Promise(r => gotFrameCallback = r), rejectInMs(8000)]);
     57      transformer.options.port.postMessage('got frame');
     58    } catch (e) {
     59      // TODO: This does not work if we send e.name, why?
     60      transformer.options.port.postMessage({result: 'failure', value: `${e.name}`, message: `${e.message}`});
     61    }
     62  }
     63 
     64  transformer.options.port.postMessage('started');
     65  transformer.reader = transformer.readable.getReader();
     66  transformer.writer = transformer.writable.getWriter();
     67 
     68  function process(transformer)
     69  {
     70    transformer.reader.read().then(chunk => {
     71      if (chunk.done)
     72        return;
     73      if (chunk.value instanceof RTCEncodedVideoFrame) {
     74        if (chunk.value.type == 'key') {
     75          keyFrameCount++;
     76        }
     77      }
     78      if (gotFrameCallback) {
     79        gotFrameCallback();
     80      }
     81      transformer.writer.write(chunk.value);
     82      process(transformer);
     83    });
     84  }
     85 
     86  process(transformer);
     87 };
     88 self.postMessage('registered');