Fills the foundation stubs in ingest.py and audio_sync.py. - ingest: ffprobe probe + mono 16 kHz WAV extraction per video (ffmpeg); idempotent run_ingest reuses existing rows so synthetic -> ingest -> sync works without unique-constraint collisions. - sync: PHAT-whitened GCC-PHAT pairwise offsets with sub-sample parabolic peak refinement, scored by peak-to-second-peak ratio; confidence-weighted global least-squares solve with cycle-consistency rejection (>50 ms); windowed drift estimation (ppm) with a 5 ppm deadband; disconnected sync-graph components -> offset_ms=None (spec pitfall #5). - Persists offset_ms/drift_ppm/sync_confidence via db.update_video_sync and exports data/work/sync.json. Verified on the synthetic fixture: synthetic -> ingest -> sync recovers the ground-truth offsets (0 / +1370 / -842 ms) to <0.001 ms and drift 0 ppm, well inside the spec M1 tolerances (+/-10 ms, +/-3 ppm). pytest: 43 passed (24 foundation + 19 new in test_ingest.py and test_audio_sync.py). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.8 KiB
Status — lane-A
Round 0 — 2026-07-16 — STATUS: in_progress
Directives acknowledged: round 0 of plan/DIRECTIVES.md (run order & protocol; Lane A = spec M1).
Acceptance checklist (spec M1 + lane brief):
ingest: ffprobe each file indata/raw, register invideos, extract mono 16 kHz WAV per video intodata/work/audio/.sync: GCC-PHAT (PHAT-whitened, not raw xcorr) pairwise offsets, scored by peak-to-second-peak ratio.- Global least-squares solve over the offset graph, confidence-weighted, cycle-consistency rejection (>50 ms).
- Drift: windowed GCC-PHAT, line fit →
drift_ppm; store 0 if|drift| < 5 ppm. - Disconnected sync-graph components →
offset_ms = None(spec pitfall #5). - Persist
offset_ms/drift_ppm/sync_confidenceviadb.update_video_sync; exportconfig.SYNC_JSON. python -m festival4d ingest && python -m festival4d syncrecovers GT offsets (±10 ms) and drift (±3 ppm).pytestgreen (newtest_ingest.py,test_audio_sync.py); synthetic end-to-end intact.
Done this round: branched lane/a-media from main; baseline pytest green (24 passed). Verified env: ffmpeg/ffprobe present, librosa 0.11, scipy 1.18; synthetic fixtures (data/raw/cam{0,1,2}.mp4, DB rows GT offsets 0/+1370/−842) in place. Implementing ingest.py + audio_sync.py.
Blockers / questions for coordinator: none. sync.json schema is unspecified by the spec — designing a self-describing schema (reference id, per-video offset/drift/confidence, raw edges, components); no consumer depends on it (API reads the DB), so no change request needed.
Next: implement both modules, validate GCC-PHAT against the real extracted fixture audio, write tests, run acceptance, then update status → ready_to_merge.