32blogby StudioMitsu
Archive7 min read

Building a Redistributable FFmpeg on Windows with MSYS2

Step-by-step guide to building a legally redistributable FFmpeg binary on Windows. Covers MSYS2 setup, configure options for LGPL compliance, and troubleshooting common build errors.

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.

ModeHow to enableCommercial redistribution
LGPL v2.1Default (no special flags)Yes, with conditions
GPL v2/v3--enable-gplMust open-source your product or comply with GPL
Non-free--enable-nonfreeCannot 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.1 license 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

  1. Download the installer from https://www.msys2.org/
  2. Run it with default settings (installs to C:\msys64 by default)
  3. After installation, open MSYS2 UCRT64 and update the package database:
bash
pacman -Syu

Close MSYS2 when prompted, reopen UCRT64, and complete the update:

bash
pacman -Su

Installing build tools

bash
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:

bash
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:

bash
export PATH=/ucrt64/bin:$PATH

Add this to ~/.bashrc so it persists across sessions:

bash
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

bash
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:

bash
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.

bash
./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

OptionPurpose
--disable-gplExclude GPL-licensed components; build remains LGPL
--disable-nonfreeExclude non-redistributable closed-source components
--enable-sharedBuild as shared DLLs (required for LGPL compliance)
--disable-staticDon't build static libraries
--disable-libx264Exclude H.264 encoder (patent-encumbered)
--disable-libx265Exclude H.265 encoder (patent-encumbered)
--disable-libmp3lameExclude MP3 encoder
--disable-libfdk-aacExclude AAC encoder
--disable-encodersStart 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):

bash
# 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

bash
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:

bash
# Clean and retry
make clean
./configure [same options]
make -j$(nproc)

# If parallel build is causing issues, try single-threaded:
make

Installing

bash
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

bash
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

bash
# 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:

bash
export PATH=$HOME/bin:$PATH

Or specify a path when configuring:

bash
./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:

bash
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:

bash
# 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:

bash
tail -100 ffbuild/config.log

Redistribution Checklist

Before shipping your FFmpeg build to users:

  • ffmpeg -version shows --disable-gpl and --disable-nonfree in configuration
  • No patent-encumbered codecs are enabled (verify with ffmpeg -encoders | grep x264)
  • COPYING.LGPLv2.1 is 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:

  1. Set up MSYS2 as the build environment and install the required toolchain
  2. Clone the FFmpeg source with git clone
  3. Run ./configure --disable-gpl --disable-nonfree --enable-shared with your specific codec requirements
  4. Build with make -j$(nproc), verify with ffmpeg -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.