Hacky demo changes

This commit is contained in:
Andras Schmelczer 2026-05-06 19:36:04 +01:00
parent 7cba369308
commit ea7afd618c
39 changed files with 2041 additions and 745 deletions

88
video/src/verify.ts Normal file
View file

@ -0,0 +1,88 @@
import { execFileSync } from 'node:child_process';
import { existsSync, statSync } from 'node:fs';
import { MAX_DURATION_S, MIN_DURATION_S, OUTPUT_FPS, OUTPUT_DIR, VIDEO_SIZE } from './config.js';
interface Probe {
streams?: {
width?: number;
height?: number;
avg_frame_rate?: string;
r_frame_rate?: string;
}[];
format?: {
duration?: string;
size?: string;
};
}
function fail(message: string): never {
console.error(`[verify] FAIL: ${message}`);
process.exit(1);
}
function parseRate(rate: string | undefined): number {
if (!rate) return 0;
const [num, den] = rate.split('/').map(Number);
if (!num || !den) return Number(rate) || 0;
return num / den;
}
function probe(path: string): Probe {
const raw = execFileSync(
'ffprobe',
[
'-v',
'error',
'-select_streams',
'v:0',
'-show_entries',
'stream=width,height,r_frame_rate,avg_frame_rate',
'-show_entries',
'format=duration,size',
'-of',
'json',
path,
],
{ encoding: 'utf8' }
);
return JSON.parse(raw) as Probe;
}
function verifyVideo(path: string) {
if (!existsSync(path)) fail(`${path} is missing`);
if (statSync(path).size === 0) fail(`${path} is empty`);
const data = probe(path);
const stream = data.streams?.[0];
if (!stream) fail(`${path} has no video stream`);
const duration = Number(data.format?.duration ?? 0);
const fps = parseRate(stream.avg_frame_rate || stream.r_frame_rate);
if (stream.width !== VIDEO_SIZE.width || stream.height !== VIDEO_SIZE.height) {
fail(`${path} is ${stream.width}x${stream.height}, expected ${VIDEO_SIZE.width}x${VIDEO_SIZE.height}`);
}
if (duration < MIN_DURATION_S || duration > MAX_DURATION_S) {
fail(
`${path} duration is ${duration.toFixed(2)}s, expected ${MIN_DURATION_S}-${MAX_DURATION_S}s`
);
}
if (Math.abs(fps - OUTPUT_FPS) > 0.1) {
fail(`${path} is ${fps.toFixed(2)}fps, expected ${OUTPUT_FPS}fps`);
}
console.log(
`[verify] ${path}: ${stream.width}x${stream.height}, ${duration.toFixed(2)}s, ${fps.toFixed(2)}fps`
);
}
function verifyImage(path: string) {
if (!existsSync(path)) fail(`${path} is missing`);
if (statSync(path).size === 0) fail(`${path} is empty`);
console.log(`[verify] ${path}: ${statSync(path).size} bytes`);
}
const videoPath = process.argv[2] ?? `${OUTPUT_DIR}/recording.mp4`;
const posterPath = process.argv[3] ?? (process.argv[2] ? undefined : `${OUTPUT_DIR}/poster.jpg`);
verifyVideo(videoPath);
if (posterPath) verifyImage(posterPath);