Capture, compose and audio
Recording a real interface
capture drives a real page through a scripted sequence and records it — the "video of the
product actually working" that no amount of motion graphics substitutes for.
cleya capture --url https://app.example.com --script steps.json --output demo.mp4
The script is a list of steps: goto, click, type, scroll, hover, with a synthetic
cursor and click ripples drawn in. Useful extras:
state— seed cookies and localStorage so the recording starts logged in. This is what makes SaaS demos possible at all.--hide— hide CSS selectors during the recording; common framework dev overlays (the Next.js badge, Vite and React error overlays) are hidden automatically.- Chapters — steps can emit timestamps you can cut against later.
Assembling scenes
compose renders several scenes and joins them into one film:
cleya compose --scenes film.json --output film.mp4
It handles per-scene rendering, transitions (uniform or per-cut, including hard cuts), an audio bed with fades and ducking, beat-snapped cuts, and per-scene voiceover for narrated films.
Renders are cached per scene, content-hashed — so changing one scene and re-composing takes fractions of a second instead of re-rendering the whole film.
Voiceover
cleya tts --text "Welcome to the show" --voice nova --tone warm --output vo.mp3
tts is the only tool that calls the network — the OpenAI audio API, opt-in, requiring
OPENAI_API_KEY. --instructions and --tone (energetic, warm, calm, serious, excited) steer
delivery, which matters: the default read is flat.
For existing footage, transcribe and autosub run locally through whisper.cpp, and
animated_captions renders karaoke-style captions from word-level timestamps on macOS.