MSTP/MSTG FrameDropper (working)
by jib1
HTML
<button id="button">Start</button><br>
<video id="video1" width="320" height="180" autoplay controls></video><br>
<div id="fps1">FPS 0.00</div>
<video id="video2" width="320" height="180" autoplay controls></video><br>
<div id="fps2">FPS 0.00</div>
JavaScript
// Showing a high-fps self-view while "sending" (encode/decode) low-fps video
button.onclick = async () => {
try {
const video = {width: 1280, height: 720};
const stream = await navigator.mediaDevices.getUserMedia({video});
const [track] = stream.getTracks();
const {readable} = new MediaStreamTrackProcessor({track});
const track2 = new MediaStreamTrackGenerator({kind: 'video'});
const writableSelfView = track2.writable;
video1.srcObject = new MediaStream([track2]);
const track3 = new MediaStreamTrackGenerator({kind: 'video'});
const writableRemoteView = track3.writable;
video2.srcObject = new MediaStream([track3]);
const b = new Blob([`(${work.toString()})()`], {type: "text/javascript"});
const worker = new Worker(URL.createObjectURL(b));
worker.postMessage({readable, writableSelfView, writableRemoteView},
[readable, writableSelfView, writableRemoteView]);
const frames = v => v.mozPaintedFrames || v.webkitDecodedFrameCount;
const wait = ms => new Promise(r => setTimeout(r, ms));
const updateFps = (element, video, state) => {
const last = state.counter;
state.counter = frames(video);
element.innerHTML = `FPS ${(state.counter - last).toFixed(2)}`;
}
const frames1 = {counter: frames(video1)};
const frames2 = {counter: frames(video2)};
while (true) {
await wait(1000);
updateFps(fps1, video1, frames1);
updateFps(fps2, video2, frames2);
}
} catch (e) {
console.log(e);
}
};
function work() {
let decoder;
onmessage = async ({data: {readable, writableSelfView, writableRemoteView}}) => {
try {
readable = readable.pipeThrough(new TransformStream({transform: crop}));
const [r1, r2] = teeSynchronizedCloned(readable);
await Promise.all([
r1.pipeTo(writableSelfView),
r2.pipeThrough(new FrameDropper())
.pipeThrough(new EncodeVideoStream({
codec: "vp8",
...