Skip to main content

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.