Audio Track
REQUIRED BACKGROUND: marketing-studio skill. Work in C:/Projects/animations.
Read the PLAYBOOK's Audio section first (endpoints, ducking, manifest contract).
Every film gets this pass; it is not opt-in (CLAUDE.md: a film is not done without
audio, and audio means narration). node scripts/check-audio.mjs <brand> is the exit
gate for all three recipes that touch video.
Three modes; pick by what the target is:
- Bespoke film (
studio/src/films/<brand>/, e.g. PostflopFilm) — post-render
scoring with scripts/build-<brand>-film-audio.mjs + scripts/score-film.mjs.
Recipe A0.
- Video soundtrack — a LaunchVideo template composition re-rendered with music +
voiceover (
out/<brand>/<asset>-audio.mp4). Recipe A.
- Standalone audio — a music track and/or narration mp3s delivered as files
(a sting, a jingle, a narration for something outside this studio). Recipe B.
Both need ELEVENLABS_API_KEY in the repo .env (missing key = feeder exits 2;
videos stay silent). Generation costs real money: one pass, trim copy rather than
regenerate blindly. Free tier returns 402; Starter or above required.
Recipe A0: bespoke film
- Shared-repo guard + toolchain per marketing-studio.
- Copy source of truth:
scripts/build-<brand>-film-audio.mjs (copy postflop's).
Narration lines carry the film SECOND they start on, computed from the film's
timeline.ts so a re-timed shot moves its line with it; SFX cues carry the frame the
shot lands something on (Stamp/Rule/click constants + the shot's from), max two
per beat. Budget ~2.6 words/second minus a 150ms breath per line.
- Run it (VO lines and the exact-length bed hit the API once; re-runs reuse files,
--force <id,...|music> regenerates). Read the printed start/end table: every line
inside its shot.
node scripts/score-film.mjs <brand> out/<brand>/film/film-vN.mp4 — refuses
overlapping lines (trim copy, re-run the builder) and zero-VO manifests; masters by
measured gain and verifies the DELIVERED file (I within 0.5 of TARGET_I, TP <= -1).
- Listen-proof:
node scripts/verify-cue.mjs <scored.mp4> <voStart> <voDur> on one
narration window and one bed-only window (voice ~6 dB above the bed), then
node scripts/check-audio.mjs <brand> (exit 0), then SEND the scored file.
Recipe A: video soundtrack
- Shared-repo guard + toolchain per marketing-studio.
- Copy source of truth:
scripts/build-<brand>-audio.mjs (copy the noban one for a
new brand). VO lines are keyed by act, written FOR THE EAR ("dot gg", not ".gg"),
one line per act, terse. Music prompt describes the brand's sonic character.
- Run it:
node scripts/build-<brand>-audio.mjs (music takes 1-3 min). Check every
line's duration fits its act; trim TEXT if not, re-run with --force.
- Merge + render:
node scripts/merge-launch-audio.mjs then render the composition
with the merged props.
- Listen-proof: verify the mp4 has an audio stream (ffprobe), then SEND the video —
audio is approved by ear, by the user. Ducking feel (base 0.35 / duck 0.12) is
tunable in
studio/src/lib/audioMix.ts if redlined.
Recipe B: standalone audio
- Shared-repo guard per marketing-studio (the feeder lives in the engine repo even
for standalone output).
- Music:
node feeders/audio/client.mjs music --prompt "<sonic character>" --length-ms <n> --out out/<brand>/<name>.mp3
(exact-length, commercially licensed on paid plans; 3s-120s).
Voiceover: write {lines: [{id, text}]} to a temp JSON (text written for the ear),
then node feeders/audio/client.mjs vo --script <json> --out out/<brand>/.
Durations print as ... OK: <name> <ms>ms; probe --file <mp3> re-measures.
- Listen-proof: SEND the mp3(s) to the user, then copy approved files into the
calling repo per the marketing-studio delivery contract.
1---2name: audio-track3description: Create music, voiceover, narration, or standalone audio; /audio-track.4---56# Audio Track78**REQUIRED BACKGROUND:** marketing-studio skill. Work in `C:/Projects/animations`.9Read the PLAYBOOK's Audio section first (endpoints, ducking, manifest contract).1011Every film gets this pass; it is not opt-in (CLAUDE.md: a film is not done without12audio, and audio means narration). `node scripts/check-audio.mjs <brand>` is the exit13gate for all three recipes that touch video.1415Three modes; pick by what the target is:16- **Bespoke film** (`studio/src/films/<brand>/`, e.g. PostflopFilm) — post-render17 scoring with `scripts/build-<brand>-film-audio.mjs` + `scripts/score-film.mjs`.18 Recipe A0.19- **Video soundtrack** — a LaunchVideo template composition re-rendered with music +20 voiceover (`out/<brand>/<asset>-audio.mp4`). Recipe A.21- **Standalone audio** — a music track and/or narration mp3s delivered as files22 (a sting, a jingle, a narration for something outside this studio). Recipe B.2324Both need `ELEVENLABS_API_KEY` in the repo `.env` (missing key = feeder exits 2;25videos stay silent). Generation costs real money: one pass, trim copy rather than26regenerate blindly. Free tier returns 402; Starter or above required.2728## Recipe A0: bespoke film29301. Shared-repo guard + toolchain per marketing-studio.312. Copy source of truth: `scripts/build-<brand>-film-audio.mjs` (copy postflop's).32 Narration lines carry the film SECOND they start on, computed from the film's33 timeline.ts so a re-timed shot moves its line with it; SFX cues carry the frame the34 shot lands something on (Stamp/Rule/click constants + the shot's `from`), max two35 per beat. Budget ~2.6 words/second minus a 150ms breath per line.363. Run it (VO lines and the exact-length bed hit the API once; re-runs reuse files,37 `--force <id,...|music>` regenerates). Read the printed start/end table: every line38 inside its shot.394. `node scripts/score-film.mjs <brand> out/<brand>/film/film-vN.mp4` — refuses40 overlapping lines (trim copy, re-run the builder) and zero-VO manifests; masters by41 measured gain and verifies the DELIVERED file (I within 0.5 of TARGET_I, TP <= -1).425. Listen-proof: `node scripts/verify-cue.mjs <scored.mp4> <voStart> <voDur>` on one43 narration window and one bed-only window (voice ~6 dB above the bed), then44 `node scripts/check-audio.mjs <brand>` (exit 0), then SEND the scored file.4546## Recipe A: video soundtrack47481. Shared-repo guard + toolchain per marketing-studio.492. Copy source of truth: `scripts/build-<brand>-audio.mjs` (copy the noban one for a50 new brand). VO lines are keyed by act, written FOR THE EAR ("dot gg", not ".gg"),51 one line per act, terse. Music prompt describes the brand's sonic character.523. Run it: `node scripts/build-<brand>-audio.mjs` (music takes 1-3 min). Check every53 line's duration fits its act; trim TEXT if not, re-run with --force.544. Merge + render: `node scripts/merge-launch-audio.mjs` then render the composition55 with the merged props.565. Listen-proof: verify the mp4 has an audio stream (ffprobe), then SEND the video —57 audio is approved by ear, by the user. Ducking feel (base 0.35 / duck 0.12) is58 tunable in `studio/src/lib/audioMix.ts` if redlined.5960## Recipe B: standalone audio61621. Shared-repo guard per marketing-studio (the feeder lives in the engine repo even63 for standalone output).642. Music: `node feeders/audio/client.mjs music --prompt "<sonic character>" --length-ms <n> --out out/<brand>/<name>.mp3`65 (exact-length, commercially licensed on paid plans; 3s-120s).66 Voiceover: write `{lines: [{id, text}]}` to a temp JSON (text written for the ear),67 then `node feeders/audio/client.mjs vo --script <json> --out out/<brand>/`.68 Durations print as `... OK: <name> <ms>ms`; `probe --file <mp3>` re-measures.693. Listen-proof: SEND the mp3(s) to the user, then copy approved files into the70 calling repo per the marketing-studio delivery contract.