Stop Googling ffmpeg Flags: 12 Recipes That Cover 95% of Real Jobs
ffmpeg's documentation reads like a phone book. Here's the operator's cut — twelve battle-tested recipes for converting, compressing, trimming, and extracting media, with the flags that matter and the gotchas that eat your afternoon.
Every Linux box worth its salt has ffmpeg one apt install away, and almost nobody has read its manual. The manual is 100,000 words of flags; real life is a dozen jobs you do over and over. The trap most people fall into is copying a random invocation from a forum, watching it work once, and never learning why — so the next file breaks in a new and exciting way.
This is the 12-recipe field guide. Learn these and you stop cargo-culting flags.
Ground rules before the recipes
Three things make every ffmpeg command readable:
-imarks an input. Options placed before-iconfigure the input; options after it configure the output. Order matters.-c copymeans "don't re-encode." It copies the stream as-is: instant and lossless. Anything else re-encodes, which costs CPU and (slightly) quality.- Test on a copy.
-yoverwrites output without asking;-nrefuses to overwrite. For batch jobs,-nis the safe default.
1. Convert anything to a plays-everywhere MP4
ffmpeg -i input.mkv -c:v libx264 -crf 23 -preset medium -c:a aac -movflags +faststart output.mp4
This is the one you'll use weekly. -crf 23 sets quality (lower is better and bigger; 18–28 is the sane range). -preset medium trades encoding speed for file size — veryfast for rush jobs, slow when size matters. -movflags +faststart moves the metadata to the front so web players start before the whole file downloads.
Gotcha: some old players and picky hardware choke on anything but 8-bit 4:2:0. Add -pix_fmt yuv420p and the "black screen on grandma's TV" class of bugs disappears.
2. Shrink a video for messaging apps
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset veryfast -vf "scale=1280:-2" -c:a aac -b:a 96k output.mp4
CRF 28 plus downscaling to 1280px wide turns a 200 MB clip into something you can actually send. Audio at 96k is plenty for phone speakers.
Gotcha: scale=1280:-2 — the -2 keeps the aspect ratio and forces an even height. x264 requires even dimensions; scale=1280:-1 on an odd-height source fails with a cryptic error.
3. Extract audio as MP3
ffmpeg -i video.mp4 -vn -c:a libmp3lame -q:a 2 audio.mp3
-vn drops the video stream; -q:a 2 is VBR quality (~190 kbps, transparent for most ears).
Gotcha: forget -vn and ffmpeg errors out — MP3 can't hold a video stream, and the error message won't say that plainly.
4. Trim a clip without re-encoding
ffmpeg -ss 00:01:30 -to 00:02:15 -i input.mp4 -c copy cut.mp4
Stream copy makes this instant: no quality loss, no waiting.
Gotcha: -ss before -i seeks fast but cuts at the nearest keyframe, so your cut point can drift a second or two. Put -ss after -i for frame-accurate cuts — slower, because it decodes everything up to that point. For sample-exact trims, drop -c copy and re-encode.
5. Make a GIF that doesn't look like a 1998 relic
ffmpeg -i input.mp4 -vf "fps=12,scale=480:-1:flags=lanczos,palettegen" palette.png
ffmpeg -i input.mp4 -i palette.png -lavfi "fps=12,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" out.gif
GIF only holds 256 colors; the two-pass palette trick picks the right 256 for your clip. Twelve fps and 480px wide keeps the file small enough to actually share.
Gotcha: the one-pass ffmpeg -i in.mp4 out.gif everyone tries first produces muddy, banded garbage. The palette pass is the entire trick.
6. Grab a thumbnail frame
ffmpeg -ss 00:00:42 -i video.mp4 -frames:v 1 -q:v 2 thumb.jpg
Seek to the moment, dump one frame. -q:v 2 sets JPEG quality (2–5 is the sweet spot).
Gotcha: -ss before -i is fast but lands on a keyframe, which might be a blurry scene change. For a precise frame, seek after -i — or just try a few timestamps; it's cheap.
7. Normalize podcast or interview audio
ffmpeg -i in.wav -af loudnorm=I=-16:TP=-1.5:LRA=11 out.wav
The loudnorm filter targets broadcast loudness standards (-16 LUFS is the podcast norm). One command, consistent volume.
Gotcha: single-pass loudnorm adjusts dynamically and may miss the target on tricky material. The correct workflow is two-pass: first pass with print_format=json to measure, second pass feeding the measured values in. For quick jobs one pass is fine; for published episodes, do both.
8. Join clips with no re-encode
printf "file 'a.mp4'\nfile 'b.mp4'\n" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy joined.mp4
The concat demuxer stitches files together at stream level — instant, lossless.
Gotcha: every file must share the same codec, resolution, and container parameters. Mixing a phone clip with a screen recording? Re-encode instead (-c:v libx264 -crf 20) or the join will glitch.
9. Record your screen
ffmpeg -f x11grab -video_size 1920x1080 -framerate 30 -i :0.0+0,0 -c:v libx264 -preset ultrafast out.mp4
On X11 this just works: capture the display, encode fast, sort it out later.
Gotcha: on Wayland, x11grab can't see native Wayland windows — that's a security feature, not a bug. Use your compositor's built-in recorder (GNOME and KDE both have one), wf-recorder on wlroots compositors, or OBS. Don't fight the display server; route around it.
10. Extract subtitles
ffmpeg -i movie.mkv -map 0:s:0 subs.srt
-map 0:s:0 means "first input, subtitle streams, the first one." Without -map, ffmpeg picks a "best" video and audio stream and silently drops everything else.
Gotcha: streams are zero-indexed per type. 0:s:1 is the second subtitle track (often the forced/SDH one you actually want). Check with ffprobe first — that's recipe 12.
11. Batch-convert a whole folder
for f in *.mkv; do
ffmpeg -n -i "$f" -c:v libx264 -crf 23 -c:a aac "${f%.mkv}.mp4"
done
Loop, convert, done. -n means "never overwrite" — the batch-safe choice when you're processing 50 files at 2 AM. "${f%.mkv}" strips the old extension.
Gotcha: quote "$f". Filenames with spaces will ruin your evening otherwise — the oldest shell trap in the book, still catching people.
12. Inspect a file before you touch it
ffprobe -v error -show_entries stream=codec_name,width,height,duration \
-of default=noprint_wrappers=1 input.mp4
ffprobe ships with ffmpeg and answers the questions you should ask before guessing flags: what codec is this, what resolution, how long, which audio track is English.
Gotcha: "why is this file 4 GB" and "why does the audio drift out of sync" are both answered here in two seconds. Make this a reflex.
What this doesn't cover
Filter graphs, hardware encoding (-hwaccel, NVENC/VAAPI — same recipes, different -c:v), and streaming are the other 5%. And when you want preset-driven encoding with a progress bar instead of flags, HandBrake exists for a reason — no shame in it.
But for the daily work — convert, shrink, trim, extract, join, inspect — these twelve are the whole job. The manual stays on the shelf for the day something truly weird shows up.
Sources: FFmpeg Documentation · FFmpeg Wiki · ffprobe Documentation
Reader feedback
Was this article helpful?
0 people found this article helpful.
