Skip to main content
decktalk.toml is the project file. It maps each section to a page or a clip, and it sets the voice, the transitions, and the sound. Use this page to look up a table or a key and its default. The file sits in the project root. Every path in it is relative to that directory.

Minimal file

The smallest file that loads has one page section.
decktalk.toml
decktalk init writes a nine-section file with comments. Sections 5 and 7 are optional clip sections. This fuller example adds a clip section, a dip to black, and an underscore.
decktalk.toml

Load rules

Every project command loads decktalk.toml first. The load fails in each of these cases.
  • A top-level table is unknown.
  • The file has no [[section]] table.
  • A required key is missing.
  • A value has the wrong type. For example, seconds = 120.5 under [soundscape.music] fails.
  • Two sections share a number.
  • A section has both page and clip, or neither.
  • extra_seconds, hold_seconds, lead_seconds, or tail_seconds is below 0.
  • carries_previous is set on the first section.
  • A dips pair or a [[mix.sfx]] table names a section that does not exist.
The error names the table and the key.
An unknown key inside a table does not fail the load. DeckTalk prints a warning, ignores the key, and continues. The same rule covers the tuning tables and the per-machine file.
A page section key on a clip section, or a clip section key on a page section, gets its own warning. The warning names the section kind that the key belongs to.

Which value wins

  • --model wins over [voice] model, which wins over [narration] model.
  • A tuning table in decktalk.toml wins over the per-machine file. A DECKTALK_<TABLE>_<FIELD> variable and a command option win over both.
  • The project tables on this page have no environment variables.
Configuration lists the five layers for tuning tables.

[project]

[voice]

[voice] sets how the voice sounds. The API key and the voice id are secrets, so they live in .env as ELEVENLABS_API_KEY and ELEVENLABS_VOICE_ID, or in the environment. Note: each key is part of every section’s cache key. After a change, the next voiced build voices every section again. What spends credits lists every change that costs credits. An unregistered provider fails when narrate runs, not at load.

[[section]]

Write one [[section]] table for each ## N. section of the script. DeckTalk sorts sections by number, so the order in the file does not matter. Each section is a page section or a clip section.

Keys for every section

Page section keys

Note: params values become strings. A beats key replaces the cue times, a scene key replaces scene, a words key replaces the spoken words, and a prevwords key replaces the previous section’s words. t0 is always signal, whatever params says.

Silence in a section

Three keys add silence to a page section. None of them is sent to the voice or changes the narration cache, so a cached take stays cached.
  • The section starts when its silence starts. So lead_seconds moves every word and every word cue of the section later, and $start stays at 0.
  • The recording covers the lead, because the section span in timeline.json includes it.
  • tail_seconds is a least value, like min_tail_seconds. A take that already has a longer tail keeps it.
  • A hold on any page section pauses the narration, as a clip between page sections does. The next section starts after the hold, on its own words.
  • A [pause N] before a section’s first words is removed. Use lead_seconds to open a section on silence.
decktalk.toml
Set carries_previous = true when a section continues the previous section’s picture, such as a page that opens where the last page ended. verify compares the two frames at the cut, outside any dip. A dip still fades through black, so leave the pair out of [transition] dips for a cut that should not show. Cut continuity defines the check.

Clip section keys

A clip section follows three rules.
  1. A clip section can sit before, between, or after page sections.
  2. The narration pauses for a clip between page sections, and resumes with the next page section.
  3. If the file is missing, a titled slate plays for slate_seconds. With --strict, assemble and build fail instead, unless the section sets optional = true.
Set optional = true while the clip is not ready. Delete that line after you add the clip. DeckTalk scales and pads the clip to the frame size. A clip section has captions only when it sets words, and chapters include the clip. Add a clip section shows the whole task.

[transition]

Note: leave out dips to dip at every cut. Set dips = [] for no dips. Audio never dips.

[mix]

[mix] is optional. Without it, the video carries narration and clip audio only. Sound explains how the parts fit together. Note: a missing underscore or ambience file does not fail the build. assemble logs a warning, such as underscore missing (<path>); no music, and plays the video without it.

[[mix.sfx]]

Write one [[mix.sfx]] table for each sound effect. Put a sound effect on a cue shows the task. Note: this offset belongs to the sound effect, not to the cue. A missing file or an unresolved cue does not fail the build. assemble logs skipped for that sound effect.

[mix.loudnorm]

[mix.loudnorm] sets the targets of the loudness pass. Loudness explains the pass. Note: the keys work in upper or lower case. A silent build skips the loudness pass.

markers.json

A markers file swells or mutes the underscore at spoken phrases. [mix] markers names it, and the scaffold’s file is media/markers.json.
media/markers.json
  • Markers apply only when the underscore file exists. --nomix turns them off.
  • $start works on any section. A phrase or $end needs a spoken section.
  • A phrase matches by the same rules as a cue phrase.
  • If the file is missing, assemble logs markers file missing (<path>); underscore without structure.
  • If a marker does not resolve, assemble logs marker '<name>' unresolved; skipped.
  • A file that is not valid JSON fails assemble with a ConfigError.

[soundscape]

[soundscape] holds the prompts for decktalk soundscape, which generates sound with ElevenLabs. Each item writes to a default path unless its out key names another.
  • [soundscape.ambience] writes to [mix] ambience, else to build/sfx/ambience.mp3.
  • [soundscape.music] writes to [mix] underscore, else to build/music/underscore.mp3.
  • [soundscape.sfx.<name>] writes to build/sfx/<name>.mp3.

[soundscape.ambience]

[soundscape.sfx.<name>]

[soundscape.music]

Note: a length above [elevenlabs] max_music_chunk_seconds (300) is requested in parts, and DeckTalk crossfades the parts. The scaffold sets seconds = 120.

Tuning tables

decktalk.toml can also hold the tuning tables, such as [video] or [record]. A tuning table in the project overrides the per-machine file. Configuration lists every field with its default.