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.mp4This 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.mp4CRF 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.mp4Stream 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.gifGIF 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.jpgSeek 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.wavThe 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.mp4The 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.mp4On 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"
doneLoop, 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.mp4ffprobe 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


