Remotion Ads
Create professional video ads and explainer videos with Remotion, ElevenLabs voiceover, and animated captions.
Setup
- Copy
references/brand-config-template.md → references/brand-config.md
- Fill in brand colors, fonts, voice, caption styling, and content rules
- Create pronunciation dictionary from
assets/dictionaries/template.pls
See references/setup.md for dependencies and folder structure.
Supported Formats
| Format |
Aspect |
Resolution |
Duration |
Scenes |
| Instagram Reels |
9:16 |
1080×1920 |
15-60s |
4 (Hook→Problem→Solution→CTA) |
| Instagram Reels (Ohneis) |
9:16 |
1080×1920 |
15-45s |
Beat-driven (word-level) |
| Website Explainers |
16:9 |
1920×1080 |
60-160s |
6 (Hook→Problem→Context→Solution→Process→CTA) |
| Carousels |
4:5 |
1080×1350 |
Static |
5-10 slides |
See references/formats.md for safe zones and crop specs.
See references/ohneis-style.md for beat-driven cinematic reel template.
See references/website-videos.md for 16:9 long-form format.
Workflow
From scratch
# 1. Write scene JSON
# 2. Generate voiceover with word timestamps
node scripts/generate.js \
--scenes scenes.json \
--with-timestamps \
--dictionary your-brand \
--output-dir public/audio/ad-example/
# 3. Create Remotion composition using actualDuration from info.json
# 4. Render
npx remotion render AdExample out/ad-example.mp4 --codec=h264 --crf=18
From a URL (page → video)
# 1. Extract page data into scene JSON
node scripts/url-to-scenes.js --url https://example.com/page --format reels --output scenes.json
# 2. Review/edit the generated scenes.json
# 3. Continue with voiceover + composition as above
See references/url-to-video.md for the full URL-to-video workflow.
Safe Zones (Critical)
Reels (1080×1920)
┌──────────────────────────┐ 0px
│ TOP DANGER (285px) │
├──────────────────────────┤
│ ←80px SAFE AREA 120px→ │
│ 880×1235px │
├──────────────────────────┤
│ BOTTOM DANGER (400px) │
└──────────────────────────┘ 1920px
const SAFE = { top: 285, bottom: 400, left: 80, right: 120 };
Website Videos (1920×1080)
const SAFE = { top: 60, bottom: 60, left: 80, right: 80 };
Scene JSON Format
{
"name": "ad-example",
"voice": "VoiceName",
"character": "narrator",
"dictionary": "your-brand",
"scenes": [
{ "id": "scene1", "text": "Hook text.", "duration": 3.5, "character": "dramatic" },
{ "id": "scene2", "text": "Problem.", "duration": 4.5 },
{ "id": "scene3", "text": "Solution.", "duration": 4.0, "character": "expert" },
{ "id": "scene4", "text": "CTA.", "duration": 3.0, "character": "calm" }
]
}
Voice Character Presets
| Character |
Style |
Stability |
Similarity |
Style Param |
dramatic |
Intense, emotional |
0.3 |
0.8 |
0.7 |
narrator |
Professional, smooth |
0.5 |
0.75 |
0.4 |
expert |
Authoritative |
0.6 |
0.85 |
0.3 |
calm |
Soothing, reassuring |
0.7 |
0.8 |
0.2 |
conversational |
Casual, friendly |
0.45 |
0.7 |
0.5 |
Composition Template
import { AbsoluteFill, Audio, Series, staticFile } from "remotion";
// Import from your brand-config.md values
const COLORS = { primary: "#000", accent: "#888", dark: "#111", background: "#fff" };
export const AdTemplate: React.FC = () => {
const { fps } = useVideoConfig();
// Use actualDuration from info.json, not estimated
const DURATIONS = { scene1: 3.42, scene2: 4.35, scene3: 4.12, scene4: 3.31 };
const pad = 5;
return (
<AbsoluteFill>
<Audio src={staticFile("audio/ad-example/ad-example-combined.mp3")} />
<Series>
<Series.Sequence durationInFrames={Math.round(DURATIONS.scene1 * fps) + pad}>
<Scene1Hook />
</Series.Sequence>
{/* ... remaining scenes */}
</Series>
</AbsoluteFill>
);
};
See references/components.md for reusable scene components.
See references/voiceover.md for TransitionSeries audio sync.
Reference Files
Load these on demand based on the task:
Core (read first)
| File |
When to read |
| setup.md |
Project initialization |
| brand-config-template.md |
Configuring brand: colors, fonts, voice, captions, compliance |
| formats.md |
Dimension specs, safe zones, crop previews |
Video Creation
| File |
When to read |
| ohneis-style.md |
Beat-driven cinematic reel template: mixed-font typography, hard cuts, moody photos |
| voiceover.md |
ElevenLabs TTS, models, scene JSON, timing sync, dictionaries |
| captions.md |
Animated captions: TikTok-style, word-by-word, karaoke |
| animations.md |
Spring configs, transitions, animation components |
| components.md |
Reusable scene template components |
| html-in-canvas.md |
Render live DOM into a canvas with 2D filters or WebGL2 shaders (vintage, progressive blur, page-tour mockup) |
| website-videos.md |
16:9 long-form format, 6-scene structure |
| url-to-video.md |
Create videos from existing web pages |
Audio
| File |
When to read |
| sound-effects.md |
ElevenLabs SFX generation |
| music.md |
Background music via ElevenLabs or Suno |
Assets & Static
| File |
When to read |
| local-assets.md |
Background images, icons, illustrations |
| carousels.md |
4:5 carousel design and batch rendering |
Copywriting
| File |
When to read |
| ad-copywriting.md |
Script frameworks, hook formulas, CTA patterns |
| copy-frameworks.md |
Headline templates, section formulas |
| natural-transitions.md |
Human-sounding transitions, AI-tell avoidance |
Distribution
| File |
When to read |
| paid-ads.md |
Meta campaign strategy, targeting, budgets |
| social-content.md |
Content calendar, repurposing framework |
Scripts
| Script |
Purpose |
scripts/generate.js |
ElevenLabs voiceover with dictionaries, request stitching (note: --with-timestamps flag is currently a no-op) |
scripts/gemini-tts.mjs |
Gemini TTS — single-request generate + silence split with text-proportion boundary picker |
scripts/suno-direct.ts |
Suno background music generation |
scripts/url-to-scenes.js |
Extract page content into scene JSON |
Pre-Upload Checklist
Reels
Website Videos
Carousels
Source: Maartenlouis/remotion-ads — distributed by TomeVault.
1---2name: remotion-ads3description: Professional video ad creation with Remotion — Instagram Reels (9:16), website explainers (16:9), and carousels (4:5). Use when creating video ads, animated social content, or educational explainer videos. Includes ElevenLabs voiceover with word-level captions, AI icon generation, background music, ad copywriting frameworks, and Meta campaign management. Also use when the user provides a URL and wants to create a video for that page. Use when this capability is needed.4---56# Remotion Ads78Create professional video ads and explainer videos with Remotion, ElevenLabs voiceover, and animated captions.910## Setup11121. Copy `references/brand-config-template.md` → `references/brand-config.md`132. Fill in brand colors, fonts, voice, caption styling, and content rules143. Create pronunciation dictionary from `assets/dictionaries/template.pls`1516See [references/setup.md](references/setup.md) for dependencies and folder structure.1718---1920## Supported Formats2122| Format | Aspect | Resolution | Duration | Scenes |23|--------|--------|-----------|----------|--------|24| Instagram Reels | 9:16 | 1080×1920 | 15-60s | 4 (Hook→Problem→Solution→CTA) |25| Instagram Reels (Ohneis) | 9:16 | 1080×1920 | 15-45s | Beat-driven (word-level) |26| Website Explainers | 16:9 | 1920×1080 | 60-160s | 6 (Hook→Problem→Context→Solution→Process→CTA) |27| Carousels | 4:5 | 1080×1350 | Static | 5-10 slides |2829See [references/formats.md](references/formats.md) for safe zones and crop specs.30See [references/ohneis-style.md](references/ohneis-style.md) for beat-driven cinematic reel template.31See [references/website-videos.md](references/website-videos.md) for 16:9 long-form format.3233---3435## Workflow3637### From scratch3839```bash40# 1. Write scene JSON41# 2. Generate voiceover with word timestamps42node scripts/generate.js \43 --scenes scenes.json \44 --with-timestamps \45 --dictionary your-brand \46 --output-dir public/audio/ad-example/4748# 3. Create Remotion composition using actualDuration from info.json49# 4. Render50npx remotion render AdExample out/ad-example.mp4 --codec=h264 --crf=1851```5253### From a URL (page → video)5455```bash56# 1. Extract page data into scene JSON57node scripts/url-to-scenes.js --url https://example.com/page --format reels --output scenes.json58# 2. Review/edit the generated scenes.json59# 3. Continue with voiceover + composition as above60```6162See [references/url-to-video.md](references/url-to-video.md) for the full URL-to-video workflow.6364---6566## Safe Zones (Critical)6768### Reels (1080×1920)6970```71┌──────────────────────────┐ 0px72│ TOP DANGER (285px) │73├──────────────────────────┤74│ ←80px SAFE AREA 120px→ │75│ 880×1235px │76├──────────────────────────┤77│ BOTTOM DANGER (400px) │78└──────────────────────────┘ 1920px79```8081```tsx82const SAFE = { top: 285, bottom: 400, left: 80, right: 120 };83```8485### Website Videos (1920×1080)8687```tsx88const SAFE = { top: 60, bottom: 60, left: 80, right: 80 };89```9091---9293## Scene JSON Format9495```json96{97 "name": "ad-example",98 "voice": "VoiceName",99 "character": "narrator",100 "dictionary": "your-brand",101 "scenes": [102 { "id": "scene1", "text": "Hook text.", "duration": 3.5, "character": "dramatic" },103 { "id": "scene2", "text": "Problem.", "duration": 4.5 },104 { "id": "scene3", "text": "Solution.", "duration": 4.0, "character": "expert" },105 { "id": "scene4", "text": "CTA.", "duration": 3.0, "character": "calm" }106 ]107}108```109110### Voice Character Presets111112| Character | Style | Stability | Similarity | Style Param |113|-----------|-------|-----------|------------|-------------|114| `dramatic` | Intense, emotional | 0.3 | 0.8 | 0.7 |115| `narrator` | Professional, smooth | 0.5 | 0.75 | 0.4 |116| `expert` | Authoritative | 0.6 | 0.85 | 0.3 |117| `calm` | Soothing, reassuring | 0.7 | 0.8 | 0.2 |118| `conversational` | Casual, friendly | 0.45 | 0.7 | 0.5 |119120---121122## Composition Template123124```tsx125import { AbsoluteFill, Audio, Series, staticFile } from "remotion";126127// Import from your brand-config.md values128const COLORS = { primary: "#000", accent: "#888", dark: "#111", background: "#fff" };129130export const AdTemplate: React.FC = () => {131 const { fps } = useVideoConfig();132 // Use actualDuration from info.json, not estimated133 const DURATIONS = { scene1: 3.42, scene2: 4.35, scene3: 4.12, scene4: 3.31 };134 const pad = 5;135136 return (137 <AbsoluteFill>138 <Audio src={staticFile("audio/ad-example/ad-example-combined.mp3")} />139 <Series>140 <Series.Sequence durationInFrames={Math.round(DURATIONS.scene1 * fps) + pad}>141 <Scene1Hook />142 </Series.Sequence>143 {/* ... remaining scenes */}144 </Series>145 </AbsoluteFill>146 );147};148```149150See [references/components.md](references/components.md) for reusable scene components.151See [references/voiceover.md](references/voiceover.md) for TransitionSeries audio sync.152153---154155## Reference Files156157Load these on demand based on the task:158159### Core (read first)160161| File | When to read |162|------|-------------|163| [setup.md](references/setup.md) | Project initialization |164| [brand-config-template.md](references/brand-config-template.md) | Configuring brand: colors, fonts, voice, captions, compliance |165| [formats.md](references/formats.md) | Dimension specs, safe zones, crop previews |166167### Video Creation168169| File | When to read |170|------|-------------|171| [ohneis-style.md](references/ohneis-style.md) | Beat-driven cinematic reel template: mixed-font typography, hard cuts, moody photos |172| [voiceover.md](references/voiceover.md) | ElevenLabs TTS, models, scene JSON, timing sync, dictionaries |173| [captions.md](references/captions.md) | Animated captions: TikTok-style, word-by-word, karaoke |174| [animations.md](references/animations.md) | Spring configs, transitions, animation components |175| [components.md](references/components.md) | Reusable scene template components |176| [html-in-canvas.md](references/html-in-canvas.md) | Render live DOM into a canvas with 2D filters or WebGL2 shaders (vintage, progressive blur, page-tour mockup) |177| [website-videos.md](references/website-videos.md) | 16:9 long-form format, 6-scene structure |178| [url-to-video.md](references/url-to-video.md) | Create videos from existing web pages |179180### Audio181182| File | When to read |183|------|-------------|184| [sound-effects.md](references/sound-effects.md) | ElevenLabs SFX generation |185| [music.md](references/music.md) | Background music via ElevenLabs or Suno |186187### Assets & Static188189| File | When to read |190|------|-------------|191| [local-assets.md](references/local-assets.md) | Background images, icons, illustrations |192| [carousels.md](references/carousels.md) | 4:5 carousel design and batch rendering |193194### Copywriting195196| File | When to read |197|------|-------------|198| [ad-copywriting.md](references/ad-copywriting.md) | Script frameworks, hook formulas, CTA patterns |199| [copy-frameworks.md](references/copy-frameworks.md) | Headline templates, section formulas |200| [natural-transitions.md](references/natural-transitions.md) | Human-sounding transitions, AI-tell avoidance |201202### Distribution203204| File | When to read |205|------|-------------|206| [paid-ads.md](references/paid-ads.md) | Meta campaign strategy, targeting, budgets |207| [social-content.md](references/social-content.md) | Content calendar, repurposing framework |208209---210211## Scripts212213| Script | Purpose |214|--------|---------|215| `scripts/generate.js` | ElevenLabs voiceover with dictionaries, request stitching (note: `--with-timestamps` flag is currently a no-op) |216| `scripts/gemini-tts.mjs` | Gemini TTS — single-request generate + silence split with text-proportion boundary picker |217| `scripts/suno-direct.ts` | Suno background music generation |218| `scripts/url-to-scenes.js` | Extract page content into scene JSON |219220---221222## Pre-Upload Checklist223224### Reels225- [ ] 1080×1920, H.264, 30fps226- [ ] All text within safe zones227- [ ] No content in top 285px or bottom 400px228- [ ] Font sizes ≥ 48px229- [ ] Voiceover synced, captions timed230- [ ] ~15s total duration231232### Website Videos233- [ ] 1920×1080, H.264, 30fps234- [ ] Font sizes ≥ 36px235- [ ] 60-160s duration236- [ ] 6-scene structure with appropriate voice characters237238### Carousels239- [ ] 1080×1350, PNG240- [ ] 80px padding from edges241- [ ] 5-10 slides with swipe indicators242243---244> Source: [Maartenlouis/remotion-ads](https://github.com/Maartenlouis/remotion-ads) — distributed by [TomeVault](https://tomevault.io).245<!-- tomevault:4.0:skill_md:2026-06-17 -->