Audio-clocked playback for judging sync

Lip sync cannot be judged silently. extract.sh now pulls the audio track and
writes manifest.json alongside the frames; the page reads the true extraction
rate from it rather than assuming one, since a guessed fps desynchronises
picture from sound - the one thing this view exists to show.

Audio is the clock: frame = floor(currentTime * fps). A slow render loop drops
frames instead of drifting, and half/quarter speed work via playbackRate with
the picture following for free. Scrubbing, stepping and clicking a thumbnail
all seek the audio too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-09-24 14:53:09 -04:00
parent a082208ad5
commit 5ac919b9d6
7 changed files with 157 additions and 36 deletions

View file

@ -7,7 +7,8 @@ const r = (v) => Math.round(v);
export function writeTake(take) {
const L = [];
L.push(`take name=${take.name} frames=${take.frames} width=${take.width} height=${take.height} exposure=${take.exposure}`);
L.push(`take name=${take.name} frames=${take.frames} width=${take.width} height=${take.height}` +
` exposure=${take.exposure}${take.fps ? ` fps=${take.fps}` : ''}`);
L.push('');
take.palette.forEach((p, i) => L.push(`pal ${i} ${p.name.padEnd(11)} ${i}`));
L.push('');