New: Earn 20% as an AgentAlley affiliate. Share your link and earn on every sale you refer. Join now New: Earn 20% as an affiliate. Join now

Video and audio processing with FFmpeg

FFmpeg for Video Production

by digitalsamba · MIT license · ★ 2,114 on GitHub · updated Sep 21

FFmpeg for Video Production cover

Video and audio processing with FFmpeg. Use for format conversion, resizing, compression, audio extraction, and preparing assets for Remotion.

---
name: ffmpeg
description: 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.
---

# 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)

```bash
ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p \
  -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4
```

Overview

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

Manual install (npx, ZIP)
Claude Codenpx skills add digitalsamba/claude-code-video-toolkit --skill ffmpeg -g -a claude-code
Claude Code (manual)mkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/digitalsamba/claude-code-video-toolkit/tar.gz/225c80a1c3a5 \ | tar -xz -C ~/.claude/skills --strip-components=3 claude-code-video-toolkit-225c80a1c3a5/.claude/skills/ffmpeg
Windows (PowerShell)New-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/ec3ae6c530c6ff623a59/ffmpeg.zip" -OutFile "$env:TEMP\ffmpeg.zip"; Expand-Archive "$env:TEMP\ffmpeg.zip" -DestinationPath "$HOME\.claude\skills" -Force
Claude.ai / desktopDownload the ZIP and upload it under Settings → Capabilities → Skills.
Codex, Cursor, other agentsPoint them at SKILL.md. The other files are plain text.

Connects with Agent Alley MCP · agentalley.io/mcp

Files included

  • SKILL.md12.9 KB
  • reference.md4.6 KB
Read the files here
digitalsamba/225c80a2 files
SKILL.md
Show the full text433 lines

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 
View all files on GitHub →

Details

Updated
Sep 21, 2026
License
MIT
Stars on the repo
★ 2,114
Checked
Source
digitalsamba/claude-code-video-toolkit ↗
Creator
digitalsamba · 11 listings
View creator

Similar skills

See all →
SkillMake a polished video of an app or a featureMake a demo video with OpenScreengetopenscreen/openscreen · by getopenscreenMake a polished video of an app or a feature with OpenScreen's MCP tools, from storyboard to recording, editing and export, then either attach it to a pull request or draft a post on X. Use when the user asks for a demo, a demo video, a screen recording, a product video, a launch clip, a video for X/Twitter, LinkedIn or a README, or to show a change in a pull request ("add a video to the PR", "show the feature to reviewers"). Also use to set OpenScreen up for an agent, and to continue an OpenScreen demo in a new session.★ 4.5k GitHub starsSkillTurn static SCREENSHOTS into a simulated screen recordingfake-screencast — screenshots → simulated screen recordinghassancs91/claude-youtube-editor · by hassancs91Turn static SCREENSHOTS into a simulated screen recording (TSX) — a fake screencast with an animated cursor that eases to targets and clicks, a browser URL bar that updates per page, hard-cut navigations, in-page filter crossfades, smooth scroll, and a ken-burns zoom onto the payoff. Use when a beat needs to show a walkthrough of a web app / dashboard / settings page and you'd rather build it from screenshots than get (or ask for) a real screen recording — "fake a screen recording", "turn these screenshots into a screencast", "simulate clicking through the dashboard", "animate this UI walkthrough", "cursor moving through the app". Built on remotion/src/lib/screencast.tsx. This is a technique WITHIN step 2 (make-tsx): defer timeline/render/bake orchestration to make-tsx and raw crash-free TSX rules to vidtsx-2d-generator. Not for a single static page clone (use WebBrowserFrame directly) and not when the point is genuine proof of real speed/output (use a real recording).★ 330 GitHub starsSkillA Khan Academy style explainer videoKhan explainerhaiderfarooq3/khan-explainer · by haiderfarooq3Use when the user wants a Khan Academy style explainer video, a blackboard or whiteboard lesson, a hand-drawn chalk-talk animation, a short narrated video that teaches a concept ("explain X in a video", "explainer video", "teach X in 30 seconds"), or a tutorial that draws hand-written arrows, circles and captions over product screenshots ("draw over the UI", "annotated walkthrough"), or clips cut from a YouTube video or podcast where the speaker's real audio plays under a blackboard drawn to it ("khanify this video", "clip this with the Khan visual"), especially when it must be free, local, and use no paid APIs or keys. macOS only.★ 113 GitHub starsSkillPick the output format that makes an explanation easiestUnderstanding ladderChangWenC/understanding-ladder · by ChangWenCPick the output format that makes an explanation easiest to understand, following Karpathy's understanding ladder — (1) plain controlled text, (2) diagram, (3) interactive HTML page, (4) 3Blue1Brown-style explainer video. Classify the content (definition/steps, process/causality, parameter→outcome, unfolding derivation), recommend the lowest rung that fully answers, then produce it. Works in English and Chinese. Use when the user says "explain this clearly", "help me understand", "draw a diagram", "make it interactive", "make an explainer video", "what's the best way to explain X", "understanding ladder", "Karpathy ladder", or 「讲清楚」「帮我理解」「画个图」「做个交互页」「做个讲解视频」「用哪种方式讲最好懂」「理解阶梯」; also when explaining a non-trivial concept, mechanism, algorithm, or an AI agent's output.★ 108 GitHub starsSkillAnimate first frames into A-roll talking head clipsAnimate (A-Roll)TheMattBerman/scrollclaw · by TheMattBermanAnimate first frames into A-roll talking head clips. Uses Sora 2 via fal.ai (primary) with Kling 3 auto-fallback when Sora is unavailable or sunset.★ 71 GitHub starsSkillGenerate B-roll environment and product shots with Kling 3B-Roll (Kling 3)TheMattBerman/scrollclaw · by TheMattBermanGenerate B-roll environment and product shots with Kling 3 via fal.ai. Environment matching, cut timing, and visual-only clips that play under continuous voice.★ 71 GitHub stars

More from digitalsamba

SkillAI music generation with ACE-Step 1.5ACE-Step 1.5 Music Generationdigitalsamba/claude-code-video-toolkit · by digitalsambaAI music generation with ACE-Step 1.5 — background music, vocal tracks, covers, stem extraction, audio repainting, and continuation for video production. Use when generating music, soundtracks, jingles, or working with audio stems. Triggers include background music, soundtrack, jingle, music generation, stem extraction, cover, style transfer, repaint, continuation, or musical composition tasks.★ 2.1k GitHub starsSkillGenerate AI voiceovers, sound effectsElevenLabs Audio Generationdigitalsamba/claude-code-video-toolkit · by digitalsambaGenerate AI voiceovers, sound effects, and music using ElevenLabs APIs. Use when creating audio content for videos, podcasts, or games. Triggers include generating voiceovers, narration, dialogue, sound effects from descriptions, background music, soundtrack generation, voice cloning, or any audio synthesis task.★ 2.1k GitHub starsSkillPrompting patterns for Ideogram 4 text-to-imageIdeogram 4 Skilldigitalsamba/claude-code-video-toolkit · by digitalsambaPrompting patterns for Ideogram 4 text-to-image — best-in-class in-image text rendering and exact color/layout control via structured JSON captions. Use when generating images that need legible on-image text (title cards, thumbnails, logos, signage, CTAs), precise brand colors, or controlled spatial layout. Triggers include title slide image, thumbnail with text, on-image text, legible text in image, brand color palette image, bounding-box layout, Ideogram.★ 2.1k GitHub starsSkillAI video generation with LTX-2.3 22BLTX-2.3 Video Generationdigitalsamba/claude-code-video-toolkit · by digitalsambaAI video generation with LTX-2.3 22B — text-to-video, image-to-video clips for video production. Use when generating video clips, animating images, creating b-roll, animated backgrounds, or motion content. Triggers include video generation, animate image, b-roll, motion, video clip, text-to-video, image-to-video.★ 2.1k GitHub starsSkillPython video composition with moviepy 2.xmoviepy for Video Productiondigitalsamba/claude-code-video-toolkit · by digitalsambaPython video composition with moviepy 2.x — overlaying deterministic text on AI-generated video (LTX-2, SadTalker), compositing clips, single-file build.py video projects. Use when adding labels/captions/lower-thirds to LTX-2 or SadTalker outputs, building short ad-style spots in pure Python without Remotion, or doing programmatic video composition. Triggers include text overlay on video, label LTX-2 clip, caption SadTalker output, lower third, build.py video, moviepy, Python video composition, sub-30s ad spot.★ 2.1k GitHub starsSkillRecord browser interactions as video using PlaywrightPlaywright Video Recordingdigitalsamba/claude-code-video-toolkit · by digitalsambaRecord browser interactions as video using Playwright. Use for capturing demo videos, app walkthroughs, and UI flows for Remotion videos. Triggers include recording a demo, capturing browser video, screen recording a website, or creating walkthrough footage.★ 2.1k GitHub stars