- Add skills: bugbot-review, ffmpeg, media-creation, video-editing - Add mcp/servers.json with example remote MCP config - Add opencode/oh-my-opencode.json with example agent config - Update README to document new directories - Make workspace templates generic (remove personal email)
12 KiB
12 KiB
name, description
| name | description |
|---|---|
| video-editing | Convert, edit, and process video and audio files using ffmpeg and ffprobe. Triggers: video conversion, video editing, ffmpeg, transcode, compress video, extract audio, trim video, merge videos, add subtitles, resize video, change framerate, gif creation, video filters. |
Role: FFmpeg Editor
You transform video/audio with ffmpeg using the safest and most efficient commands.
Mission
Produce the requested output with minimal quality loss and clear, reproducible commands.
Operating Principles
- Prefer stream copy when no re-encode is needed.
- Preserve audio unless asked to remove or replace it.
- Do not overwrite inputs; use a new output name by default.
- Ask for missing details once, then proceed.
- Verify output properties before calling it done.
Activation
Use when
- Convert video between formats (MP4, MOV, WebM, MKV, GIF)
- Compress or resize videos
- Extract or replace audio
- Trim, cut, concatenate, or stabilize
- Add subtitles, watermarks, or text overlays
- Apply filters or change framerate/resolution
Avoid when
- AI-based video generation (use media-creation instead)
- ffmpeg/ffprobe are not installed
Inputs to Ask For (only if missing)
- Input file path(s)
- Desired output format and path
- Target resolution, bitrate, or file size
- Keep audio? (yes/no)
- Frame rate or duration changes
- Subtitle file path (if adding subs)
Decision Flow
- Can the job be done with stream copy (
-c copy)? If yes, avoid re-encode. - If re-encoding, pick codec and quality (CRF/preset) based on size vs quality.
- Decide audio handling (copy, re-encode, replace, remove).
- For web delivery, add
-movflags +faststart.
Procedure
- Inspect inputs with ffprobe.
- Draft the exact ffmpeg command and confirm outputs.
- Run the command and verify duration, resolution, audio, and file size.
- Provide the final command and output path in the response.
Outputs / Definition of Done
- Output file exists at the requested path
- Properties match the requested format and specs
- Any transforms (trim, resize, subtitles) are confirmed
Guardrails
- Never overwrite the input file.
- Use
-yonly when the output path is explicitly confirmed or safe to overwrite. - Quote paths with spaces.
Quick Reference - Common Tasks
Get Video Information
ffprobe -v quiet -print_format json -show_format -show_streams "input.mp4"
Convert Format
# MP4 to WebM (VP9 + Opus)
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webm
# Any format to MP4 (H.264 + AAC - most compatible)
ffmpeg -i input.mov -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 128k output.mp4
# Convert to H.265/HEVC (smaller file, good quality)
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a aac output_hevc.mp4
Compress Video
# Reduce file size (higher CRF = more compression, 18-28 is typical)
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset slow -c:a aac -b:a 128k output.mp4
# Two-pass encoding for target file size
ffmpeg -i input.mp4 -c:v libx264 -b:v 1M -pass 1 -an -f null /dev/null && \
ffmpeg -i input.mp4 -c:v libx264 -b:v 1M -pass 2 -c:a aac -b:a 128k output.mp4
Resize/Scale Video
# Scale to 1080p (maintain aspect ratio)
ffmpeg -i input.mp4 -vf "scale=-1:1080" -c:a copy output.mp4
# Scale to 720p width
ffmpeg -i input.mp4 -vf "scale=1280:-1" -c:a copy output.mp4
# Scale to exact dimensions (may stretch)
ffmpeg -i input.mp4 -vf "scale=1920:1080" output.mp4
# Scale with padding to fit exact dimensions
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2" output.mp4
Trim/Cut Video
# Cut from timestamp to timestamp (fast, no re-encode)
ffmpeg -ss 00:01:30 -to 00:02:45 -i input.mp4 -c copy output.mp4
# Cut with re-encoding (more accurate timestamps)
ffmpeg -i input.mp4 -ss 00:01:30 -to 00:02:45 -c:v libx264 -c:a aac output.mp4
# Cut first N seconds
ffmpeg -i input.mp4 -t 30 -c copy output.mp4
# Skip first N seconds
ffmpeg -ss 10 -i input.mp4 -c copy output.mp4
Extract/Replace Audio
# Extract audio to MP3
ffmpeg -i input.mp4 -vn -acodec libmp3lame -q:a 2 output.mp3
# Extract audio to WAV
ffmpeg -i input.mp4 -vn -acodec pcm_s16le output.wav
# Remove audio from video
ffmpeg -i input.mp4 -c:v copy -an output.mp4
# Replace audio track
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 output.mp4
# Add audio to video (mix with original)
ffmpeg -i video.mp4 -i music.mp3 -filter_complex "[0:a][1:a]amix=inputs=2:duration=first" -c:v copy output.mp4
Concatenate Videos
# Create a file list (files.txt):
# file 'video1.mp4'
# file 'video2.mp4'
# file 'video3.mp4'
# Concatenate (same codec)
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
# Concatenate with re-encoding (different codecs/resolutions)
ffmpeg -f concat -safe 0 -i files.txt -c:v libx264 -c:a aac output.mp4
Create GIF
# Simple GIF (low quality)
ffmpeg -i input.mp4 -vf "fps=10,scale=480:-1" output.gif
# High quality GIF with palette
ffmpeg -i input.mp4 -vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif
# GIF from specific time range
ffmpeg -ss 00:00:05 -t 3 -i input.mp4 -vf "fps=15,scale=320:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" output.gif
Change Framerate/Speed
# Change framerate
ffmpeg -i input.mp4 -filter:v fps=30 output.mp4
# Speed up video 2x
ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" -filter:a "atempo=2.0" output.mp4
# Slow down video 0.5x
ffmpeg -i input.mp4 -filter:v "setpts=2.0*PTS" -filter:a "atempo=0.5" output.mp4
Add Subtitles
# Burn subtitles into video (hardcoded)
ffmpeg -i input.mp4 -vf "subtitles=subs.srt" output.mp4
# Add subtitle stream (soft subs)
ffmpeg -i input.mp4 -i subs.srt -c:v copy -c:a copy -c:s mov_text output.mp4
Add Text/Watermark
# Add text overlay
ffmpeg -i input.mp4 -vf "drawtext=text='Hello World':fontsize=24:fontcolor=white:x=10:y=10" output.mp4
# Add image watermark
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=10:10" output.mp4
# Add watermark bottom-right corner
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4
Video Filters
# Rotate video
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4 # 90 clockwise
ffmpeg -i input.mp4 -vf "transpose=2" output.mp4 # 90 counter-clockwise
ffmpeg -i input.mp4 -vf "hflip" output.mp4 # horizontal flip
ffmpeg -i input.mp4 -vf "vflip" output.mp4 # vertical flip
# Crop video (width:height:x:y)
ffmpeg -i input.mp4 -vf "crop=640:480:100:50" output.mp4
# Crop to center square
ffmpeg -i input.mp4 -vf "crop=min(iw\,ih):min(iw\,ih)" output.mp4
# Blur video
ffmpeg -i input.mp4 -vf "boxblur=5:1" output.mp4
# Sharpen video
ffmpeg -i input.mp4 -vf "unsharp=5:5:1.0:5:5:0.0" output.mp4
# Adjust brightness/contrast/saturation
ffmpeg -i input.mp4 -vf "eq=brightness=0.1:contrast=1.2:saturation=1.3" output.mp4
# Denoise video
ffmpeg -i input.mp4 -vf "hqdn3d=4:3:6:4.5" output.mp4
# Color correction (curves)
ffmpeg -i input.mp4 -vf "curves=preset=lighter" output.mp4
Video Stabilization
# Two-pass stabilization
ffmpeg -i input.mp4 -vf vidstabdetect -f null -
ffmpeg -i input.mp4 -vf vidstabtransform=smoothing=10 output.mp4
Green Screen / Chroma Key
# Remove green background
ffmpeg -i greenscreen.mp4 -vf "chromakey=0x00FF00:0.1:0.2" -c:v png output.mov
# Replace green screen with another video
ffmpeg -i background.mp4 -i greenscreen.mp4 -filter_complex "[1:v]chromakey=0x00FF00:0.1:0.2[fg];[0:v][fg]overlay[out]" -map "[out]" output.mp4
Extract Frames
# Extract all frames as images
ffmpeg -i input.mp4 frame_%04d.png
# Extract 1 frame per second
ffmpeg -i input.mp4 -vf fps=1 frame_%04d.png
# Extract single frame at timestamp
ffmpeg -ss 00:00:10 -i input.mp4 -frames:v 1 frame.png
# Extract thumbnail/poster
ffmpeg -i input.mp4 -ss 00:00:01 -frames:v 1 thumbnail.jpg
Create Video from Images
# Images to video (image sequence)
ffmpeg -framerate 30 -i frame_%04d.png -c:v libx264 -pix_fmt yuv420p output.mp4
# Single image to video with duration
ffmpeg -loop 1 -i image.png -c:v libx264 -t 10 -pix_fmt yuv420p output.mp4
Screen Recording
# macOS screen capture
ffmpeg -f avfoundation -i "1" -r 30 -c:v libx264 output.mp4
# List available devices (macOS)
ffmpeg -f avfoundation -list_devices true -i ""
Hardware Accelerated Encoding (macOS)
# H.264 with VideoToolbox (much faster)
ffmpeg -i input.mp4 -c:v h264_videotoolbox -b:v 5M output.mp4
# HEVC with VideoToolbox
ffmpeg -i input.mp4 -c:v hevc_videotoolbox -b:v 5M output.mp4
# Check available hardware encoders
ffmpeg -encoders | grep videotoolbox
Batch Processing
# Convert all MP4 files in a directory to WebM
for f in *.mp4; do ffmpeg -i "$f" -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus "${f%.mp4}.webm"; done
# Extract thumbnails from multiple videos
for f in *.mp4; do ffmpeg -i "$f" -ss 00:00:01 -frames:v 1 "${f%.mp4}_thumb.jpg"; done
# Compress all videos in directory
for f in *.mp4; do ffmpeg -i "$f" -c:v libx264 -crf 28 -preset fast -c:a aac "compressed_$f"; done
Codec Quick Reference
| Codec | Encoder | Use Case |
|---|---|---|
| H.264 | libx264 |
Most compatible, good quality/size |
| H.265/HEVC | libx265 |
Better compression, newer devices |
| VP9 | libvpx-vp9 |
WebM format, web streaming |
| AV1 | libaom-av1 / libsvtav1 |
Best compression, slow encode |
| ProRes | prores_ks |
Professional editing, large files |
| AAC | aac |
Standard audio codec |
| MP3 | libmp3lame |
Legacy audio format |
| Opus | libopus |
Modern audio, web streaming |
Quality Presets
CRF (Constant Rate Factor)
- 0 = Lossless
- 18 = Visually lossless
- 23 = Default (good balance)
- 28 = Lower quality, smaller file
- 51 = Worst quality
Encoding Presets (libx264/libx265)
ultrafast- Fastest, largest filefast- Good balance for quick encodesmedium- Defaultslow- Better compressionveryslow- Best compression, very slow
Common Issues & Solutions
Audio/Video Sync Issues
# Re-encode with fixed timestamps
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -async 1 output.mp4
Variable Frame Rate (VFR) to Constant Frame Rate (CFR)
ffmpeg -i input.mp4 -vsync cfr -r 30 output.mp4
Fix Rotation Metadata
ffmpeg -i input.mp4 -c copy -metadata:s:v:0 rotate=0 output.mp4
Convert for Web/HTML5
# MP4 for web (H.264 baseline, compatible with all browsers)
ffmpeg -i input.mp4 -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p -c:a aac -movflags +faststart output.mp4
Execution Notes
- Analyze the input with ffprobe.
- Prefer
-c copywhen no re-encode is needed. - Use a short clip test for long jobs.
- Use
-yonly when the output path is confirmed safe to overwrite.
Best Practices
- Quote file paths with spaces:
ffmpeg -i "my video.mp4" output.mp4 - Use
-hide_bannerfor cleaner output:ffmpeg -hide_banner -i input.mp4 ... - Preserve metadata when copying:
ffmpeg -i input.mp4 -c copy -map_metadata 0 output.mp4 - For web videos, add
-movflags +faststartfor progressive playback - Check codec support before encoding:
ffmpeg -encoders | grep <codec>
Error Handling
# Check if ffmpeg is installed
command -v ffmpeg >/dev/null 2>&1 || { echo "ffmpeg not installed"; exit 1; }
# Verify input file exists
[ -f "input.mp4" ] || { echo "Input file not found"; exit 1; }
# Check supported formats
ffmpeg -formats | grep <format>
# Verbose output for debugging
ffmpeg -v verbose -i input.mp4 output.mp4
References
references/ffmpeg-filters.md- Comprehensive filter referencereferences/ffmpeg-codecs.md- Detailed codec information