Remotion narration
Writes everything a Remotion composition needs to be driven by its voiceover: audio per scene, exact durations, start frames and captions. Scene lengths come from the real audio, so nothing drifts.
When to use
- The user has a script (Markdown, text or JSON) and a Remotion project and wants narration.
- Scenes should last exactly as long as their voiceover; captions should follow the voice word by word.
Steps
-
Make sure
MIRAGEA_API_KEYis set (never print it). Pick the voice:--voice VOICE_ID- a voice saved in the user's Miragea account, or--ref-url https://...- a public clip of the voice to clone (with the user's consent), plus--ref-text "exact words in the clip"for the cheaper 1x rate.
-
Write the script. Each
## Heading(or blank-line paragraph) becomes one scene:## intro Meet Retake, the fastest way to fix a voiceover mistake. ## demo Type the right word. Retake re-voices the sentence and splices it in. -
Generate into the Remotion
public/folder:python3 scripts/narrate.py script.md --voice VOICE_ID --out public/narration --fps 30 -
Use
public/narration/narration.jsonin the composition (seeexamples/Narrated.tsx):totalFramesfordurationInFrames, each scene'sstartFrame/durationInFramesfor a<Sequence>,staticFile('narration/' + scene.file)for<Audio>, andscene.captions(RemotionCaption[]:text,startMs,endMs,timestampMs,confidence) with@remotion/captionscreateTikTokStyleCaptions()for animated captions. -
Edit the script and re-run freely: unchanged scenes are reused from the manifest at no cost; if a run stops midway, finished scenes are kept and the next run resumes.
Options
| Flag | Default | Meaning |
|---|---|---|
--fps | 30 | Frame rate for frame maths |
--pad | 0.4 | Seconds of breathing room after each scene |
--captions miragea | yes | Times captions from the generated audio (accurate; +3 points/s) |
--captions estimate | Free: spreads words by length | |
--model | expressive | standard follows the reference voice more closely |
--speed | 1.0 | 0.25-4 |
Scenes longer than 2,000 characters are split at sentence ends and joined automatically.
Troubleshooting
choose a voice-> pass--voiceor--ref-url. Reference URLs must be public, under 1,024 chars and served directly (GitHub raw, S3/R2 public objects work; signed redirects may not).401/402/429-> key, balance, rate limit. Re-running is always safe.