Files
gods-eye-view/src/ui/cctvVideo.js
T

60 lines
1.5 KiB
JavaScript

/** Paint a second surface from the projection decoder, bounded to 640px/15 fps. */
export function createCctvVideoSurface(
canvas,
getVideo,
{
requestFrame = requestAnimationFrame,
cancelFrame = cancelAnimationFrame,
} = {},
) {
const ctx = canvas.getContext('2d');
let handle = 0;
let stopped = false;
let previous = null;
let previousTime = -1;
let paintedAt = -Infinity;
const paint = (now) => {
if (stopped) return;
const video = getVideo();
if (video !== previous) {
ctx?.clearRect(0, 0, canvas.width, canvas.height);
previous = video;
previousTime = -1;
}
if (
ctx &&
video?.readyState >= 2 &&
video.videoWidth > 0 &&
video.videoHeight > 0 &&
now - paintedAt >= 1000 / 15 &&
video.currentTime !== previousTime
) {
const width = Math.min(640, video.videoWidth);
const height = Math.max(
1,
Math.round((width * video.videoHeight) / video.videoWidth),
);
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
}
try {
ctx.drawImage(video, 0, 0, width, height);
previousTime = video.currentTime;
paintedAt = now;
} catch {
/* A resolution/decode transition retries on the next frame. */
}
}
handle = requestFrame(paint);
};
handle = requestFrame(paint);
return {
stop() {
stopped = true;
cancelFrame(handle);
ctx?.clearRect(0, 0, canvas.width, canvas.height);
},
};
}