FFMpeg
Free, open source software for transcoding
TOC
- Builds
- Filters
- Libx264
- Libx265
- NvEnc
- Sequence to video
- Getting info and help
- Colorspace conversion
- FFprobe
- Progress
- Frameserver
Builds
Static build
Everything — libx264, libaom, libsvtav1, all ~150MB of codec libraries — gets compiled into the ffmpeg.exe binaries themselves.
- ✅ Zero dependency hell. Drop it in a folder, add to PATH, done. No DLLs to lose, no version mismatches.
- ✅ Portable. You can throw the folder on a USB stick or copy it to a render node machine and it just works.
- ✅ No conflicts. Windows has this habit of having three different
avcodec-63.dlls scattered around from various apps, and whichever one your binary finds first wins. Static builds are immune to that lottery. - ❌ Bigger download (~150–190MB vs ~50–80MB). Disk space in 2026 — you'll survive.
- ❌ No lib-sharing between ffmpeg/ffprobe — each binary carries the full library set.
Shared build
Libraries live in separate DLLs next to the binaries.
- ✅ Smaller total footprint, and slightly less RAM if you run ffmpeg/ffprobe/ffplay concurrently on the same input.
- ✅ Relevant mainly for developers — if you're writing code against the FFmpeg libraries and want to update or replace just
avcodec.dllwithout rebuilding. - ❌ Any one DLL goes missing/mismatched and ffmpeg refuses to launch.
- ❌ Copy to another machine without the DLLs? Dead in the water.
Versioning
Build version via -version parameter give different output for different type of release
| What you see | What it actually is |
|---|---|
6.1.1 | Tagged release, built from the release tarball (stable release) |
6.1.1-3ubuntu1 | Tagged release + distro patch suffix (still stable) |
7:5.1.7-0+deb12u1 | Debian packaging, complete with epoch prefix |
N-127617-g94cba3150c-20261017 | Untagged master build. N = NEW. Then Number of commits since the last official release tag. Trailing date digits are the builder's stamp of a date |
7.0.1-5-gabc1234 | Built AFTER a tag on a release branch, not at it. Short git hash identifying the exact commit. |
Finding the release number for the untagged build is more difficult. You can match "g94cba3150c" against the master commits
Filters
filters in a chain are separated by commas ","
chains by a semicolon ";"
if an input or output is not specified it is assumed to come from the preceding or sent to the following item in the chain.
"filter1=setting1=value1:setting2=value2,filter2=setting1=value1:setting2=value2"
Scale
The FFmpeg rescaler provides a high-level interface to the libswscale library image conversion utilities. In particular it allows one to perform image rescaling and pixel format conversion.
https://trac.ffmpeg.org/wiki/Scaling https://ffmpeg.org/ffmpeg-scaler.html
iw is input width
-1 and -2 to preserve ratio
ffmpeg -i input -vf "scale=iw/2:-1" output
Libx264
https://trac.ffmpeg.org/wiki/Encode/H.264
To list all possible internal presets and tunes:
"%ffdev%\ffmpeg" -hide_banner -f lavfi -i nullsrc "-c:v libx264" -preset help -f mp4 -y NUL
Rate control
There are two rate control modes that are usually suggested for general use:
CRF
The range of the CRF scale is 0–51, where 0 is lossless (for 8 bit only, for 10 bit use -qp 0), 23 is the default, and 51 is worst quality possible. A lower value generally leads to higher quality, and a subjectively sane range is 17–28. Consider 17 or 18 to be visually lossless or nearly so; it should look the same or nearly the same as the input but it isn't technically lossless.
The range is exponential, so increasing the CRF value +6 results in roughly half the bitrate / file size, while -6 leads to roughly twice the bitrate.
Will two-pass provide a better quality than CRF?
No, though it does allow you to target a file size more accurately.
Two-pass ABR
For two-pass, you need to run ffmpeg twice, with almost the same settings, except for:
- In pass 1 and 2, use the
-pass 1and-pass 2options, respectively. - In pass 1, output to a null file descriptor, not an actual file. (This will generate a logfile that ffmpeg needs for the second pass.)
- In pass 1, you may leave audio out by specifying
-an
When using option
-an, you may eventually get a segfault or a broken file. If so, remove option-anand replace by-vsync cfrto the first pass.
Presets
To see a list of current presets with -preset help
If you target a certain file size or constant bit rate, you will achieve better quality with a slower preset. Similarly, for constant quality encoding, you will simply save bitrate by choosing a slower preset.
Libx265
H.265/HEVC
NvEnc
Source
Using_FFmpeg_with_NVIDIA_GPU_Hardware_Acceleration.pdf
FFmpeg wiki
REM h264_nvenc help
"%ffdev%\ffmpeg" -hide_banner -h encoder=h264_nvenc
Sequence to video
Many high-end video pipelines work with DPX, EXR or TIFF sequences. To transform these sequences into video files, the easiest way is to specify the first file in the sequence as the input and then use -framerate to set the input frame rate and -r to set the output frame rate:
ffmpeg -i input_0001.dpx -framerate 59.94 -c:v libx264 -b:v 30M -r 29.97 -an output.mp4
Palettegen
and Paletteuse, dithering options
https://ffmpeg.org/ffmpeg-filters.html#palettegen-1
https://engineering.giphy.com/how-to-make-gifs-with-ffmpeg
Getting info and help
For filters, codecs, muxers, etc
Encoders
video
rem Get encoder help
"%ffdev%\ffmpeg" -hide_banner -h encoder=exr
rem Get encoder help
"%ffdev%\ffmpeg" -hide_banner -h encoder=tiff
rem Get encoder help
"%ffdev%\ffmpeg" -hide_banner -h encoder=aac
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=h264_nvenc
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=hevc_nvenc
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=libvpx-vp9
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=mjpeg
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=png
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=libx264
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=libx265
audio
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=aac
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=ac3
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=pcm_s16le
Pixel formats
rem Get all pixel formats
"%ffdev%\ffmpeg" -hide_banner -pix_fmts
rem Get pixel formats for encoder
"%ffdev%\ffmpeg" -hide_banner -h encoder=libx264 | findstr "pixel"
Muxers
rem Get pixel muxer's private options
"%ffdev%\ffmpeg" -hide_banner -h muxer=apng
rem Get pixel muxer's private options
"%ffdev%\ffmpeg" -hide_banner -h muxer=mjpeg
Colorspace conversion
https://trac.ffmpeg.org/wiki/colorspace
FFprobe
Count keyframes
set "file=D:\Keerah\Projects1\stf tests\thecolour05.mov"
"%ffdev%\ffprobe.exe" -hide_banner -of compact=p=0:nk=1 -select_streams "v:0" -count_frames -show_entries stream=nb_read_frames -skip_frame nokey -v 0 -i "%file%"
Show streams
set "file=D:\Keerah\Projects1\stf tests\Blossom1.%%04d.puzzleMatte.exr"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_streams -show_format -sexagesimal -i "%file%"
set "file=D:\Keerah\Projects1\stf tests\thecolour05.mov"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_streams -show_format -sexagesimal -i "%file%"
set "file=D:\Keerah\Projects1\stf tests\Senses_preview.mp4"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_streams -show_format -sexagesimal -i "%file%"
set "file=D:\Keerah\Projects1\stf tests\tic201_%%04d.tif"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_streams -show_format -sexagesimal -i "%file%"
set "file=D:\Keerah\Projects1\stf tests\Senses_preview.webm"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_streams -show_format -sexagesimal -i "%file%"
set "file=F:\Keerah\Projects2\2012\Karaban - Goodavto\passat_updated.mp4"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_streams -show_format -sexagesimal -i "%file%"
Formatting output
set "file=D:\Keerah\Projects1\stf tests\thecolour05.mov"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_entries "format=format_name" -of "default=noprint_wrappers=1:nokey=1" -sexagesimal -i "%file%"
rem also:
-of flat
-of compact=p=0
-of json
-of xml
Get particular stream data
set "file=D:\Keerah\Projects1\stf tests\thecolour05.mov"
"%ffdev%\ffprobe.exe" -v error -hide_banner -show_entries "stream=width,height,duration,codec_name,pix_fmt,color_space,color_primaries,color_transfer,color_range,avg_frame_rate" -select_streams "v:0" -sexagesimal -i "%file%"
Progress
Stats
Simple version using stats parameters
ffmpeg -v warning -hide_banner -stats ${your_params}
Write to file
FFmpeg in a separate process
-progress %TEMP%\progr.txt
https://blog.programster.org/ffmpeg-output-progress-to-file
Port watcher
FFmpeg in a separate process
WATCHER_PORT=9998
DURATION= $(ffprobe -select_streams v:0 -show_entries "stream=duration" \
-of compact $INPUT_FILE | sed 's!.*=\(.*\)!\1!g')
nc -l $WATCHER_PORT | while read; do
sed -n 's/out_time=\(.*\)/\1 of $DURATION/p')
done &
ffmpeg -y -i $INPUT_FILE -progress localhost:$WATCHER_PORT $OUTPUT_ARGS