Skip to main content
decktalk build turns your script and pages into one mp4 in seven stages. To build your first video, follow the Quickstart.
Four panels. Write shows a markdown script. Narrate runs narrate and beats, and shows a tick for every word of "A bowl. A ball. One. Two, three." with 1.25 over "bowl". Record runs record, measure, and check, and shows a slide where a bowl draws on and a ball steps down it. Assemble runs assemble and verify, and shows one mp4.Four panels. Write shows a markdown script. Narrate runs narrate and beats, and shows a tick for every word of "A bowl. A ball. One. Two, three." with 1.25 over "bowl". Record runs record, measure, and check, and shows a slide where a bowl draws on and a ball steps down it. Assemble runs assemble and verify, and shows one mp4.

Each panel names the pipeline stages it runs, in order.

  1. You write four files: script.md, decktalk.toml, cues.json, and the page.
  2. The speech provider voices the script and returns a start and an end time for every word.
  3. Headless Chromium records each page section, and each reveal fires at its cue time.
  4. ffmpeg cuts each recording to its section and joins the sections into one mp4.
  5. verify measures the final mp4, so an early or late reveal shows as a number.

Stages

The seven stages always run in this order. Each stage reads files that the stages before it wrote. Each stage is also a command with the same name, and the CLI reference lists them. Build artifacts gives the fields of every file. assemble also runs the loudness pass.

Why the cuts are exact

Each reveal starts on its word because DeckTalk finds narration t=0 inside every recording, to the frame.
A strip of recorded frames. Three magenta cover frames come first, and a line marks t=0 at the first clean frame. Under the strip, the narration "A bowl. A ball. Watch it step down" starts at t=0. Dashed leads join "bowl" and "ball" to the outlined frames where the bowl and then the ball appear.A strip of recorded frames. Three magenta cover frames come first, and a line marks t=0 at the first clean frame. Under the strip, the narration "A bowl. A ball. Watch it step down" starts at t=0. Dashed leads join "bowl" and "ball" to the outlined frames where the bowl and then the ball appear.

The bowl and the ball each appear whole in the first frame after their words.

The recorder removes the cover only when the page is ready. The handshake shows each wait. measure looks for the cover only in the first [align] scan_seconds of each recording, 4 s by default. The alignment never depends on wall-clock time.

The silent build

A silent build replaces the voice with a click track, so it needs no account and no API key.
  • The click track has a soft click at the start of every estimated word, at -24 dBFS.
  • narrate spaces the estimated words evenly at silent_words_per_minute, 150 by default. It adds each pause, beat, and tail. script.md gives the length rule.
  • Every other stage runs as usual. A silent build therefore tests the cues, the pages, the recording, the cut, and the checks.
  • The narrate and beats tables mark their times as estimated.
  • The clicks let verify compare the picture with the sound in the final mp4. Verify explains the check.
  • A silent build skips the loudness pass, so the clicks keep their level.
A silent build stops when the project has voiced takes, because it would empty the narration cache. A silent build and a voiced build explains the cost.

Clips and the narration

A clip section plays a video with its own audio. narrate, record, and measure skip it, and the narration pauses for a clip between two page sections.
Lanes on one time axis. The narration.mp3 lane holds sections 1, 2, 3, 4, 6, 8, and 9 back to back, with a split before sections 6 and 8. The video lane plays the 4 s clip of section 5 after section 4 and the 5.04 s slate of section 7 after section 6, and dashed leads move sections 6, 8, and 9 later. Captions sit under page sections only. Chapters mark the start of each title, and the five sections titled The edit share one.Lanes on one time axis. The narration.mp3 lane holds sections 1, 2, 3, 4, 6, 8, and 9 back to back, with a split before sections 6 and 8. The video lane plays the 4 s clip of section 5 after section 4 and the 5.04 s slate of section 7 after section 6, and dashed leads move sections 6, 8, and 9 later. Captions sit under page sections only. Chapters mark the start of each title, and the five sections titled The edit share one.

The narration pauses for each clip and resumes with the next page section.

Add a clip section shows how to place a clip and how the narration splits.

Caching

narrate keeps each section’s audio and a hash of its text in build/audio/manifest.json. After an edit, decktalk build voices again only the sections whose text changed. A plain build still records every page section, and decktalk build --only N records only section N. A recording stays valid when a neighbor section changes length, because cue times count from the start of their own section. Rebuild one section says what each edit runs again.

What verify checks

verify checks the final mp4 in three ways.
  • Section starts: the frame 0.2 s after each section start has a pixel brighter than luma 60.
  • Cuts: the narration is at or below -40 dBFS in the last 0.15 s before each cut.
  • Cues: the picture changes within 80 ms of each cue time. After a silent build, it also changes within 120 ms of the click plus the offset key.
The verify stage inside decktalk build checks section starts and cuts, and cut continuity for a section that sets carries_previous. decktalk verify also checks the cues. Verify defines every measurement, limit, and result.

Terms

Next