Input Seeking (Major Difference)
-ssBEFORE-i: fast seek, may be inaccurate—starts from nearest keyframe-ssAFTER-i: frame-accurate but slow—decodes from startCombine both:
-ss 00:30:00 -i input.mp4 -ss 00:00:05—fast seek then accurate trimFor cutting, add
-avoid_negative_ts make_zeroto fix timestamp issues
Stream Selection
Default: first video + first audio—may not be what you want
Explicit selection:
-map 0:v:0 -map 0:a:1—first video, second audioAll streams of type:
-map 0:a—all audio streamsCopy specific:
-map 0 -c copy—all streams, no re-encodingExclude:
-map 0 -map -0:s—all except subtitles
Encoding Quality
CRF (Constant Rate Factor): lower = better quality, larger file—18-23 typical for H.264
-preset: ultrafast to veryslow—slower = smaller file at same qualityTwo-pass for target bitrate: first pass analyzes, second pass encodes
-crfand-b:vmutually exclusive—use one or the other
Container vs Codec
Container (MP4, MKV, WebM): wrapper format holding streams
Codec (H.264, VP9, AAC): compression algorithm for stream
Not all codecs fit all containers—H.264 in MP4/MKV, not WebM; VP9 in WebM/MKV, not MP4
Copy codec to new container:
-c copy—fast, no quality loss
Filter Syntax
Simple:
-vf "scale=1280:720"—single filter chainComplex:
-filter_complex "[0:v]scale=1280:720[scaled]"—named outputs for routingChain filters:
-vf "scale=1280:720,fps=30"—comma-separatedFilter order matters—scale before crop gives different result than crop before scale
Common Filters
Scale:
scale=1280:720orscale=-1:720for auto-width maintaining aspectCrop:
crop=640:480:100:50—width:height:x:y from top-leftFPS:
fps=30—change framerateTrim:
trim=start=10:end=20,setpts=PTS-STARTPTS—setpts resets timestampsOverlay:
overlay=10:10—position from top-left
Audio Processing
Sample rate:
-ar 48000—standard for videoChannels:
-ac 2—stereoAudio codec:
-c:a aac -b:a 192k—AAC at 192kbpsNormalize:
-filter:a loudnorm—EBU R128 loudness normalizationExtract audio:
-vn -c:a copy output.m4a—no video, copy audio
Concatenation
Same codec/params: concat demuxer—
-f concat -safe 0 -i list.txt -c copyDifferent formats: concat filter—
-filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1"list.txt format:
file 'video1.mp4'per line—escape special charactersDifferent resolutions: scale/pad to match before concat filter
Subtitles
Burn-in (hardcode):
-vf "subtitles=subs.srt"—cannot be turned offMux as stream:
-c:s mov_text(MP4) or-c:s srt(MKV)—user toggleableFrom input:
-map 0:s—include subtitle streamsExtract:
-map 0:s:0 subs.srt—first subtitle to file
Hardware Acceleration
Decode:
-hwaccel cudaor-hwaccel videotoolbox(macOS)Encode:
-c:v h264_nvenc(NVIDIA),-c:v h264_videotoolbox(macOS)Not always faster—setup overhead; benefits show on long videos
Quality may differ—software encoding often produces better quality
Common Mistakes
Forgetting
-c copywhen not re-encoding—defaults to re-encode, slow and lossy-ssafter-ifor long videos—takes forever seekingAudio desync after cutting—use
-async 1or-af aresample=async=1Filter on stream copy—filters require re-encoding;
-c copy+-vf= errorOutput extension doesn't set codec—
output.mp4without-c:vuses default, may not be H.264