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');