Skip to content

build

Assemble a reel from a storyboard: render each card to a frame, crossfade them into a 1080×1920 H.264 video, and (unless --silent) mix the narration over the music bed. Rendering shells out to ffmpeg behind the Renderer interface.

Usage

# Workspace build (the authoring loop): --workspace is a slug under the reel root
keryx reel build --workspace my-post

# Render without audio (cards use their storyboard `dur`)
keryx reel build --workspace my-post --silent

# Standalone build from a loose storyboard file
keryx reel build --storyboard board.json --out promo.mp4

Flags

Flag Description
--workspace Reel workspace slug under the reel root (reels/<slug>), the same slug used by reel new and storyboard draft. The storyboard, VO takes, music bed, and cover are read from that workspace.
--storyboard A standalone storyboard.json path, used as-is. Overrides the workspace board when both are given.
--theme Reel theme keyword (palette, fonts, music gain). Defaults to the configured reel default.
--out Output .mp4 path. Defaults to reels/<slug>/reel-<slug>.mp4 for a workspace build, or reel.mp4 for a standalone build.
--cover Cover image path. Defaults to reels/<slug>/cover.png if present.
--silent Render video only — no narration, no music. Each card must carry a dur.

Timing

  • With VO (a workspace vo/*.mp3 exists, not --silent): each card's on-screen duration is derived from its narration clip length plus lead and tail; cards crossfade. The music bed is mixed in under the VO at the theme's gain with an end fade.
  • Silent / no VO: each card uses its storyboard dur. A card with no dur is an error in this mode.

Progress

On an interactive terminal, reel build shows a live rendering… NN% line while the reel assembles — parsed from ffmpeg's own progress against the reel's total duration (spec 0026). It is written to stderr (so stdout / --output json stays clean) and cleared when the render finishes; piped or non-TTY runs show nothing. The percentage needs a backend that streams progress — the default ffmpeg does; the in-memory afmpeg backend renders without it.

Reproducibility

After rendering, reel build reports how many selected assets are locked (approved) vs merely selected. When every selected asset is locked, the reel is reproducible from committed inputs — see reel lock. The counts are also in the --output json payload (selected, locked).

See the Testing page for the BDD scenario that exercises a silent workspace render end to end.