Skip to main content
DeckTalk writes every generated file under build/, and your own tools can read any of them. This page lists each file, its time base, and its fields. Field names in the JSON files match the dataclasses in decktalk.artifacts. The file shapes are part of the stable surface that the changelog tracks.
NN is the two-digit section number. slug comes from the section title in script.md. <name> is [project] name in decktalk.toml. A clip section has no mp3, words file, or recording.

Time bases

Each time in these files counts from a fixed starting point, its time base. Read the time base before you compare times from two files. A clip section adds its length to the final mp4, but not to narration.mp3. After a clip between two page sections, a time in the final mp4 is the narration time plus the length of every earlier clip. A clip before the first page section shifts every time. Page sections are cut on whole frames, so the two times can also differ by up to one frame. Example: in the silent build of the scaffold, section 6 starts at 196.70 s in timeline.json and at 201.08 s in the final mp4. The 4.36 s slate of clip section 5 sits between them, and the whole-frame cuts before it add 0.02 s. decktalk status prints narration times.

build/audio/NN-slug.words.json

A words file lists each spoken word of one section, with its times in that section’s mp3.
Note: A silent build writes estimated words, spaced evenly at silent_words_per_minute. Each estimated word ends 0.02 s before the next one starts. Note: decktalk words prints the same words in seconds after the section starts, with the script’s punctuation and case.

build/audio/manifest.json

The manifest is the narration cache. It holds one entry per spoken section.
Note: Captions take their spelling from spoken, so they match the audio even after the script changes. A manifest without spoken falls back to the current script. Rebuild one section explains what the hash covers.

build/audio/timeline.json

The timeline gives section and word times in narration.mp3.
Note: The section span runs from start to end. The spoken span runs from start to speech_end.

build/audio/beats.json

The beats file holds the cue times of each section, as the string the page receives in ?beats=. A section with no resolved cue is not in the file.
Each item is cue id@cue time, and a comma separates the items. Section 08 plays scene 7, so its cue ids start with 7.. The page parser splits each item at the last @.

build/audio/beats.anchors.json

The anchors file holds the start of each cued word without its offset key, per section. verify uses it after a silent build to find the click at the cued word.
Note: A cue with no offset key has the same time in both files. The a/v value explains why the anchor matters.

build/rec/NN-scene.json

The sidecar lists what the recorder did for one page section, and where narration t=0 sits in the webm.
Note: check reports PAGE ERROR for any entry in page_errors, and decktalk build stops. check reports STALLED when the part of a frame gap after t=0 is longer than [align] stall_ms. record sets lead_in_seconds to null, and measure fills it. assemble prints STALE MEASUREMENT when lead_in_seconds is null, when lead_in_hash does not match the webm, or, with no lead_in_hash, when the webm is newer than the sidecar.

build/out/

The out directory holds each cut section, the final video, its captions, and its chapters. Captions break at sentence ends.
  • A caption never spans two sections.
  • No caption covers a clip section, unless the section sets words. Those captions come from the clip’s words file.
  • A caption also ends before any silence of 1 s or more.
  • Whole sentences share a caption when they fit. A sentence too long for one caption splits at the comma nearest its middle, or else between two words that are not short words like “of” or “the”. Each part keeps at least three words.
  • A caption holds at most two lines of 42 characters. The line break goes after a sentence end or a comma when the two lines stay balanced.
  • No caption and no line is a single word, unless that word is a whole sentence.
  • A caption starts at its first word and ends 0.2 s after its last word, or when the next caption starts.
build/out/my-lesson.srt
build/out/my-lesson.chapters.txt

build/shots/

decktalk shots writes screenshots here. With two or more pages, it writes one folder per page, named after the page file.
Note: --page with one page file writes no page folder. --section frames never go in a page folder.

How files are written

DeckTalk writes files so that a reader never sees half of one.
  • Stages run one after another, and one build runs one Chromium.
  • manifest.json, timeline.json, beats.json, each words file, and each sidecar go to a temporary file first. A rename then puts each one in place.
  • The final mp4 is written to a work file, then renamed to build/out/<name>.mp4. The timestamped copy comes after the rename.
  • narrate saves the manifest after each paid request, so an interrupted voiced run keeps the sections it paid for.
  • An error is a DeckTalkError subclass that names the file or field. The command line prints it as error: … and exits 1.