LGTM
This commit is contained in:
parent
9248e26af2
commit
f2a2651b8a
95 changed files with 3993 additions and 1471 deletions
|
|
@ -1,6 +1,8 @@
|
|||
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';
|
||||
import { OUTPUT_DIR } from './config.js';
|
||||
import { viewportFor, type Storyboard } from './script.js';
|
||||
import { getStoryboard } from './storyboard.js';
|
||||
|
||||
interface Probe {
|
||||
streams?: {
|
||||
|
|
@ -48,7 +50,7 @@ function probe(path: string): Probe {
|
|||
return JSON.parse(raw) as Probe;
|
||||
}
|
||||
|
||||
function verifyVideo(path: string) {
|
||||
function verifyVideo(path: string, storyboard: Storyboard) {
|
||||
if (!existsSync(path)) fail(`${path} is missing`);
|
||||
if (statSync(path).size === 0) fail(`${path} is empty`);
|
||||
|
||||
|
|
@ -56,18 +58,23 @@ function verifyVideo(path: string) {
|
|||
const stream = data.streams?.[0];
|
||||
if (!stream) fail(`${path} has no video stream`);
|
||||
|
||||
const expectedSize = viewportFor(storyboard.video);
|
||||
const { minDurationS, maxDurationS, outputFps } = storyboard.video;
|
||||
|
||||
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) {
|
||||
if (stream.width !== expectedSize.width || stream.height !== expectedSize.height) {
|
||||
fail(
|
||||
`${path} duration is ${duration.toFixed(2)}s, expected ${MIN_DURATION_S}-${MAX_DURATION_S}s`
|
||||
`${path} is ${stream.width}x${stream.height}, expected ${expectedSize.width}x${expectedSize.height}`
|
||||
);
|
||||
}
|
||||
if (Math.abs(fps - OUTPUT_FPS) > 0.1) {
|
||||
fail(`${path} is ${fps.toFixed(2)}fps, expected ${OUTPUT_FPS}fps`);
|
||||
if (duration < minDurationS || duration > maxDurationS) {
|
||||
fail(
|
||||
`${path} duration is ${duration.toFixed(2)}s, expected ${minDurationS}-${maxDurationS}s`
|
||||
);
|
||||
}
|
||||
if (Math.abs(fps - outputFps) > 0.1) {
|
||||
fail(`${path} is ${fps.toFixed(2)}fps, expected ${outputFps}fps`);
|
||||
}
|
||||
|
||||
console.log(
|
||||
|
|
@ -81,8 +88,20 @@ function verifyImage(path: string) {
|
|||
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`);
|
||||
// Usage:
|
||||
// node dist/verify.js <storyboard> [videoPath] [posterPath]
|
||||
// Defaults: videoPath=output/<storyboard>/recording.mp4,
|
||||
// posterPath=output/<storyboard>/poster.jpg.
|
||||
// If videoPath is given but posterPath is not, the poster check is skipped.
|
||||
const storyboardName = process.argv[2];
|
||||
if (!storyboardName) {
|
||||
fail('verify: missing <storyboard> argument (e.g. `node dist/verify.js recording`)');
|
||||
}
|
||||
const storyboard = getStoryboard(storyboardName);
|
||||
|
||||
verifyVideo(videoPath);
|
||||
const videoPath = process.argv[3] ?? `${OUTPUT_DIR}/${storyboard.name}/recording.mp4`;
|
||||
const posterPath =
|
||||
process.argv[4] ?? (process.argv[3] ? undefined : `${OUTPUT_DIR}/${storyboard.name}/poster.jpg`);
|
||||
|
||||
verifyVideo(videoPath, storyboard);
|
||||
if (posterPath) verifyImage(posterPath);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue