FFmpeg for Video Production

Video and audio processing with FFmpeg.

FFmpeg for Video Production — Super Bowl-style launch ad (from the digitalsamba/claude-code-video-toolkit README)

From the digitalsamba/claude-code-video-toolkit README — shows the whole collection, not only this skill. · view on GitHub

How to use it

Claude Code
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/ffmpeg, including the files SKILL.md points to.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit digitalsamba/claude-code-video-toolkit/.claude/skills/ffmpeg#main ~/.claude/skills/ffmpeg

For one project only, change the path to .claude/skills/ffmpeg. This skill also uses list.txt, export-all-platforms.sh — copying SKILL.md alone won't be enough. See the folder on GitHub.

Claude (web or desktop app)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of FFmpeg for Video Production

Show the full text433 lines
namedescription
ffmpegVideo and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion. Triggers include converting GIF to MP4, resizing video, extracting audio, compressing files, or any media transformation task.

FFmpeg for Video Production

FFmpeg is the essential tool for video/audio processing. This skill covers common operations for Remotion video projects.

Quick Reference

GIF to MP4 (Remotion-compatible)
ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p \
  -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4

Why these flags:

  • -movflags faststart - Moves metadata to start for web streaming
  • -pix_fmt yuv420p - Ensures compatibility with most players
  • scale=trunc(...) - Forces even dimensions (required by most codecs)
Resize Video
# To 1920x1080 (maintain aspect ratio, add black bars)
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4

# To 1920x1080 (crop to fill)
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080" output.mp4

# Scale to width, auto height
ffmpeg -i input.mp4 -vf "scale=1280:-2" output.mp4
Compress Video
# Good quality, smaller file (CRF 23 is default, lower = better quality)
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4

# Aggressive compression for web preview
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 96k output.mp4

# Target file size (e.g., ~10MB for 60s video = ~1.3Mbps)
ffmpeg -i input.mp4 -c:v libx264 -b:v 1300k -c:a aac -b:a 128k output.mp4
Extract Audio
# Extract to MP3
ffmpeg -i input.mp4 -vn -acodec libmp3lame -q:a 2 output.mp3

# Extract to AAC
ffmpeg -i input.mp4 -vn -acodec aac -b:a 192k output.m4a

# Extract to WAV (uncompressed)
ffmpeg -i input.mp4 -vn output.wav
Convert Audio Formats
# M4A to MP3 (for ElevenLabs voice samples)
ffmpeg -i input.m4a -codec:a libmp3lame -qscale:a 2 output.mp3

# WAV to MP3
ffmpeg -i input.wav -codec:a libmp3lame -b:a 192k output.mp3

# Adjust volume
ffmpeg -i input.mp3 -filter:a "volume=1.5" output.mp3
Trim/Cut Video
# Cut from timestamp to duration (recommended - reliable)
ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:15 -c:v libx264 -c:a aac output.mp4

# Cut from timestamp to timestamp
ffmpeg -i input.mp4 -ss 00:00:30 -to 00:00:45 -c:v libx264 -c:a aac output.mp4

# Stream copy (faster but may lose frames at cut points)
# Only use when source has frequent keyframes
ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:15 -c copy output.mp4

Note: Re-encoding is recommended for trimming. Stream copy (-c copy) can silently drop video if the seek point doesn't align with a keyframe.

Speed Up / Slow Down
# 2x speed (video and audio)
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4

# 0.5x speed (slow motion)
ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" -map "[v]" -map "[a]" output.mp4

# Video only (no audio)
ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" -an output.mp4
Concatenate Videos
# Create file list
echo "file 'clip1.mp4'" > list.txt
echo "file 'clip2.mp4'" >> list.txt
echo "file 'clip3.mp4'" >> list.txt

# Concatenate (same codec/resolution)
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

# Concatenate with re-encoding (different sources)
ffmpeg -f concat -safe 0 -i list.txt -c:v libx264 -c:a aac output.mp4
Add Fade In/Out
# Fade in first 1 second, fade out last 1 second (30fps video)
ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" -c:a copy output.mp4

# Audio fade
ffmpeg -i input.mp4 -af "afade=t=in:st=0:d=1,afade=t=out:st=9:d=1" -c:v copy output.mp4
Get Video Info
# Duration, resolution, codec info
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4

# Full info
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4

Remotion-Specific Patterns

Video Speed Adjustment for Remotion

When to use FFmpeg vs Remotion playbackRate:

Scenario Use FFmpeg Use Remotion
Constant speed (1.5x, 2x) Either works ✅ Simpler
Extreme speeds (>4x or <0.25x) ✅ More reliable May have issues
Variable speed (accelerate over time) ✅ Pre-process Complex workaround needed
Need perfect audio sync ✅ Guaranteed Usually fine
Demo needs to fit voiceover timing ✅ Pre-calculate Runtime adjustment

Remotion limitation: playbackRate must be constant. Dynamic interpolation like playbackRate={interpolate(frame, [0, 100], [1, 5])} won't work correctly because Remotion evaluates frames independently.

# Speed up demo to fit a scene (e.g., 60s demo into 20s = 3x speed)
ffmpeg -i demo-raw.mp4 \
  -filter_complex "[0:v]setpts=0.333*PTS[v];[0:a]atempo=3.0[a]" \
  -map "[v]" -map "[a]" \
  public/demos/demo-fast.mp4

# Slow motion for emphasis (0.5x speed)
ffmpeg -i action.mp4 \
  -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" \
  -map "[v]" -map "[a]" \
  public/demos/action-slow.mp4

# Speed up without audio (common for screen recordings)
ffmpeg -i demo.mp4 -filter:v "setpts=0.5*PTS" -an public/demos/demo-2x.mp4

# Timelapse effect (10x speed, drop audio)
ffmpeg -i long-demo.mp4 -filter:v "setpts=0.1*PTS" -an public/demos/timelapse.mp4

Calculate speed factor:

  • To fit X seconds of video into Y seconds of scene: speed = X / Y
  • setpts multiplier = 1 / speed (e.g., 3x speed = setpts=0.333*PTS)
  • atempo value = speed (e.g., 3x speed = atempo=3.0)

Extreme speed (>2x audio): Chain atempo filters (each limited to 0.5-2.0 range):

# 4x speed audio
-filter_complex "[0:a]atempo=2.0,atempo=2.0[a]"

# 8x speed audio
-filter_complex "[0:a]atempo=2.0,atempo=2.0,atempo=2.0[a]"
Prepare Demo Recording for Remotion
# Standard 1080p, 30fps, Remotion-ready
ffmpeg -i raw-recording.mp4 \
  -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,fps=30" \
  -c:v libx264 -crf 18 -preset slow \
  -c:a aac -b:a 192k \
  -movflags faststart \
  public/demos/demo.mp4
Screen Recording to Remotion Asset
# From iPhone/iPad recording (usually 60fps, variable resolution)
ffmpeg -i iphone-recording.mov \
  -vf "scale=1920:-2,fps=30" \
  -c:v libx264 -crf 20 \
  -an \
  public/demos/mobile-demo.mp4
Batch Convert GIFs
for f in assets/*.gif; do
  ffmpeg -i "$f" -movflags faststart -pix_fmt yuv420p \
    -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
    "public/demos/$(basename "$f" .gif).mp4"
done

Common Issues

"Height not divisible by 2"

Add scale filter: -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"

Video won't play in browser

Use: -movflags faststart -pix_fmt yuv420p -c:v libx264

Audio out of sync after speed change

Use filter_complex with atempo: -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]"

File too large

Increase CRF (23→28) or reduce resolution

Quality Guidelines

Use Case CRF Preset Notes
Archive/Master 18 slow Best quality, large files
Production 20-22 medium Good balance
Web/Preview 23-25 fast Smaller files
Draft/Quick 28+ veryfast Fast encoding

Platform-Specific Output Optimization

After Remotion renders your video (typically to out/video.mp4), use FFmpeg to optimize for each distribution platform.

Workflow Integration
Remotion render (master)     FFmpeg optimization      Platform upload
       ↓                            ↓                       ↓
   out/video.mp4  ────────→  out/video-youtube.mp4  ───→  YouTube
                  ────────→  out/video-twitter.mp4  ───→  Twitter/X
                  ────────→  out/video-linkedin.mp4 ───→  LinkedIn
                  ────────→  out/video-web.mp4      ───→  Website embed

YouTube re-encodes everything, so upload high quality:

# YouTube optimized (1080p)
ffmpeg -i out/video.mp4 \
  -c:v libx264 -preset slow -crf 18 \
  -profile:v high -level 4.0 \
  -bf 2 -g 30 \
  -c:a aac -b:a 192k -ar 48000 \
  -movflags +faststart \
  out/video-youtube.mp4

# YouTube Shorts (vertical 1080x1920)
ffmpeg -i out/video.mp4 \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" \
  -c:v libx264 -crf 18 -c:a aac -b:a 192k \
  out/video-shorts.mp4
Twitter/X

Twitter has strict limits: max 140s, 512MB, 1920x1200:

# Twitter optimized (under 15MB target for fast upload)
ffmpeg -i out/video.mp4 \
  -c:v libx264 -preset medium -crf 24 \
  -profile:v main -level 3.1 \
  -vf "scale='min(1280,iw)':'min(720,ih)':force_original_aspect_ratio=decrease" \
  -c:a aac -b:a 128k -ar 44100 \
  -movflags +faststart \
  -fs 15M \
  out/video-twitter.mp4

# Check file size and duration
ffprobe -v error -show_entries format=duration,size -of csv=p=0 out/video-twitter.mp4
LinkedIn

LinkedIn prefers MP4 with AAC audio, max 10 minutes:

# LinkedIn optimized
ffmpeg -i out/video.mp4 \
  -c:v libx264 -preset medium -crf 22 \
  -profile:v main \
  -vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" \
  -c:a aac -b:a 192k -ar 48000 \
  -movflags +faststart \
  out/video-linkedin.mp4
Website/Embed (Optimized for Fast Loading)
# Web-optimized MP4 (small file, progressive loading)
ffmpeg -i out/video.mp4 \
  -c:v libx264 -preset medium -crf 26 \
  -profile:v baseline -level 3.0 \
  -vf "scale=1280:720" \
  -c:a aac -b:a 128k \
  -movflags +faststart \
  out/video-web.mp4

# WebM alternative (better compression, wider browser support)
ffmpeg -i out/video.mp4 \
  -c:v libvpx-vp9 -crf 30 -b:v 0 \
  -vf "scale=1280:720" \
  -c:a libopus -b:a 128k \
  -deadline good \
  out/video-web.webm
GIF (for Previews/Thumbnails)
# High-quality GIF (first 5 seconds)
ffmpeg -i out/video.mp4 -t 5 \
  -vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
  out/preview.gif

# Smaller file GIF
ffmpeg -i out/video.mp4 -t 3 \
  -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
  out/preview-small.gif
Platform Requirements Quick Reference
Platform Max Resolution Max Size Max Duration Audio
YouTube 8K 256GB 12 hours AAC 48kHz
Twitter/X 1920x1200 512MB 140s AAC 44.1kHz
LinkedIn 4096x2304 5GB 10 min AAC 48kHz
Instagram Feed 1080x1350 4GB 60s AAC 48kHz
Instagram Reels 1080x1920 4GB 90s AAC 48kHz
TikTok 1080x1920 287MB 10 min AAC
Batch Export for All Platforms
#!/bin/bash
# save as: export-all-platforms.sh
INPUT="out/video.mp4"

# YouTube (high quality)
ffmpeg -i "$INPUT" -c:v libx264 -preset slow -crf 18 \
  -c:a aac -b:a 192k -movflags +faststart \
  out/video-youtube.mp4

# Twitter (compressed)
ffmpeg -i "$INPUT" -c:v libx264 -crf 24 \
  -vf "scale='min(1280,iw)':'-2'" \
  -c:a aac -b:a 128k -movflags +faststart \
  out/video-twitter.mp4

# LinkedIn
ffmpeg -i "$INPUT" -c:v libx264 -crf 22 \
  -c:a aac -b:a 192k -movflags +faststart \
  out/video-linkedin.mp4

# Web embed (small)
ffmpeg -i "$INPUT" -c:v libx264 -crf 26 \
  -vf "scale=1280:720" \
  -c:a aac -b:a 128k -movflags +faststart \
  out/video-web.mp4

echo "Exported:"
ls -lh out/video-*.mp4

Error Handling

Common errors and fixes when processing video:

# Check if FFmpeg succeeded
ffmpeg -i input.mp4 -c:v libx264 output.mp4 && echo "Success" || echo "Failed: check input file"

# Validate output file is playable
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 output.mp4

# Get detailed error info
ffmpeg -v error -i input.mp4 -f null - 2>&1 | head -20
Handling Common Failures
Error Cause Fix
"No such file" Input path wrong Check path, use quotes for spaces
"Invalid data" Corrupted input Re-download or re-record source
"height not divisible by 2" Odd dimensions Add scale filter with trunc
"encoder not found" Missing codec Install FFmpeg with full codecs
Output 0 bytes Silent failure Check full ffmpeg output for errors

Feedback & Contributions

If this skill is missing information or could be improved:

  • Missing a command? Describe what you needed
  • Found an error? Let me know what's wrong
  • Want to contribute? I can help you:
    1. Update this skill with improvements
    2. Create a PR to github.com/digitalsamba/claude-code-video-toolkit

Just say "improve this skill" and I'll guide you through updating .claude/skills/ffmpeg/SKILL.md.

1---
2name: ffmpeg
3description: Video and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion. Triggers include converting GIF to MP4, resizing video, extracting audio, compressing files, or any media transformation task.
4---
5 
6# FFmpeg for Video Production
7 
8FFmpeg is the essential tool for video/audio processing. This skill covers common operations for Remotion video projects.
9 
10## Quick Reference
11 
12### GIF to MP4 (Remotion-compatible)
13 
14```bash
15ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p \
16 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4
17```
18 
19**Why these flags:**
20- `-movflags faststart` - Moves metadata to start for web streaming
21- `-pix_fmt yuv420p` - Ensures compatibility with most players
22- `scale=trunc(...)` - Forces even dimensions (required by most codecs)
23 
24### Resize Video
25 
26```bash
27# To 1920x1080 (maintain aspect ratio, add black bars)
28ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4
29 
30# To 1920x1080 (crop to fill)
31ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=increase,crop=1920:1080" output.mp4
32 
33# Scale to width, auto height
34ffmpeg -i input.mp4 -vf "scale=1280:-2" output.mp4
35```
36 
37### Compress Video
38 
39```bash
40# Good quality, smaller file (CRF 23 is default, lower = better quality)
41ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k output.mp4
42 
43# Aggressive compression for web preview
44ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 96k output.mp4
45 
46# Target file size (e.g., ~10MB for 60s video = ~1.3Mbps)
47ffmpeg -i input.mp4 -c:v libx264 -b:v 1300k -c:a aac -b:a 128k output.mp4
48```
49 
50### Extract Audio
51 
52```bash
53# Extract to MP3
54ffmpeg -i input.mp4 -vn -acodec libmp3lame -q:a 2 output.mp3
55 
56# Extract to AAC
57ffmpeg -i input.mp4 -vn -acodec aac -b:a 192k output.m4a
58 
59# Extract to WAV (uncompressed)
60ffmpeg -i input.mp4 -vn output.wav
61```
62 
63### Convert Audio Formats
64 
65```bash
66# M4A to MP3 (for ElevenLabs voice samples)
67ffmpeg -i input.m4a -codec:a libmp3lame -qscale:a 2 output.mp3
68 
69# WAV to MP3
70ffmpeg -i input.wav -codec:a libmp3lame -b:a 192k output.mp3
71 
72# Adjust volume
73ffmpeg -i input.mp3 -filter:a "volume=1.5" output.mp3
74```
75 
76### Trim/Cut Video
77 
78```bash
79# Cut from timestamp to duration (recommended - reliable)
80ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:15 -c:v libx264 -c:a aac output.mp4
81 
82# Cut from timestamp to timestamp
83ffmpeg -i input.mp4 -ss 00:00:30 -to 00:00:45 -c:v libx264 -c:a aac output.mp4
84 
85# Stream copy (faster but may lose frames at cut points)
86# Only use when source has frequent keyframes
87ffmpeg -i input.mp4 -ss 00:00:30 -t 00:00:15 -c copy output.mp4
88```
89 
90**Note:** Re-encoding is recommended for trimming. Stream copy (`-c copy`) can silently drop video if the seek point doesn't align with a keyframe.
91 
92### Speed Up / Slow Down
93 
94```bash
95# 2x speed (video and audio)
96ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4
97 
98# 0.5x speed (slow motion)
99ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" -map "[v]" -map "[a]" output.mp4
100 
101# Video only (no audio)
102ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" -an output.mp4
103```
104 
105### Concatenate Videos
106 
107```bash
108# Create file list
109echo "file 'clip1.mp4'" > list.txt
110echo "file 'clip2.mp4'" >> list.txt
111echo "file 'clip3.mp4'" >> list.txt
112 
113# Concatenate (same codec/resolution)
114ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4
115 
116# Concatenate with re-encoding (different sources)
117ffmpeg -f concat -safe 0 -i list.txt -c:v libx264 -c:a aac output.mp4
118```
119 
120### Add Fade In/Out
121 
122```bash
123# Fade in first 1 second, fade out last 1 second (30fps video)
124ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" -c:a copy output.mp4
125 
126# Audio fade
127ffmpeg -i input.mp4 -af "afade=t=in:st=0:d=1,afade=t=out:st=9:d=1" -c:v copy output.mp4
128```
129 
130### Get Video Info
131 
132```bash
133# Duration, resolution, codec info
134ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
135 
136# Full info
137ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
138```
139 
140## Remotion-Specific Patterns
141 
142### Video Speed Adjustment for Remotion
143 
144**When to use FFmpeg vs Remotion `playbackRate`:**
145 
146| Scenario | Use FFmpeg | Use Remotion |
147|----------|------------|--------------|
148| Constant speed (1.5x, 2x) | Either works | ✅ Simpler |
149| Extreme speeds (>4x or <0.25x) | ✅ More reliable | May have issues |
150| Variable speed (accelerate over time) | ✅ Pre-process | Complex workaround needed |
151| Need perfect audio sync | ✅ Guaranteed | Usually fine |
152| Demo needs to fit voiceover timing | ✅ Pre-calculate | Runtime adjustment |
153 
154**Remotion limitation:** `playbackRate` must be constant. Dynamic interpolation like `playbackRate={interpolate(frame, [0, 100], [1, 5])}` won't work correctly because Remotion evaluates frames independently.
155 
156```bash
157# Speed up demo to fit a scene (e.g., 60s demo into 20s = 3x speed)
158ffmpeg -i demo-raw.mp4 \
159 -filter_complex "[0:v]setpts=0.333*PTS[v];[0:a]atempo=3.0[a]" \
160 -map "[v]" -map "[a]" \
161 public/demos/demo-fast.mp4
162 
163# Slow motion for emphasis (0.5x speed)
164ffmpeg -i action.mp4 \
165 -filter_complex "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]" \
166 -map "[v]" -map "[a]" \
167 public/demos/action-slow.mp4
168 
169# Speed up without audio (common for screen recordings)
170ffmpeg -i demo.mp4 -filter:v "setpts=0.5*PTS" -an public/demos/demo-2x.mp4
171 
172# Timelapse effect (10x speed, drop audio)
173ffmpeg -i long-demo.mp4 -filter:v "setpts=0.1*PTS" -an public/demos/timelapse.mp4
174```
175 
176**Calculate speed factor:**
177- To fit X seconds of video into Y seconds of scene: `speed = X / Y`
178- setpts multiplier = `1 / speed` (e.g., 3x speed = setpts=0.333*PTS)
179- atempo value = `speed` (e.g., 3x speed = atempo=3.0)
180 
181**Extreme speed (>2x audio):** Chain atempo filters (each limited to 0.5-2.0 range):
182```bash
183# 4x speed audio
184-filter_complex "[0:a]atempo=2.0,atempo=2.0[a]"
185 
186# 8x speed audio
187-filter_complex "[0:a]atempo=2.0,atempo=2.0,atempo=2.0[a]"
188```
189 
190### Prepare Demo Recording for Remotion
191 
192```bash
193# Standard 1080p, 30fps, Remotion-ready
194ffmpeg -i raw-recording.mp4 \
195 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,fps=30" \
196 -c:v libx264 -crf 18 -preset slow \
197 -c:a aac -b:a 192k \
198 -movflags faststart \
199 public/demos/demo.mp4
200```
201 
202### Screen Recording to Remotion Asset
203 
204```bash
205# From iPhone/iPad recording (usually 60fps, variable resolution)
206ffmpeg -i iphone-recording.mov \
207 -vf "scale=1920:-2,fps=30" \
208 -c:v libx264 -crf 20 \
209 -an \
210 public/demos/mobile-demo.mp4
211```
212 
213### Batch Convert GIFs
214 
215```bash
216for f in assets/*.gif; do
217 ffmpeg -i "$f" -movflags faststart -pix_fmt yuv420p \
218 -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
219 "public/demos/$(basename "$f" .gif).mp4"
220done
221```
222 
223## Common Issues
224 
225### "Height not divisible by 2"
226Add scale filter: `-vf "scale=trunc(iw/2)*2:trunc(ih/2)*2"`
227 
228### Video won't play in browser
229Use: `-movflags faststart -pix_fmt yuv420p -c:v libx264`
230 
231### Audio out of sync after speed change
232Use filter_complex with atempo: `-filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]"`
233 
234### File too large
235Increase CRF (23→28) or reduce resolution
236 
237## Quality Guidelines
238 
239| Use Case | CRF | Preset | Notes |
240|----------|-----|--------|-------|
241| Archive/Master | 18 | slow | Best quality, large files |
242| Production | 20-22 | medium | Good balance |
243| Web/Preview | 23-25 | fast | Smaller files |
244| Draft/Quick | 28+ | veryfast | Fast encoding |
245 
246## Platform-Specific Output Optimization
247 
248After Remotion renders your video (typically to `out/video.mp4`), use FFmpeg to optimize for each distribution platform.
249 
250### Workflow Integration
251 
252```
253Remotion render (master) FFmpeg optimization Platform upload
254 ↓ ↓ ↓
255 out/video.mp4 ────────→ out/video-youtube.mp4 ───→ YouTube
256 ────────→ out/video-twitter.mp4 ───→ Twitter/X
257 ────────→ out/video-linkedin.mp4 ───→ LinkedIn
258 ────────→ out/video-web.mp4 ───→ Website embed
259```
260 
261### YouTube (Recommended Settings)
262 
263YouTube re-encodes everything, so upload high quality:
264 
265```bash
266# YouTube optimized (1080p)
267ffmpeg -i out/video.mp4 \
268 -c:v libx264 -preset slow -crf 18 \
269 -profile:v high -level 4.0 \
270 -bf 2 -g 30 \
271 -c:a aac -b:a 192k -ar 48000 \
272 -movflags +faststart \
273 out/video-youtube.mp4
274 
275# YouTube Shorts (vertical 1080x1920)
276ffmpeg -i out/video.mp4 \
277 -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" \
278 -c:v libx264 -crf 18 -c:a aac -b:a 192k \
279 out/video-shorts.mp4
280```
281 
282### Twitter/X
283 
284Twitter has strict limits: max 140s, 512MB, 1920x1200:
285 
286```bash
287# Twitter optimized (under 15MB target for fast upload)
288ffmpeg -i out/video.mp4 \
289 -c:v libx264 -preset medium -crf 24 \
290 -profile:v main -level 3.1 \
291 -vf "scale='min(1280,iw)':'min(720,ih)':force_original_aspect_ratio=decrease" \
292 -c:a aac -b:a 128k -ar 44100 \
293 -movflags +faststart \
294 -fs 15M \
295 out/video-twitter.mp4
296 
297# Check file size and duration
298ffprobe -v error -show_entries format=duration,size -of csv=p=0 out/video-twitter.mp4
299```
300 
301### LinkedIn
302 
303LinkedIn prefers MP4 with AAC audio, max 10 minutes:
304 
305```bash
306# LinkedIn optimized
307ffmpeg -i out/video.mp4 \
308 -c:v libx264 -preset medium -crf 22 \
309 -profile:v main \
310 -vf "scale='min(1920,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease" \
311 -c:a aac -b:a 192k -ar 48000 \
312 -movflags +faststart \
313 out/video-linkedin.mp4
314```
315 
316### Website/Embed (Optimized for Fast Loading)
317 
318```bash
319# Web-optimized MP4 (small file, progressive loading)
320ffmpeg -i out/video.mp4 \
321 -c:v libx264 -preset medium -crf 26 \
322 -profile:v baseline -level 3.0 \
323 -vf "scale=1280:720" \
324 -c:a aac -b:a 128k \
325 -movflags +faststart \
326 out/video-web.mp4
327 
328# WebM alternative (better compression, wider browser support)
329ffmpeg -i out/video.mp4 \
330 -c:v libvpx-vp9 -crf 30 -b:v 0 \
331 -vf "scale=1280:720" \
332 -c:a libopus -b:a 128k \
333 -deadline good \
334 out/video-web.webm
335```
336 
337### GIF (for Previews/Thumbnails)
338 
339```bash
340# High-quality GIF (first 5 seconds)
341ffmpeg -i out/video.mp4 -t 5 \
342 -vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
343 out/preview.gif
344 
345# Smaller file GIF
346ffmpeg -i out/video.mp4 -t 3 \
347 -vf "fps=10,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
348 out/preview-small.gif
349```
350 
351### Platform Requirements Quick Reference
352 
353| Platform | Max Resolution | Max Size | Max Duration | Audio |
354|----------|---------------|----------|--------------|-------|
355| YouTube | 8K | 256GB | 12 hours | AAC 48kHz |
356| Twitter/X | 1920x1200 | 512MB | 140s | AAC 44.1kHz |
357| LinkedIn | 4096x2304 | 5GB | 10 min | AAC 48kHz |
358| Instagram Feed | 1080x1350 | 4GB | 60s | AAC 48kHz |
359| Instagram Reels | 1080x1920 | 4GB | 90s | AAC 48kHz |
360| TikTok | 1080x1920 | 287MB | 10 min | AAC |
361 
362### Batch Export for All Platforms
363 
364```bash
365#!/bin/bash
366# save as: export-all-platforms.sh
367INPUT="out/video.mp4"
368 
369# YouTube (high quality)
370ffmpeg -i "$INPUT" -c:v libx264 -preset slow -crf 18 \
371 -c:a aac -b:a 192k -movflags +faststart \
372 out/video-youtube.mp4
373 
374# Twitter (compressed)
375ffmpeg -i "$INPUT" -c:v libx264 -crf 24 \
376 -vf "scale='min(1280,iw)':'-2'" \
377 -c:a aac -b:a 128k -movflags +faststart \
378 out/video-twitter.mp4
379 
380# LinkedIn
381ffmpeg -i "$INPUT" -c:v libx264 -crf 22 \
382 -c:a aac -b:a 192k -movflags +faststart \
383 out/video-linkedin.mp4
384 
385# Web embed (small)
386ffmpeg -i "$INPUT" -c:v libx264 -crf 26 \
387 -vf "scale=1280:720" \
388 -c:a aac -b:a 128k -movflags +faststart \
389 out/video-web.mp4
390 
391echo "Exported:"
392ls -lh out/video-*.mp4
393```
394 
395## Error Handling
396 
397Common errors and fixes when processing video:
398 
399```bash
400# Check if FFmpeg succeeded
401ffmpeg -i input.mp4 -c:v libx264 output.mp4 && echo "Success" || echo "Failed: check input file"
402 
403# Validate output file is playable
404ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of csv=p=0 output.mp4
405 
406# Get detailed error info
407ffmpeg -v error -i input.mp4 -f null - 2>&1 | head -20
408```
409 
410### Handling Common Failures
411 
412| Error | Cause | Fix |
413|-------|-------|-----|
414| "No such file" | Input path wrong | Check path, use quotes for spaces |
415| "Invalid data" | Corrupted input | Re-download or re-record source |
416| "height not divisible by 2" | Odd dimensions | Add scale filter with trunc |
417| "encoder not found" | Missing codec | Install FFmpeg with full codecs |
418| Output 0 bytes | Silent failure | Check full ffmpeg output for errors |
419 
420---
421 
422## Feedback & Contributions
423 
424If this skill is missing information or could be improved:
425 
426- **Missing a command?** Describe what you needed
427- **Found an error?** Let me know what's wrong
428- **Want to contribute?** I can help you:
429 1. Update this skill with improvements
430 2. Create a PR to github.com/digitalsamba/claude-code-video-toolkit
431 
432Just say "improve this skill" and I'll guide you through updating `.claude/skills/ffmpeg/SKILL.md`.
433 

Discussion

Alternatives

Also in Video productionSee all 320 in Content creator →