cheat-sheets

ffmpeg

ffmpeg converts, trims, scales and re-encodes audio and video; ffprobe inspects media files. Syntax is ffmpeg [input options] -i INPUT [output options] OUTPUT, and options apply to the next file named after them. Pair it with yt-dlp for downloading media.

Documentation: ffmpeg docs, H.264 guide, H.265 guide

Install #

COMMANDDESCRIPTION
sudo apt install ffmpegUbuntu / Debian
brew install ffmpegmacOS (Homebrew)
winget install Gyan.FFmpegWindows (winget)
ffmpeg -versionShow version and build flags
ffmpeg -encoders | grep -i x26List available encoders (also -decoders, -formats, -hwaccels)

Everyday Conversions #

COMMANDDESCRIPTION
ffmpeg -i in.mkv out.mp4Convert; ffmpeg picks codecs from the extension (re-encodes)
ffmpeg -i in.mkv -c copy out.mp4Change container only, no re-encode (fast, lossless)
ffmpeg -i in.mp4 -c:v copy -c:a aac -b:a 192k out.mp4Copy video, re-encode audio
ffmpeg -i in.mov -vf scale=1280:-2 out.mp4Scale to 1280 wide, keep aspect (-2 keeps height even)
ffmpeg -i in.mp4 -vf scale=-2:720 out.mp4Scale to 720p tall
ffmpeg -i in.mp4 -r 30 out.mp4Change frame rate
ffmpeg -i in.mp4 -vf "transpose=1" out.mp4Rotate 90 degrees clockwise
ffmpeg -i in.mp4 -an out.mp4Drop the audio track
ffmpeg -y -i in.mkv out.mp4Overwrite the output without asking (-n never overwrites)
ffmpeg -hide_banner -loglevel error -i in.mkv out.mp4Quiet output for scripts
ffmpeg -i in.mkv -map 0 -c copy out.mkvKeep every stream (video, all audio, subtitles)
ffmpeg -i in.mkv -map 0:v -map 0:a:1 -c copy out.mkvPick streams: video plus the second audio track

Trim and Cut #

COMMANDDESCRIPTION
ffmpeg -ss 00:01:30 -to 00:02:45 -i in.mp4 -c copy out.mp4Cut a clip without re-encoding (snaps to keyframes)
ffmpeg -ss 00:01:30 -i in.mp4 -t 30 out.mp430 seconds from 1:30, re-encoded, frame accurate
ffmpeg -i in.mp4 -ss 90 -t 30 -c copy out.mp4Same as above using seconds
ffmpeg -sseof -10 -i in.mp4 -c copy out.mp4Last 10 seconds

-ss before -i seeks quickly; with -c copy the cut lands on the nearest earlier keyframe, so re-encode when you need exact frames.

Audio #

COMMANDDESCRIPTION
ffmpeg -i in.mp4 -vn -c:a copy out.m4aExtract audio without re-encoding (check the codec first)
ffmpeg -i in.mp4 -vn -c:a libmp3lame -q:a 2 out.mp3Extract to VBR MP3 (-q:a 0 best to 9 smallest)
ffmpeg -i in.wav -c:a flac out.flacLossless FLAC
ffmpeg -i in.mp3 -c:a libopus -b:a 96k out.opusOpus at 96 kbit/s
ffmpeg -i in.mp4 -af loudnorm out.mp4Normalise loudness (EBU R128, single pass)
ffmpeg -i in.mp4 -af volume=1.5 out.mp4Raise volume by 50%
ffmpeg -i video.mp4 -i audio.m4a -map 0:v -map 1:a -c copy -shortest out.mp4Replace or add an audio track

Encoding: x264, x265, AV1 #

Lower CRF means higher quality and a bigger file. Slower presets compress better at the same quality.

CODECEXAMPLENOTES
H.264ffmpeg -i in.mkv -c:v libx264 -crf 20 -preset medium -c:a aac -b:a 160k out.mp4CRF 18 to 28, default 23; widest compatibility
H.265ffmpeg -i in.mkv -c:v libx265 -crf 24 -preset medium -tag:v hvc1 -c:a copy out.mp4CRF 28 is about x264 CRF 23; -tag:v hvc1 helps Apple players
AV1 (SVT)ffmpeg -i in.mkv -c:v libsvtav1 -crf 32 -preset 6 -c:a libopus out.mkvCRF 0 to 63, preset 0 (slow) to 13 (fast)
AV1 (libaom)ffmpeg -i in.mkv -c:v libaom-av1 -crf 30 -b:v 0 -cpu-used 4 out.mkvSlow; -b:v 0 enables constant quality
VP9ffmpeg -i in.mkv -c:v libvpx-vp9 -crf 31 -b:v 0 out.webmWeb friendly
Web streamffmpeg -i in.mkv -c:v libx264 -crf 22 -pix_fmt yuv420p -movflags +faststart out.mp4faststart moves metadata up front for playback while downloading

Available encoders depend on how your ffmpeg was built; check with ffmpeg -encoders.

Hardware Acceleration #

Hardware encoders are much faster but give larger files than x264/x265 at the same quality. Use -cq/-global_quality/-qp rather than -crf.

HARDWAREEXAMPLE
NVIDIA NVENCffmpeg -hwaccel cuda -i in.mkv -c:v hevc_nvenc -preset p5 -cq 28 -c:a copy out.mkv
Intel QSVffmpeg -hwaccel qsv -i in.mkv -c:v h264_qsv -global_quality 23 out.mp4
VA-API (Intel/AMD, Linux)ffmpeg -vaapi_device /dev/dri/renderD128 -i in.mkv -vf 'format=nv12,hwupload' -c:v h264_vaapi -qp 23 out.mp4
AMD AMF (Windows)ffmpeg -i in.mkv -c:v h264_amf -quality balanced out.mp4
Apple VideoToolboxffmpeg -i in.mkv -c:v hevc_videotoolbox -q:v 60 out.mp4

Codec names follow h264_, hevc_ or av1_ plus the API. List support with ffmpeg -hwaccels and ffmpeg -encoders | grep -E 'nvenc|qsv|vaapi'. For containers, pass /dev/dri through (see Docker-Compose).

Concatenate #

Same codecs and parameters in every file: use the concat demuxer.

bash
printf "file '%s'\n" part1.mp4 part2.mp4 part3.mp4 > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy joined.mp4

Different codecs or sizes: use the concat filter (re-encodes).

bash
ffmpeg -i a.mp4 -i b.mp4 \
  -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" \
  -map "[v]" -map "[a]" out.mp4

GIF and Images #

COMMANDDESCRIPTION
ffmpeg -i in.mp4 -vf "fps=12,scale=480:-1:flags=lanczos" out.gifQuick GIF (poor palette)
ffmpeg -i in.mp4 -vf "fps=12,scale=480:-1:flags=lanczos,split[a][b];[a]palettegen[p];[b][p]paletteuse" out.gifGIF with a generated palette (better quality)
ffmpeg -ss 5 -i in.mp4 -frames:v 1 shot.pngOne screenshot at 5 seconds
ffmpeg -i in.mp4 -vf fps=1 frame_%04d.pngOne frame per second to PNGs
ffmpeg -framerate 30 -i frame_%04d.png -c:v libx264 -pix_fmt yuv420p out.mp4Images to video
ffmpeg -i in.mp4 -vf "thumbnail,scale=320:-1" -frames:v 1 thumb.jpgPick a representative frame

Subtitles #

COMMANDDESCRIPTION
ffmpeg -i in.mkv -map 0:s:0 subs.srtExtract the first subtitle track to SRT
ffmpeg -i in.mp4 -i subs.srt -c copy -c:s mov_text out.mp4Add soft subtitles to MP4
ffmpeg -i in.mp4 -i subs.srt -c copy -c:s srt out.mkvAdd soft subtitles to MKV
ffmpeg -i in.mp4 -vf "subtitles=subs.srt" out.mp4Burn subtitles into the picture (re-encodes)
ffmpeg -i in.mkv -vf "subtitles=in.mkv:si=1" out.mp4Burn in the second embedded subtitle track
ffmpeg -i in.mp4 -i subs.srt -map 0 -map 1 -c copy -metadata:s:s:0 language=eng out.mkvTag the subtitle language

Image-based subtitles (PGS, VobSub) cannot be converted to SRT without OCR.

ffprobe #

COMMANDDESCRIPTION
ffprobe in.mp4Human-readable summary of streams
ffprobe -v error -show_format -show_streams in.mp4Full detail
ffprobe -v error -print_format json -show_format -show_streams in.mp4JSON output, pipe to jq
ffprobe -v error -select_streams v:0 -show_entries stream=codec_name,width,height,r_frame_rate -of csv=p=0 in.mp4Video codec, size and frame rate
ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 in.mp4Duration in seconds
ffprobe -v error -select_streams a -show_entries stream=index,codec_name:stream_tags=language -of csv=p=0 in.mkvAudio tracks and languages

Batch Examples #

bash
# Convert every MKV in a folder to MP4 (H.264/AAC)
for f in *.mkv; do ffmpeg -n -i "$f" -c:v libx264 -crf 22 -c:a aac "${f%.mkv}.mp4"; done
powershell
# PowerShell equivalent
Get-ChildItem *.mkv | ForEach-Object { ffmpeg -n -i $_.FullName -c:v libx264 -crf 22 -c:a aac "$($_.BaseName).mp4" }

In a while read loop add -nostdin to ffmpeg, otherwise it swallows the loop’s standard input.

Not Verified #

Commands were written from the official documentation and not executed. Hardware encoder flags depend on drivers and the ffmpeg build.

Search all sheets

Tip: / or Ctrl/Cmd+K to open, Esc to close.