---
name: voiced-explainer-video
description: Use when making a short voiced explainer or "build in public" video for X, TikTok or YouTube Shorts with HyperFrames - voice-first timing, whisper-timed captions, code-written music, one composition rendered in 16:9 and 9:16, and the checks to run before posting (flicker, loudness, intelligibility).
---

# Voiced explainer video (X + TikTok + Shorts)

This is a recipe from @I_Ship_With_AI, refined over five published videos. It sits on top of the
HyperFrames skills (`npx skills add heygen-com/hyperframes`); use those for the mechanics of
compositions and rendering. This skill covers the decisions that make the result feel edited by a
person.

## 0. Before writing anything
- **One sentence of story.** Use the Brag skill if you have it: hook → proof → punchline.
- **Verify every on-screen fact against a source,** and keep a `plan.md` with fact → source.
  If something never happened, say "would have", never "did".
- **Never show code, file paths, file names or internal tooling on screen.** Describe it in plain
  words instead. Viewers read code on screen as clutter or as exposing your product.

## 1. Voice first, picture second
- Write the narration as a list of lines (`lines.json`), one sentence or beat per line.
- Synthesize one TTS call per line: `npx hyperframes tts "<line>" -v am_michael -s 1.08 -o lNN.wav`
  (a Kokoro voice, local and free).
- Lay the lines out on a **120 BPM grid**:
  - every scene starts on a beat (multiples of 0.5 s);
  - a scene lasts until its last line ends plus a breath, or until its minimum picture time,
    whichever is later.
- When trimming silence off each line before concatenating, **keep at least ~180 ms after the last
  loud sample.** Final consonants are quiet. A 20 ms tail cut the "d" off "Code" and the "k" off
  "click", and listeners (and whisper) heard "Cogue" and "clip".
- Run faster-whisper (`large-v3-turbo`, `word_timestamps=True`) over the assembled narration and
  keep **word times**.
- Never put an impact or a riser peak on the first word of a call to action; its tail masks the
  word.

## 2. Captions
- **Caption TEXT comes from the script; caption TIMES come from whisper.** Whisper mishears names
  and homophones ("Code" → "Cogue", "click" → "clip"), drops "So"/"And", and writes numbers as
  digits. Keep an alias table and match tokens with a small look-ahead.
- Use chips of at most 5 words, split evenly, with the active word highlighted.
- A line that is already big on screen gets no caption chip.

## 3. Picture
- Every hit lands on the word that says it: a stamp, a counter reaching its number, a ✓.
- Change scenes by dipping out then in. Do not crossfade.
- **Frame 0 is the thumbnail.** Compose it as a settled, curious frame. Never bake a different
  poster frame in afterwards; a one-frame swap reads as flicker.
- **No grain, noise or per-frame jitter.** Viewers call it flicker. Static vignettes and slow
  glows are fine.
- **No `Math.random()` and no GSAP `stagger: { from: "random" }`.** Render workers would disagree
  frame to frame. Pre-pick random indices with a seeded PRNG at build time.
- **Two formats from one timeline.** Keep a layout table per format (text box, visual box, caption
  position) and use only relative offsets in tweens. On 9:16, keep important content above the
  bottom ~25% (TikTok's caption area) and away from the right-edge buttons.

## 4. Music written as math
- numpy/scipy synthesis: kick, clap, hats, bass, pads, plucks, plus SFX (whoosh, stamp, click,
  chime, buzz, riser, impact). There are no samples, so there are no licensing questions.
- Place the score on the same grid and read the sync points the build writes (`sync.json`) so
  every SFX hits its on-screen moment.
- **Duck the music −9 dB under the voice, except the closing line**: −2 dB there, with the groove
  already playing from the start of the outro scene. A drop right at the punchline feels wrong.

## 5. Checks before posting
1. `npx hyperframes check` passes. Mark intentional overlaps with `data-layout-allow-overlap`.
2. Snapshots of every scene and of mid-transitions, in both formats (`snapshot --describe false`).
3. **Flicker:** run ffmpeg `signalstats` YDIF per frame. The max should stay under ~15 except on
   deliberate cuts.
4. **Loudness:** about −16 to −15 LUFS integrated, true peak below −1 dBTP, measured after the
   AAC encode.
5. **Intelligibility:** whisper on the final MP4 must hear every line through the music.

## 6. What the person does
The first render is never the one you post. Watch it and say what's wrong in plain words. Every
note becomes a rule for next time; write those rules into this file.
