FFmpeg
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0FFmpeg is the multimedia framework almost every other tool on this wiki leans on. It ships three command-line programs: ffmpeg (decode, filter, encode, mux), ffprobe (inspect files) and ffplay (a minimal player), plus the libav* libraries that players, browsers and encoders such as Av1an use internally.
FFmpeg wraps external encoders rather than replacing them: libx264, libx265, libsvtav1, libaom-av1, libopus and so on are the same libraries as the standalone encoders, exposed through FFmpeg options. Which of them you have depends entirely on how your binary was built.
For a guided first encode, see Make your first FFmpeg encode.
Get a good build
Section titled “Get a good build”| Platform | Recommended source |
|---|---|
| Windows | gyan.dev or BtbN. Both offer release and git-master builds. Pick gyan.dev’s “full” build for encoding work; it includes libraries such as SVT-AV1 and dav1d that the “essentials” build leaves out. winget install ffmpeg installs it. |
| macOS | Homebrew (brew install ffmpeg) or the static builds linked from the download page. |
| Linux | Your distribution’s package if it is recent. Debian/Ubuntu LTS packages are often several major versions behind; BtbN publishes static Linux builds as well. |
| Any | Build from source following the compilation guide when you need a specific encoder version or a library no packaged build includes. |
The FFmpeg project itself only publishes source code; every binary above is a third-party build. Encoders improve quickly, so an old distribution FFmpeg can be stuck on an SVT-AV1 or libaom release that is years out of date. ffmpeg -encoders shows what your build actually contains.
Licensing follows the build: FFmpeg is LGPL by default, becomes GPL when GPL libraries such as x264 or x265 are enabled, and builds with “nonfree” components such as libfdk_aac cannot be redistributed. See FFmpeg legal.
How a command is put together
Section titled “How a command is put together”ffmpeg [global options] [input options] -i input [output options] outputOptions apply to the next input or output file named after them, so position matters:
ffmpeg -r 24 -i input.mkv output.mkv # input option: treat the input as 24 fpsffmpeg -i input.mkv -r 24 output.mkv # output option: convert to 24 fps, dropping or duplicating framesA normal encode:
ffmpeg -i input.mkv -c:v libx264 -crf 20 -preset slow -c:a libopus -b:a 128k output.mkvThe :v and :a suffixes are stream specifiers. -c:v sets the video codec, -b:a the audio bitrate, -c:a:1 the codec of the second audio stream only. Encoder-specific options (-crf, -preset, -svtav1-params, -x265-params) are documented on each encoder’s page and in FFmpeg codecs; ffmpeg -h encoder=libsvtav1 prints the options your build’s wrapper accepts.
The output container is chosen from the file extension. Use -f only when there is no extension to go by, for example -f null - to decode without writing a file or -f yuv4mpegpipe - to pipe to another program.
Common general options:
| Option | Use |
|---|---|
-y | Overwrite the output without asking. |
-ss, -t, -to | Start time, duration and end time. Before -i they apply to the input, after it to the output. |
-frames:v N | Stop after N video frames. |
-hide_banner | Hide the build configuration that FFmpeg prints at startup. |
-loglevel error | Print only errors (useful in scripts). |
Choose streams with -map
Section titled “Choose streams with -map”Without -map, FFmpeg picks one video stream (highest resolution), one audio stream (most channels) and one subtitle stream if the output container can hold it. Extra audio tracks, subtitles, attachments and data streams are silently dropped. That is the most common surprise for newcomers.
Once you use -map, only the mapped streams go to the output:
ffmpeg -i input.mkv -map 0 -c:v libx264 -crf 20 -c:a copy -c:s copy output.mkv| Map | Selects |
|---|---|
-map 0 | Every stream of the first input |
-map 0:v:0 | The first video stream |
-map 0:a | All audio streams |
-map 0:a:m:language:jpn | Audio streams tagged Japanese |
-map -0:a:1 | Removes the second audio stream from what is already mapped |
-map '0:s?' | All subtitle streams, without failing if there are none |
-map 1:a | Audio from the second input file (inputs are numbered from 0) |
Quote maps that contain ? so your shell does not treat it as a wildcard. ffprobe input.mkv lists the streams with their indexes and languages.
Copy streams instead of re-encoding
Section titled “Copy streams instead of re-encoding”-c copy copies the compressed stream into the new container untouched. It is fast and lossless, so use it for every stream you are not re-encoding:
ffmpeg -i input.mkv -map 0 -c copy output.mp4The target container must support every copied codec. MP4, for example, cannot hold ASS or PGS subtitles, so the command above fails if the input has them; drop them with -map -0:s or keep Matroska. You can mix copy and encoding per stream:
ffmpeg -i input.mkv -map 0 -c copy -c:a:1 libopus -b:a:1 96k output.mkvCutting with -c copy can only start on a keyframe. With -ss before -i, FFmpeg keeps the frames from the previous keyframe so the cut starts earlier than you asked; re-encode the video if the cut has to be frame-accurate. For lossless cutting and joining of Matroska files, mkvmerge is usually easier.
Filters
Section titled “Filters”Filters only run on streams you re-encode; you cannot filter and -c copy the same stream. A single-input chain uses -vf (video) or -af (audio), with filters separated by commas:
ffmpeg -i input.mkv -vf "crop=1920:800,scale=-2:720" -c:v libsvtav1 -crf 35 -preset 6 -c:a copy output.mkvscale=-2:720 keeps the aspect ratio and rounds the width to an even number, which 4:2:0 encoders require. Filters with several inputs or outputs use -filter_complex with labelled pads. This one scales an encode back to the source resolution and stacks the two side by side for a visual comparison:
ffmpeg -i source.mkv -i encode.mkv -filter_complex "[1:v]scale=1920:1080:flags=bicubic[enc];[0:v][enc]hstack" -frames:v 1 compare.pngCommonly used filters include scale and zscale (resizing and colour conversion), crop, format (pixel format), fps, yadif/bwdif (deinterlacing) and the metric filters libvmaf, xpsnr, ssim and psnr. Anything more involved, such as denoising, debanding or inverse telecine, is usually done in VapourSynth.
Pipe into standalone encoders
Section titled “Pipe into standalone encoders”Standalone encoders often get new features before FFmpeg’s wrappers expose them. Pipe decoded frames to them as Y4M:
ffmpeg -i input.mkv -pix_fmt yuv420p10le -strict -1 -f yuv4mpegpipe - | SvtAv1EncApp -i - --crf 30 --preset 4 -b output.ivf-strict -1 is needed because 10-bit pixel formats are not part of the original Y4M specification and FFmpeg refuses to write them otherwise. The encoder writes video only; mux it with the audio afterwards using FFmpeg or mkvmerge.
Inspect files with ffprobe
Section titled “Inspect files with ffprobe”ffprobe input.mkvffprobe -v error -show_streams -show_format -of json input.mkvThe first prints a readable summary of every stream. The second gives the full stream properties (codec, profile, pixel format, colour metadata, frame rate, language and disposition) as JSON for scripts. -select_streams v:0 limits the output to one stream, and -show_entries stream=codec_name,pix_fmt,color_transfer to specific fields.
To check that a file decodes cleanly from start to finish:
ffmpeg -v error -i output.mkv -f null -Any decode error is printed; no output means the streams decoded without errors.
Documentation
Section titled “Documentation”- ffmpeg, filters, codecs, formats and ffprobe manuals;
ffmpeg -h fullprints every option offline. - The FFmpeg wiki has encoding guides for H.264, H.265 and AV1, some of them dated.
- On this wiki: first FFmpeg encode, audio and subtitles, preserving colour and HDR, and the encoder pages such as SVT-AV1 and x264.