The FFmpeg binaries available for download from gyan.dev and other sources are convenient, but they include codecs covered by patents and licenses that may not permit redistribution in commercial software. If you're shipping FFmpeg as part of a product, embedding it in an application, or distributing it as part of a service, you need a build you control.
This guide walks through building FFmpeg on Windows using MSYS2, configured to be fully redistributable under the LGPL license, with patented codecs excluded.
What you'll learn
- FFmpeg's license structure and what "redistributable" means
- Setting up MSYS2 as a Windows build environment
- Configuring FFmpeg to exclude GPL and patent-encumbered codecs
- Running the build and verifying the result
- Troubleshooting common build failures
Understanding FFmpeg's License Structure
FFmpeg can be built in three license modes. Understanding the difference is critical before you ship anything.
| Mode | How to enable | Commercial redistribution |
|---|---|---|
| LGPL v2.1 | Default (no special flags) | Yes, with conditions |
| GPL v2/v3 | --enable-gpl | Must open-source your product or comply with GPL |
| Non-free | --enable-nonfree | Cannot redistribute at all |
For commercial redistribution, you need an LGPL build with --disable-gpl --disable-nonfree, and you need to exclude codecs covered by third-party patents (H.264, H.265, MP3, AAC, and others).
LGPL compliance requires:
- Distributing FFmpeg as a shared library (DLL), not statically linked into your binary
- Including the
COPYING.LGPLv2.1license file - Noting in documentation that your product uses FFmpeg under LGPL
Setting Up MSYS2 as a Build Environment
Windows doesn't have a native build toolchain suitable for FFmpeg. MSYS2 provides a Linux-like environment with GCC, Make, and package management.
Installing MSYS2
- Download the installer from https://www.msys2.org/
- Run it with default settings (installs to
C:\msys64by default) - After installation, open MSYS2 UCRT64 and update the package database:
pacman -Syu
Close MSYS2 when prompted, reopen UCRT64, and complete the update:
pacman -Su
Installing build tools
pacman -S \
mingw-w64-ucrt-x86_64-toolchain \
base-devel \
git \
make \
nasm \
yasm \
pkg-config \
mingw-w64-ucrt-x86_64-cmake
When asked whether to proceed, press Y and Enter.
If you get "could not resolve host" errors:
This is a DNS or network issue. Try a different network, or update MSYS2's mirror list:
nano /etc/pacman.d/mirrorlist.ucrt64
Move a faster or more reliable mirror to the top of the file.
Configure environment variables
Add the UCRT64 bin directory to PATH:
export PATH=/ucrt64/bin:$PATH
Add this to ~/.bashrc so it persists across sessions:
echo 'export PATH=/ucrt64/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
Without this, configure may fail with "nasm not found" or similar errors.
Getting the FFmpeg Source Code
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
If you get SSL certificate errors:
Use the per-command option to avoid permanently modifying your global git config:
git -c http.sslVerify=false clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
Avoid git config --global http.sslVerify false — it disables SSL verification for all git operations system-wide, which is a security risk.
Building Redistributable FFmpeg
Choosing configure options
This is the most important step. The options you pass to ./configure determine which codecs are included and what license applies.
./configure \
--disable-gpl \
--disable-nonfree \
--enable-shared \
--disable-static \
--disable-libx264 \
--disable-libx265 \
--disable-libmp3lame \
--disable-libvorbis \
--disable-libopus \
--disable-libfdk-aac \
--disable-libass \
--disable-libvpx \
--disable-encoders \
--disable-decoders \
--disable-muxers \
--disable-demuxers \
--disable-parsers \
--disable-bsfs \
--disable-filters \
--enable-encoder=png \
--enable-encoder=rawvideo \
--enable-decoder=png \
--enable-decoder=rawvideo \
--enable-muxer=image2 \
--enable-muxer=rawvideo \
--enable-demuxer=image2 \
--enable-demuxer=rawvideo
This is a minimal "PNG and raw video only" configuration. Add --enable-encoder=xxx options for the specific codecs your use case requires.
What each option does
| Option | Purpose |
|---|---|
--disable-gpl | Exclude GPL-licensed components; build remains LGPL |
--disable-nonfree | Exclude non-redistributable closed-source components |
--enable-shared | Build as shared DLLs (required for LGPL compliance) |
--disable-static | Don't build static libraries |
--disable-libx264 | Exclude H.264 encoder (patent-encumbered) |
--disable-libx265 | Exclude H.265 encoder (patent-encumbered) |
--disable-libmp3lame | Exclude MP3 encoder |
--disable-libfdk-aac | Exclude AAC encoder |
--disable-encoders | Start with all encoders disabled; selectively enable what you need |
Patent-free codecs you can optionally add to an LGPL build:
The configure above is a minimal "PNG and raw video only" baseline. To add patent-free codecs, replace the corresponding --disable-xxx line with --enable-xxx (and install the required library first):
# These are generally safe for LGPL redistribution:
--enable-libvpx # VP8/VP9 (requires libvpx to be installed)
--enable-libaom # AV1 (requires libaom)
--enable-libopus # Opus audio codec (replace --disable-libopus)
--enable-libvorbis # Ogg Vorbis audio codec (replace --disable-libvorbis)
Running the build
make -j$(nproc)
-j$(nproc) enables parallel compilation using all available CPU cores. On a 4-core machine, the build takes roughly 5–10 minutes.
If the build fails midway:
# Clean and retry
make clean
./configure [same options]
make -j$(nproc)
# If parallel build is causing issues, try single-threaded:
make
Installing
make install
No sudo required in MSYS2 for the default installation path. To install to a custom location, add --prefix=/path/to/install to the ./configure command.
Verifying the Build
Check version and configuration
ffmpeg -version
Expected output:
ffmpeg version N-XXXXXX Copyright (c) 2000-2025 the FFmpeg developers
built with gcc XX.X.X
configuration: --disable-gpl --disable-nonfree --enable-shared ...
libavutil XX.YY.ZZ / XX.YY.ZZ
libavcodec XX.YY.ZZ / XX.YY.ZZ
Confirm the configuration: line contains --disable-gpl and --disable-nonfree.
Functional test
# Generate a test PNG using FFmpeg's built-in test source
ffmpeg -f lavfi -i testsrc=size=320x240:rate=1 -vframes 1 test_input.png
# Resize it
ffmpeg -i test_input.png -vf scale=160:120 test_output.png
A successful run produces output like:
Output #0, image2, to 'test_output.png':
Stream #0:0: Video: png, rgb24, 160x120
Troubleshooting
command not found: ffmpeg
FFmpeg's install location isn't in PATH. Either add it:
export PATH=$HOME/bin:$PATH
Or specify a path when configuring:
./configure --prefix=$HOME/ffmpeg-build ...
export PATH=$HOME/ffmpeg-build/bin:$PATH
cannot find libXXXX.dll at runtime
FFmpeg was built as shared libraries. The DLLs must be in the same directory as ffmpeg.exe or in a directory in PATH. Check what's missing:
ldd ffmpeg.exe
Copy any "not found" DLLs from /ucrt64/bin/ to the same directory as your FFmpeg binary.
Unknown encoder 'libx264'
Expected — you disabled libx264 deliberately. Use a patent-free alternative:
# VP9 (patent-free alternative)
ffmpeg -i input.png -c:v libvpx-vp9 output.webm
Error 1 during make
Look at the error message just above it for the actual cause. If it mentions a missing library, install it with pacman -S. If it's a configure option issue, check ffbuild/config.log for details:
tail -100 ffbuild/config.log
Redistribution Checklist
Before shipping your FFmpeg build to users:
ffmpeg -versionshows--disable-gpland--disable-nonfreein configuration- No patent-encumbered codecs are enabled (verify with
ffmpeg -encoders | grep x264) COPYING.LGPLv2.1is included in your distribution- Documentation states that your product uses FFmpeg under the LGPL
- FFmpeg is distributed as DLLs (shared library), not statically linked
Summary
Building a redistributable FFmpeg on Windows involves four main steps:
- Set up MSYS2 as the build environment and install the required toolchain
- Clone the FFmpeg source with
git clone - Run
./configure --disable-gpl --disable-nonfree --enable-sharedwith your specific codec requirements - Build with
make -j$(nproc), verify withffmpeg -version
The specific codecs you enable depend entirely on your use case. The key constraints are: exclude GPLv2+ licensed components, exclude non-free components, and exclude patent-encumbered codecs (H.264, H.265, MP3, AAC) unless you have a license for them.
For the equivalent Linux build procedure, see the companion article on building redistributable FFmpeg for Linux.