OpenParable
Skip to content
← Back to skills

Ffmpeg

Documents
ffmpeg

Ffmpeg is an Agent Skill for documents published in the rendi-api/ffmpeg-cheatsheet repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.

Use when the user asks for FFmpeg or FFprobe commands, video/audio conversion, trimming, resizing, padding, overlays, subtitles, thumbnails, GIFs, storyboards, slideshows, social-media crops, codec settings, CRF/preset tuning, stream mapping, or troubleshooting media automation pipelines.

View on GitHub ↗
QUICK START

How to use this skill

Bring this guide into your coding agent with a prompt tailored to the tool you use.

  1. Open your project in Codex.
  2. Copy and paste the prompt below.
  3. Review files and risks before approving any action.
Prompt to paste
Inspect the Agent Skill at https://github.com/rendi-api/ffmpeg-cheatsheet/blob/HEAD/skills/ffmpeg/SKILL.md and all supporting files. Report provenance, permissions, scripts, dependencies, and security risks. Propose an exact installation into .agents/skills/ffmpeg, but wait for my approval before writing files or running scripts.

Copying this prompt does not install or run the skill. Review third-party files before use.

FFmpeg

Use this skill to produce reliable, explainable FFmpeg/FFprobe commands for media automation.

Workflow

  1. Identify the user's source media, desired output container/codec, target dimensions/duration, and whether quality, speed, or file size matters most.
  2. Prefer the simplest command that meets the goal.
  3. Use -c copy only when no filtering, re-encoding, precise trimming, subtitle burn-in, compression, or codec change is needed.
  4. Use explicit stream mapping when multiple inputs or outputs are involved.
  5. For commands with filters, quote the filter graph and name streams in filter_complex when it improves readability.
  6. Include -y only when the user wants non-interactive overwrite behavior.
  7. Validate command intent with ffprobe or a low-duration sample when practical.

Defaults

  • Web-compatible MP4: -c:v libx264 -crf 18 -preset slow -pix_fmt yuv420p -c:a aac -movflags +faststart
  • High-quality archival H.264: -c:v libx264 -crf 17 or -crf 18
  • Smaller modern MP4: -c:v libx265 -crf 24 -vtag hvc1 -c:a aac
  • WebM/VP9: -c:v libvpx-vp9 -crf 15 -b:v 0 -c:a libopus
  • Preserve audio when safe: -c:a copy
  • Force square pixels after scale/pad/crop: setsar=1:1
  • Playback compatibility from generated images: format=yuv420p or -pix_fmt yuv420p

Common command patterns

Inspect media

ffprobe -hide_banner -show_streams -show_format input.mp4

Remux without re-encoding

ffmpeg -i input.mp4 -c copy output.mkv

Resize and pad to vertical 1080x1920

ffmpeg -i input.mp4 \
  -vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2:color=black,setsar=1:1" \
  -c:v libx264 -crf 18 -preset slow -pix_fmt yuv420p -c:a aac -movflags +faststart \
  output.mp4

Frame-accurate trim

Use output seeking and re-encode for reliable exact cuts:

ffmpeg -i input.mp4 -ss 00:00:10 -to 00:00:25 \
  -c:v libx264 -crf 18 -preset slow -c:a aac output_trimmed.mp4

Use input seeking before -i only when speed matters more than accuracy.

Replace audio

ffmpeg -i input.mp4 -i music.mp3 \
  -map 0:v -map 1:a -shortest -c:v copy -c:a aac output.mp4

Mix background music under original audio

ffmpeg -i input.mp4 -i music.mp3 \
  -filter_complex "[1:a]volume=0.2[bgm];[0:a][bgm]amix=inputs=2:duration=shortest[a]" \
  -map 0:v -map "[a]" -c:v copy -c:a aac -shortest output.mp4

Overlay logo for a time range

ffmpeg -i input.mp4 -i logo.png \
  -filter_complex "overlay=x=(main_w-overlay_w)/8:y=(main_h-overlay_h)/8:enable='gte(t,1)*lte(t,7)'" \
  -c:v libx264 -crf 18 -preset slow -c:a copy output.mp4

Burn subtitles

ffmpeg -i input.mp4 \
  -vf "subtitles=subtitles.srt:fontsdir=.:force_style='FontName=Poppins,FontSize=24,PrimaryColour=&HFFFFFF'" \
  -c:v libx264 -crf 18 -preset slow -c:a copy output_subtitled.mp4

Add soft subtitle track

ffmpeg -i input.mp4 -i subtitles.srt \
  -c copy -c:s srt -disposition:s:0 default output.mkv

Thumbnail

ffmpeg -i input.mp4 -ss 00:00:07 -frames:v 1 -q:v 2 thumbnail.jpg

GIF from video

ffmpeg -i input.mp4 \
  -vf "select='gt(trunc(t/2),trunc(prev_t/2))',setpts='PTS*0.1',scale=trunc(oh*a/2)*2:320:force_original_aspect_ratio=decrease,pad=trunc(oh*a/2)*2:320:-1:-1" \
  -loop 0 -an output.gif

Takes every second frame and accelerates playback 10x; scale=trunc(oh*a/2)*2:320 forces an even width derived from a 320px height while preserving aspect ratio. Use -loop 1 for play-once.

Gotchas

  • -c copy cannot apply filters and is not frame-accurate for most cuts.
  • -ss before -i is fast but approximate; -ss after -i is slower but accurate.
  • MP4 playback in QuickTime and browsers often needs yuv420p for H.264 output.
  • Use -movflags +faststart for web-hosted MP4/MOV/M4A so playback starts sooner.
  • In filter graphs, [0:v] means first input's video stream, [1:a] means second input's audio stream, and -map chooses which streams become outputs.
  • Escaping filter expressions is shell-sensitive. Prefer single quotes inside double-quoted filter graphs for time expressions, and escape commas inside nested expressions when required.
  • drawtext with special characters is fragile; prefer textfile= for user-supplied text.
  • Burned subtitles require re-encoding; soft subtitle tracks can often use stream copy.

When more depth is needed

Load references/command-patterns.md for additional examples and decision rules distilled from this repository's FFmpeg cheat sheet.