Choose and Verify FFmpeg Codecs Before You Encode
You will finish with a codec that this FFmpeg installation can actually use, a small test file, and a command you can adapt without guessing whether a name refers to an encoder or a decoder. The examples were checked against FFmpeg 8.0.1 on Linux.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes for the first pass. You need an installed ffmpeg, a readable input file if you are testing your own media, and enough space for a temporary output. Nothing here needs root privileges. Keep the input and output paths as ordinary user files.
1. Confirm the installation and version
Start by checking the executable that will run your command. This catches the common distraction where a shell, container or service is using a different FFmpeg build from the one you expected.
$ command -v ffmpeg
$ ffmpeg -version | sed -n '1,4p'
Expected output begins with a path such as /usr/bin/ffmpeg and a version line. This machine reports ffmpeg version 8.0.1. The available codecs depend on how the package was built, so do not copy a codec name from another machine without checking it here.
Checkpoint: the executable is known
If command -v prints nothing, install or enable the FFmpeg package through your distribution's normal package management, then repeat this step. Do not work around a missing binary by changing a service or adding a system-wide symlink.
2. Read the codec capability flags
Ask FFmpeg for its enabled codec list and inspect the six-character capability field. The first character means decoding, the second means encoding, and later characters identify video, audio, subtitles and other properties.
$ ffmpeg -hide_banner -codecs 2>/dev/null | sed -n '1,16p'
$ ffmpeg -hide_banner -codecs 2>/dev/null | grep -E ' (h264|aac|opus) '
For example, a line beginning VFS..D h264 has a decoding marker in the first position and describes the H.264 codec. A line beginning .EVIL. a64_multi has an encoding marker in the second position. The exact list will vary with the package build.
The codec list is not the same thing as a list of usable encoders. A codec may have several implementations, such as a native encoder and an external-library encoder. Use the separate lists when choosing a name for -c:v or -c:a.
3. Check the encoder and its private options
List encoders, then request help for the exact implementation. The generic options described by ffmpeg-codecs(1) apply broadly, while private options belong only to the selected codec.
$ ffmpeg -hide_banner -encoders 2>/dev/null | grep -E ' (libx264|aac|libopus) '
$ ffmpeg -hide_banner -h encoder=libx264 2>/dev/null | sed -n '1,35p'
On the checked installation, libx264, aac and libopus are present. The encoder help reports options including -preset, -tune and -crf for libx264. Do not assume that an option shown for libx264 is accepted by another H.264 encoder.
4. Run a small, reversible encode
Before processing a long recording, create a two-second test file. This uses FFmpeg's built-in test pattern, so it does not need an input file and does not alter your media.
$ TEST_OUT=/tmp/ffmpeg-codecs-test.mp4
$ ffmpeg -hide_banner -y \
-f lavfi -i 'testsrc2=size=320x180:rate=10' \
-t 2 -an -c:v libx264 -preset veryfast -crf 28 "$TEST_OUT"
Successful output ends with a summary containing a video stream and a line similar to video:...kB. The -y flag permits replacement of this disposable path. Do not use it with a valuable destination unless overwriting is deliberate.
Verify the result with a probe rather than trusting the exit status alone:
$ ffprobe -hide_banner -v error \
-show_entries stream=codec_name,codec_type,width,height \
-of default=noprint_wrappers=1 "$TEST_OUT"
codec_name=h264
codec_type=video
width=320
height=180
Remove only this temporary file when you are finished:
$ rm -- "$TEST_OUT"
5. Apply generic options with care
The manpage documents options shared by encoders and decoders, but their effect depends on the media type and codec. For example, -threads defaults to automatic selection for supported video codecs. Set it only when you have a reason to cap or reproduce parallelism:
$ ffmpeg -hide_banner -i /path/to/input.mp4 \
-c:v libx264 -threads 4 -c:a copy /path/to/output.mp4
-c:a copy leaves the audio stream compressed as it is, while the video is encoded by libx264. If the output container or player rejects that audio format, choose an audio encoder after checking it with -encoders, for example -c:a aac -b:a 128k. The codec guide lists -b as a bitrate option and gives 128K as the default audio bitrate, but an explicit value makes a production command easier to review.
Other generic options have sharp trade-offs. -lowres decodes at half, quarter or eighth resolution, and -skip_frame can discard frames. These can be useful for analysis, previews or resource limits, but are wrong for a faithful transcode. The default for -skip_frame is default, not all.
6. Keep decoding boundaries explicit
Do not enable experimental decoding merely to make an unfamiliar file open. The codec documentation warns that experimental decoders can pose a security risk when decoding untrusted input. For files from outside your control, use a current package, keep the output directory separate, and avoid running conversion commands as root.
You can narrow the input decoder set with the documented codec_whitelist option when your workflow requires an allow-list. Its value is a comma-separated list, and the default is to allow all decoders. Treat that as a policy decision: a narrow list can make a pipeline fail on a legitimate input rather than silently selecting another decoder.
Common failure points
- "Unknown encoder": the name is absent from
ffmpeg -encoders, or the package lacks the external library used by that encoder. Choose an encoder present on this installation or install the distribution package that supplies the required build feature. - The codec list looks right but the command fails: you selected a codec name instead of an encoder implementation, or placed an option after the wrong output. Recheck
-h encoder=NAMEand keep output-specific options with their output. - The output is unexpectedly large or poor: bitrate and quality controls are codec-specific. Inspect the selected encoder's help instead of transferring
-crf,-qscaleor a preset from another encoder. - A test works but the real file fails: compare the input's streams and pixel format, then test a short section of the real file. A generated test pattern proves the encoder works, not that every source format is supported.
Done means
command -v ffmpegidentifies the intended executable and its version is known.- The selected implementation appears in
ffmpeg -encoders. ffmpeg -h encoder=NAMEhas been checked for private options.- A short encode completes and
ffprobereports the expected stream codec. - Temporary output is removed, and no valuable file was overwritten.