I grew up around audio and apprenticed in a studio. FFmpeg was how I got to play with audio on my own: convert, cut, rip a track, resample, batch a whole folder of takes. It’s bailed me out more times than I can count and is still one of the most useful tools I’ve learned - so this is my recipe box, the commands I keep coming back to.
FFmpeg can convert, cut, resize, filter, mux, and record essentially any audio/video. It looks cryptic because it’s one tool for a thousand jobs - but almost every command is the same shape. Learn the shape and the recipes below cover the rest.
The mental model
ffmpeg [global opts] -i INPUT [per-output opts] OUTPUT- Options before
-iapply to reading the input (e.g. seek). - Options after the input apply to writing the output (codecs, filters).
-c copy= stream copy: no re-encode → instant and lossless (only remuxes). Drop it and ffmpeg re-encodes (slow, lossy, but lets you change quality/size).-yoverwrites the output without asking;-c:v/-c:apick video/audio codec.
Two things that confuse everyone:
-crfis backwards: lower = higher quality + bigger file (x264 sane range 18–28, 23 default).-ssplacement: before-i= fast keyframe seek; after-i= slow but frame-accurate.
Inspect anything first:
ffprobe -hide_banner input.mp4 # codecs, resolution, duration, bitrateConvert & remux
# Re-encode to MP4 (H.264 + AAC) - universal, web-safe
ffmpeg -i in.mov -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 128k out.mp4
# Change container only, NO re-encode (instant, lossless) - e.g. MKV → MP4
ffmpeg -i in.mkv -c copy out.mp4Cut & trim
# Fast, lossless cut (snaps to nearest keyframe)
ffmpeg -ss 00:01:30 -i in.mp4 -t 30 -c copy clip.mp4 # 30s starting at 1:30
# Frame-accurate cut (re-encodes; -ss AFTER -i)
ffmpeg -i in.mp4 -ss 00:01:30 -to 00:02:00 -c:v libx264 -crf 20 clip.mp4Resize, framerate, rotate
ffmpeg -i in.mp4 -vf "scale=1280:-2" out.mp4 # width 1280, height auto (-2 = keep AR, even)
ffmpeg -i in.mp4 -r 30 out.mp4 # force 30 fps
ffmpeg -i in.mp4 -vf "transpose=1" out.mp4 # rotate 90° CW (2 = CCW); hflip / vflip to mirrorAudio: extract, strip, volume, normalize
ffmpeg -i in.mp4 -vn -c:a copy audio.m4a # rip audio, no re-encode
ffmpeg -i in.mp4 -vn -q:a 2 audio.mp3 # to MP3 (q:a 0=best … 9=worst)
ffmpeg -i in.mp4 -an -c:v copy muted.mp4 # remove audio
ffmpeg -i in.mp3 -af "volume=1.5" louder.mp3 # +50% volume
ffmpeg -i in.mp3 -af loudnorm out.mp3 # EBU R128 loudness normalizeCompress (shrink a big file)
ffmpeg -i big.mp4 -c:v libx264 -crf 28 -preset slow -c:a aac -b:a 96k small.mp4Push crf up (28–32) and use a slower -preset for smaller files; slower preset =
better compression at the same quality, just more CPU time.
Frames, thumbnails & GIFs
ffmpeg -ss 00:00:05 -i in.mp4 -frames:v 1 thumb.jpg # one frame at 5s
ffmpeg -i in.mp4 -vf "fps=1" frame_%04d.png # a frame every second
# High-quality GIF (two-pass palette - the trick to non-ugly gifs)
ffmpeg -i in.mp4 -vf "fps=15,scale=480:-1:flags=lanczos,palettegen" palette.png
ffmpeg -i in.mp4 -i palette.png \
-filter_complex "fps=15,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" out.gifJoin & merge
# Concatenate clips with the SAME codec (lossless) - via a list file
printf "file 'a.mp4'\nfile 'b.mp4'\n" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy joined.mp4
# Mux separate video + audio into one file
ffmpeg -i video.mp4 -i audio.aac -c copy -map 0:v:0 -map 1:a:0 -shortest out.mp4Overlays & subtitles
# Watermark a logo bottom-right, 10px margin
ffmpeg -i in.mp4 -i logo.png -filter_complex "overlay=W-w-10:H-h-10" out.mp4
# Burn subtitles INTO the video (hard subs)
ffmpeg -i in.mp4 -vf "subtitles=subs.srt" out.mp4
# Add subtitles as a soft, toggleable track (no re-encode)
ffmpeg -i in.mp4 -i subs.srt -c copy -c:s mov_text out.mp4Speed up / slow down
# 2× faster (video + audio kept in sync)
ffmpeg -i in.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" \
-map "[v]" -map "[a]" fast.mp4setpts multiplier is the inverse of speed (0.5 = 2×); atempo is the speed
directly (valid 0.5–2.0, chain two for more, e.g. atempo=2.0,atempo=2.0 = 4×).
Notes
-c copyis your friend - if you’re only cutting or changing the container, never re-encode. It’s instant and preserves quality perfectly.-filter_complexvs-vf:-vfis a simple single-stream video filter;-filter_complexis for multiple inputs/outputs (overlays, merging, a/v filters together).- Hardware encoding (
-c:v h264_nvencon Nvidia,h264_videotoolboxon macOS) is far faster thanlibx264but slightly lower quality per bit - great for bulk jobs. - Add
-hide_bannerto quiet the version spam;-v errorto only see real errors.