Open source · Apache-2.0

Narrated presentations, cut to the word.

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.

$uv tool install decktalk
Read the quickstart
Watch the demo · 4:01 · sound on
Made with DeckTalk. A markdown script and HTML slides, narrated and cut to the word.Captions available in the player.
How it works

Update your video the way you update a doc.

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.

01 WRITE
script.md
## 1. Open
A bowl. [beat] A ball. [beat]
Watch it step down on my
count. [beat] One. [beat]
Two, three. [beat]

A script in markdown

One heading starts one section. Bracketed directions are not spoken.

02 NARRATE
build/audio/01-open.words.json
{ "word": "One",
  "start": 4.485 }
cues.json
{ "cue": "1.1one",
  "on": "One" }

Your voice reads it

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.

03 RECORD
deck/index.html
<g data-cue="1.1one"
   data-fx="none">
  <rect class="box full"/>
  <text>one</text>
</g>

Slides reveal on cue

Chromium records the plain HTML, and the page runtime shows each step when its word is spoken.

04 ASSEMBLE
$ decktalk build
[cut ] 01 -> 01-section.mp4
[caps] 35 cue(s) -> srt, vtt
$ decktalk verify
cue         at  offset
1:1.1one  4.49  -10ms

Cut to the frame

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.

What you get

Built for the tenth edit, not the first take.

[lead] 01 trim 1.440s

Frame-exact cuts

Each recording opens on a magenta cover until narration starts. The cut is measured from the frames, not from a timer.

[skip] 01-open.mp3 unchanged

Cached narration

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.

[mix ] 3 audio input(s)

A soundscape

An underscore ducks under speech, ambience beds and effects land on cues, and the mix meets streaming loudness. Every part is optional.

1:1.1one -10ms changed

Verified output

Black or truncated recordings stop before assembly. A cue that cannot be found stops the build. A check proves each cue moved pixels.

From install to a first video.

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