| name | drama-video |
| description | Build a dialogue-first narrative video. Use when the user wants a "scene", "drama", "monologue", "dramatic clip", or a character acting through lines (not a music video). Spec authors the character, an ElevenLabs audio bed (dialogue + ambience + pauses) and a shot list whose start/duration aligns to the dialogue cues, then this skill renders flux anchors → LTX ia2v shots → vconcat + overlay full audio. Sibling to `music-video` (which is song-first and bar-aligned). |
drama-video
A narrative-first sibling to music-video. The primary axis is
dialogue — you author lines with pauses, generate them through
ElevenLabs (along with an ambience bed), and cut shots against the
per-line timestamps the API returns. Each shot is one LTX ia2v render
(image + audio slice → video); shots chain via @last so the character's
identity carries across cuts.
When to use this vs music-video
| Use | If the primary driver is |
|---|
music-video | a song (scene lengths snap to bars/BPM, transitions land on beat) |
drama-video | dialogue + ambience (shots align to cue boundaries, cuts happen at pauses or line starts) |
If the piece has both (song and dialogue over it), use music-video
and add the dialogue as a per-scene audio: override.
Spec shape
title: "Fennie's Moment"
description: "Fennie practising alone late at night…"
character:
name: Fennie
anchor: ./path/to/character_anchor.png
description: "Fennie — 17-year-old Korean ballet trainee…"
reference_sheet: ./path/to/sheet.png
video:
fps: 24
resolution: [1024, 576]
negative: "cartoon, text, watermark, distorted face, still frame, low quality, extra fingers"
tail_buffer_sec: 0.5
audio:
file: ./outputs/scene_complete.mp3
cues: ./outputs/scene_complete.cues.json
gate_confirm_audio: false
gate_confirm_anchors: true
shots:
- label: opening_focus
start_sec: 0.00
duration_sec: 13.43
image: "@anchor"
camera_lora: static
camera_lora_strength: 0.8
prompt: "Close-mid shot of {character} in a late-night dance studio…"
anchor:
type: i2i
reference: ./path/to/character_anchor.png
prompt: "Wide shot of the studio, overhead spot, wooden floor…"
- label: frustration
start_sec: 13.43
duration_sec: 10.85
image: "@last"
camera_lora: dolly-in
prompt: "{character} sinks onto the floor…"
Shot durations
Hard cap 15 s per shot (same as music-video, for the same LTX-2.3
OOM reasons). If a cue range is longer, split it into two shots with
the same prompt trend — you pick the visual cut point.
Continuation between shots (recommended for most drama)
A regular image: "@last" shot starts from the previous shot's last
single frame — LTX re-interprets that one frame and often produces a
visible cut even with the transition LoRA. For truly seamless
continuation, use the continue_from_prev flag:
shots:
- label: opening_focus
start_sec: 0.0
duration_sec: 4.68
image: "@anchor"
anchor:
type: i2i
reference: ./media/character.png
prompt: "The character in the studio, overhead light, …"
prompt: "Close-mid shot, she exhales, rises onto her toes …"
- label: first_attempt
start_sec: 4.68
duration_sec: 7.96
continue_from_prev: true
overlap_seconds: 1.0
overlap_strength: 1.0
prompt: "She attempts the spin, mid-motion, arms extended …"
How it works: the pipeline invokes the continuation comfyui workflow,
which loads the previous shot's mp4, extracts the last N frames via
LoadVideo → GetVideoComponents → GetImageRangeFromBatch, and injects
them as a multi-frame LTXVAddGuide(frame_idx=0, strength=overlap_strength)
on an empty latent. The rest of the shot is generated from the new
prompt + audio slice.
When to use continue_from_prev: same physical space, time flows
forward, character continues to be present. Most drama shots fit this.
When to fall back to anchor + fresh ia2v: hard scene change
(different room, different character, flashback). Skip
continue_from_prev on that shot; give it a fresh anchor: block.
Ingredients mode (silent inserts)
For B-roll / establishing / no-dialogue shots that must keep the recurring cast,
props and locations consistent, set mode: ingredients on the shot and provide a
project reference_sheet: (black-bg element panels — build it with
storyboard/scripts/generate_reference_sheet.py, aspect matching
video.resolution). The shot renders via the LTX-2.3 reference-sheet IC-LoRA:
reference_sheet: ./sheet.png
shots:
- label: pier_insert
start_sec: 41.0
duration_sec: 5
prompt: "wide insert: Marco alone on the pier at dusk, holding the trident"
mode: ingredients
Silent by design — ingredients shots carry no lipsync/dialogue (identity
comes from the sheet, not the identity_anchor); the full audio track is muxed
over the timeline at assemble. Use them only where on-screen speech isn't needed.
mode: ingredients is checked first in the dispatch (over
continuation/ia2v). Per-shot reference_sheet, negative,
ingredients_lora_strength (def 1.4) and ingredients_reference_strength (def
1.0) override the defaults. See the comfyui skill's ingredients command.
CLI
drama_video.py plan <spec.yaml> # show shots + audio alignment
drama_video.py audio <spec.yaml> # render audio via elevenlabs (if audio.spec set)
drama_video.py anchors <spec.yaml> # pre-render all shot anchors via flux2
drama_video.py shot N <spec.yaml> # render one shot (1-indexed)
drama_video.py shots <spec.yaml> # render all shots serially (skips existing)
drama_video.py assemble <spec.yaml> # vconcat + overlay the full audio
drama_video.py all <spec.yaml> # 1→5 end-to-end, with quality gates
drama_video.py status <spec.yaml> # show what's on disk
Each stage is idempotent — mp4s and anchors are skipped if already
present. To force a re-render, rm the artifact and re-run the stage.
Output layout
<project>/
spec.yaml
audio/ # if audio.spec was used
scene_complete.mp3
scene_complete.cues.json
shots/
001-opening_focus-anchor.png
001-opening_focus.mp3 # audio slice for this shot
001-opening_focus.mp4
001-opening_focus-last.png
…
final.mp4
run.log
Prompt conventions
- The top-level
character.description is available as {character}
inside any shot prompt (and anchor prompt). Recurring-character
substitution just like music-video's subjects: block — useful so
you don't copy/paste the identity description into every shot.
- Inside anchor prompts, refer to the character by name or via
{character} so flux2 i2i preserves identity when blending with a
new scene environment.
- Keep shot prompts tight: one sentence for setting, one for action,
one for camera motion. Long shot prompts compete with the character
anchor and drift identity.
Gotchas
- Shot 1's
@anchor resolves to character.anchor; later shots
with image: "@last" chain from the prev shot's -last.png. First
shot must have either @anchor or a literal image: path.
- The
audio block must exist before shots stage runs. If you set
audio.spec:, the audio stage renders it; otherwise audio.file:
must already exist on disk.
- Shot
start_sec + duration_sec must stay within the audio file's
length. plan checks this.
- If your audio has
cues.json, plan warns when a shot's
start_sec lands mid-line (cuts across a word).