Hypernatural

TechniqueBy HypernaturalVersion 2, Oct 29, 2026

python-time-lyrics

Time a song's lyric sheet word by word against speech-to-text of the vocal stem (ElevenLabs STT or whisper-cli JSON): each sung line matched in order, a misheard word keeping the STT's timing under the lyric's text, a dropped word interpolated and marked ?, a clean section's timing copied onto a repeat STT garbled, and every line printed with its bar. Use to cue kinetic lyric captions and karaoke-style words on the syllable.

SKILL.md

Time a lyric sheet

Give it the lyric sheet, the vocal stem's word timings and the song's beats.json; get lines.json, every sung line with a start and end per word, and a printout of each line with its bar and the words to check by ear. Use it when captions must land on the syllable. recipe-multi-style-music-video aligns lyrics more simply (sequence-match and interpolate, in its own steps) and is enough for captions per line.

Inputs

  • The lyric sheet as text: one sung line per line; blank lines are skipped and a [Chorus] style header names the section of the lines under it. Add ad-libs the sheet leaves out ("oh, oh") as their own lines if they should be captioned; leave them out and they are skipped.
  • Word timings of the vocal stem, never the mix (demucs-split-song-stems): ElevenLabs speech-to-text JSON (words with text, start, end, type) or whisper-cli JSON from -ml 1 -oj (one segment per word, offsets in milliseconds).
  • beats.json from python-map-song-bars, for bar numbers and --repeat.

Run it

Write references/time_lyrics.md's script into the job's scripts/ as time_lyrics.py, unchanged, and run it:

exec("python", ["scripts/time_lyrics.py", "--lyrics", "source/lyrics.txt",
     "--stt", "analysis/vocals_stt.json", "--beats", "analysis/beats.json",
     "--out", "captions/lines.json", "--from", "15", "--repeat", "29", "68", "7"],
     cwd="<job>", skill="python-time-lyrics")
  • --from S skips STT words before S seconds: a hook sung in the intro that the sheet places later would otherwise swallow the first lines.
  • --repeat SRC DST BARS gives the lines that start in bars DST to DST+BARS the timing of the lines in SRC to SRC+BARS, moved by the bar grid. Use it when one repeat of a chorus comes back garbled and another is clean. Both ranges must hold the same number of lines; the script stops and says so when they don't. Repeatable.

What you get

lines.json: [{text, section, words: [{text, start, end, matched}]}], in sheet order, the lyric's own spelling with the singer's timing, plus repeat_of on copied lines. The printout:

  31.42-  34.80 bar   14 Chorus         Hold the line until the morning
  35.10-  37.95 bar   16 Chorus         we were never? meant to fall
  • A misheard word (sung "there", heard "dare") keeps the STT word's time under the lyric's text, matched: true.
  • A dropped word (STT lost "I'll") gets a time 0.25 s before the next matched word and matched: false, printed with ?. Check every ? by ear.
  • A line with no match at all follows the line before, every word ?: look at the STT around it, then fix with --from or --repeat, or by hand.

Tips and traps

  • STT on a sung vocal mishears and drops words, even on the vocal stem, and in the worked job it garbled the timing of one chorus out of three while the other two were clean: --repeat copied a clean one onto it.
  • Fast repeated words ("go, go, go, go") come back merged or missing. Put them on the beat grid (beats in beats.json) instead of the STT.
  • Caption what is sung. Where the singer changed a word from the sheet, change the sheet line, then re-run.
  • Each line is matched against the next few STT words after the line before (eight more than the line's length), so a line far out of order on the sheet won't be found: keep the sheet in sung order, repeats written out.
  • After a new mix or a trimmed song head, transcribe again and re-run; old times are wrong by however much the audio moved.

Check it

  • No ? left that you haven't listened to.
  • Every line's bar matches the shot list (python-map-song-bars printout).
  • Render captions over a few lines (hn4a-compositor-motion-graphics) and watch with sound: each word lands on its syllable, not a word early or late.

Go make something cool.

Install the app, open your agent, describe the video. That's the whole onboarding.

Sticker HypernaturalSticker BannerSticker TVBoy