You write a markdown script and plain HTML slides. Your cloned voice reads the script. DeckTalk produces one mp4 in which every reveal lands on the word that introduces it. Change a sentence, and only that section is voiced again.
Narration comes back with a time for every word, so a reveal follows a phrase rather than a second. DeckTalk builds the video from text you keep, so a changed sentence changes the video. Change a sentence, and only that section is voiced again. Follow one cue from the script to the frame.
script.md ## 1. Open A bowl. [beat] A ball. [beat] Watch it step down on my count. [beat] One. [beat] Two, three. [beat]
One heading starts one section. Bracketed directions are not spoken.
build/audio/01-open.words.json { "word": "One", "start": 4.485 } cues.json { "cue": "1.1one", "on": "One" }
The voice comes back with the audio and a timestamp for every word. A cue names a spoken phrase, and DeckTalk resolves it to the second the word starts.
deck/index.html <g data-cue="1.1one" data-fx="none"> <rect class="box full"/> <text>one</text> </g>
Chromium records the plain HTML, and the page runtime shows each step when its word is spoken.
$ decktalk build [cut ] 01 -> 01-section.mp4 [caps] 35 cue(s) -> srt, vtt $ decktalk verify cue at offset 1:1.1one 4.49 -10ms
ffmpeg cuts every section to the frame, so the box fills at 4.49 s, mixes the sound, and verify measures each reveal against its word.
Each recording opens on a magenta cover until narration starts. The cut is measured from the frames, not from a timer.
Each section's narration is cached by a hash of its text, voice, model, and settings. An edit synthesizes only the sections that changed, so you pay per change, not per build.
An underscore ducks under speech, ambience beds and effects land on cues, and the mix meets streaming loudness. Every part is optional.
Black or truncated recordings stop before assembly. A cue that cannot be found stops the build. A check proves each cue moved pixels.
The scaffold is the demo. A silent build takes a few minutes, because recording runs in real time. Build it silently first, and add your voice when you are ready.
$ uv tool install decktalk && decktalk setup $ decktalk init my-lesson && cd my-lesson $ decktalk build --silent # no key needed $ decktalk build # your voice