Skip to content

FFmpeg

Terminal window
ffmpeg [global options] -i <input> [output options] <output>

FFmpeg figures out formats from file extensions. Most of the work is specifying codecs, quality, and filters.


Terminal window
# MKV to MP4 (re-encode)
ffmpeg -i input.mkv output.mp4
# MKV to MP4 (copy streams — fast, no quality loss)
ffmpeg -i input.mkv -c copy output.mp4
# MOV to MP4
ffmpeg -i input.mov -c:v libx264 -c:a aac output.mp4

-c copy copies streams without re-encoding. Use this when you just need a container change — it’s instant and lossless. It fails if the target container doesn’t support the source codecs.

Terminal window
# Extract audio as-is
ffmpeg -i video.mp4 -vn -c:a copy audio.aac
# Extract and convert to MP3
ffmpeg -i video.mp4 -vn -q:a 2 audio.mp3
# Extract and convert to FLAC
ffmpeg -i video.mp4 -vn audio.flac

-vn = no video. -q:a 2 = variable bitrate quality (0=best, 9=worst for MP3).

Terminal window
# WAV to MP3
ffmpeg -i input.wav -b:a 320k output.mp3
# FLAC to MP3
ffmpeg -i input.flac -b:a 320k output.mp3
# MP3 to OGG
ffmpeg -i input.mp3 -c:a libvorbis -q:a 6 output.ogg

Terminal window
# Cut from 00:01:30 to 00:04:00
ffmpeg -i input.mp4 -ss 00:01:30 -to 00:04:00 -c copy output.mp4
# Cut 90 seconds starting at 00:01:30
ffmpeg -i input.mp4 -ss 00:01:30 -t 90 -c copy output.mp4

-ss = start time. -to = end time. -t = duration. Placing -ss before -i seeks faster (input seeking) but can be less accurate at keyframes.


Terminal window
# Scale to 1280x720
ffmpeg -i input.mp4 -vf scale=1280:720 output.mp4
# Scale width to 1280, auto-calculate height (keep aspect ratio)
ffmpeg -i input.mp4 -vf scale=1280:-2 output.mp4
# Scale to 50%
ffmpeg -i input.mp4 -vf scale=iw/2:ih/2 output.mp4

Use -2 instead of -1 for auto-dimension — it rounds to even numbers, which many codecs require.


Terminal window
# CRF mode (constant quality) — lower = better, 18-28 is sane range
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset medium output.mp4
# Presets: ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow
# Slower presets = better compression at same quality = smaller files = longer encode
Terminal window
ffmpeg -i input.mp4 -c:v libx265 -crf 28 output.mp4

~50% smaller files than H.264 at similar quality. Slower to encode. CRF scale differs — 28 in H.265 is roughly equivalent to 23 in H.264.


FlagPurpose
-c:vVideo codec (libx264, libx265, copy)
-c:aAudio codec (aac, libmp3lame, copy)
-c copyCopy all streams (no re-encoding)
-b:v 5MVideo bitrate
-b:a 320kAudio bitrate
-r 30Output frame rate
-anStrip audio
-vnStrip video
-snStrip subtitles
-yOverwrite output without asking
-nNever overwrite
-map 0Include all streams from first input
-metadata title="Name"Set metadata

Terminal window
ffmpeg -i input.mp4 -ss 5 -t 3 -vf "fps=15,scale=480:-2" -loop 0 output.gif
Terminal window
ffmpeg -i input.mp4 -vf subtitles=subs.srt output.mp4

Create a text file list.txt:

file 'part1.mp4'
file 'part2.mp4'
file 'part3.mp4'
Terminal window
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4
Terminal window
# One frame per second
ffmpeg -i input.mp4 -vf fps=1 frame_%04d.png
# Single frame at timestamp
ffmpeg -i input.mp4 -ss 00:00:30 -frames:v 1 thumbnail.png
Terminal window
ffmpeg -i input.mp4 -c:v libx264 -crf 28 -preset slow -c:a aac -b:a 128k -movflags +faststart output.mp4

-movflags +faststart moves the metadata to the beginning of the file so browsers can start playing before the full download.


Terminal window
# Show file info
ffprobe input.mp4
# JSON output (detailed)
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
# Just duration
ffprobe -v quiet -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4