ffmpeg-build-script turns a static FFmpeg build into one command
The FFmpeg build script provides an easy way to build a static FFmpeg on OSX and Linux with non-free codecs included.
At a glance
- What is it?
- markus-perl/ffmpeg-build-script compiles a static FFmpeg on macOS and Linux, with the GPL and non-free codecs switched on or off by a single flag. The heavy lifting happens in a workspace directory where the script builds its own toolchain, and the trade-off is a long compile plus a binary you may not be allowed to redistribute.
- Who is it for?
- Adopt ffmpeg-build-script if you need one static FFmpeg binary that carries the codecs your distribution does not ship, and if you can wait through a full source compile on a machine with a C and C++ toolchain. Do not adopt it on Windows, on a distribution its maintainer does not support, or when you need to hand the resulting binary to customers, because a GPL and non-free build is unredistributable by the project's own warning.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 32 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A static FFmpeg with the codecs a package manager leaves out
The problem this solves is narrow and familiar. A system package of FFmpeg on most distributions ships without the encoders and decoders that carry patent or licensing encumbrances, so a pipeline that needs H.264 encoding, MP3 output or AAC through fdk-aac has to hunt for a third party build or assemble the dependencies by hand. The project description says the script builds a static FFmpeg on macOS and Linux with non-free codecs included, and the README presents the same thing as a static build with optional non-free and GPL codecs behind the `--enable-gpl-and-non-free` switch. Static here is the point. The resulting binary carries its own dependencies, so it can be dropped onto a machine that has none of them. That suits CI runners, minimal containers, and laptops where a Homebrew or apt upgrade would otherwise decide which codec set you get.
The script builds its own toolchain inside workspace/
The mechanism that makes the build work on a bare host is visible in the README. The script builds its own `pkg-config`, `nasm`, `yasm`, autotools and `cmake` into `workspace/`, so nothing beyond a C and C++ compiler has to be installed first. On macOS the only stated prerequisite is XCode 14.x or greater, and the README points out that `xcode-select --install` is enough because the full IDE is not required. Homebrew is explicitly not required. On Linux the host must supply `make`, `g++` and `curl`, and the script exits at startup if either of the first two is missing, with the same check applied to the downloader. `tar`, `xz` and `gzip` unpack the source archives, while `diffutils` and `findutils` are needed by the packages' own configure scripts, which the README warns are absent on minimal or UBI images. `file` is used only to report the type of the finished binary.
On macOS the one command the README gives for that prerequisite is:
$ xcode-select --installTwo one-line installers and a switch that changes the license outcome
The fastest path on macOS is a shell process substitution that fetches the installer and runs it in one line. Two variants exist and the difference is legal, not technical. The plain script builds without the GPL and non-free codecs, the other appends `--enable-gpl-and-non-free` to the build. The installer creates an `ffmpeg-build` directory, downloads the source archive of the latest release into it, extracts the archive and runs `build-ffmpeg --build`. To pin a different revision you set `FFMPEG_BUILD_SCRIPT_REF` to a release tag such as `v9.0.3` or to a branch name such as `main`, and the README is explicit that it must be a single tag or branch name, since slashes are rejected. The same switch exists in the cloned workflow, where `./build-ffmpeg --enable-gpl-and-non-free --build` is the GPL and non-free variant of `./build-ffmpeg --build`.
$ git clone https://github.com/markus-perl/ffmpeg-build-script.git
$ cd ffmpeg-build-script
# Without GPL and non-free codecs
$ ./build-ffmpeg --build
# With GPL and non-free codecs
$ ./build-ffmpeg --enable-gpl-and-non-free --buildOptional host tools decide which encoders you silently lose
The Linux prerequisites are described in two blocks per distribution, a required toolchain line and optional lines that buy you features. The word to watch is silently. Without `python3` and `meson` and `ninja` the meson and ninja bootstrap does not happen, so you get no dav1d for AV1 decoding and no LV2 filters, and the build finishes without telling you the encoder set is narrower. Without `cargo` and `rust` there is no rav1e, so AV1 encoding disappears. The README also notes that installing meson and ninja from the package manager is more reliable than the script's own `pip` fallback, which points at a separate section about meson failing in an externally managed environment. The X11 case is the sharpest one. SDL is compiled from source and picks up whatever X11 headers it finds, so a partial header set makes the SDL build fail with `X11/extensions/Xext.h: No such file`, and no X11 at all leaves `ffplay` unable to open a video device.
The Docker path builds inside the image and leaves the host alone
For a machine you would rather not touch, the repository ships container files. The main `Dockerfile` starts from `ubuntu:26.04`, installs a build toolchain with `build-essential`, `curl`, `libva-dev`, `libasound2-dev`, `libpulse-dev`, python, meson and ninja, copies in `build-ffmpeg` and the `src` directory, and then runs the build with `SKIPINSTALL=yes /app/build-ffmpeg --build`. A second stage keeps the runtime lean and installs `libva-drm2`, `libpulse0` and `libasound2t64` so the finished binary can start. The comments in that file explain why those three are not optional. `libpulse0` is required because `--enable-libpulse` links `libpulse.so.0` dynamically, so without it the binary does not start at all, while the missing ALSA runtime costs only the openal indev. The repository root also carries `full-static.dockerfile`, `export.dockerfile` and `cuda-ubuntu.dockerfile` for other arrangements.
macOS hardware acceleration and the features that come with it
On Apple hardware the README routes acceleration through Video Toolbox, and through Vulkan with MoltenVK where it is available. OpenCL is listed as unavailable because Apple discontinued support for it. The prereq table is where the optional cost shows up. `python3`, `meson` and `ninja` from Homebrew bring in dav1d for fast AV1 decoding and the LV2 filters, and `cargo` or `rust` brings in rav1e for AV1 encoding. Apple Silicon is covered, with M1 and newer named explicitly, alongside Intel Macs. The README also notes that Video Toolbox acceleration on macOS arrives with the build, so a machine that lacks the right SDK will simply not have that path available. What the build produces lands in `workspace/bin/`, and `build-ffmpeg` then prompts about installing the binaries into `/usr/local/bin`.
The boundaries: Windows, redistribution and whose bugs you may file
The script is clear about where it stops. Windows is listed as not supported, and the guidance is to use Docker or WSL2 with the Linux instructions instead. The maintainer also asks readers not to file bug reports for systems other than Debian and macOS, saying there is not the time or resources to maintain different systems, and that the script is maintained in spare time. The disclaimer on data privacy is the most consequential line in the README. The script downloads packages with different licenses from various sources that may track usage and are out of the developers' control, and it can create a non-free and unredistributable binary. Downloading and using it means accepting that. The repository itself is MIT licensed, but that license covers the script and says nothing about the binary it produces.
Maintenance pace and the cost of an older revision
The repository is not archived, and the last push was on 2026-09-21. Release tags follow close behind, with v9.0.10 on 2026-09-19, v9.0.9 on 2026-09-07 and v9.0.8 on 2026-08-25, which is a steady cadence of small numbered builds over a single major line. That matters for the `FFMPEG_BUILD_SCRIPT_REF` mechanism, since a pinned tag freezes both the script and the FFmpeg revision it fetches. The README points readers to `CONTRIBUTING.md` for which distributions are actually supported and for what an older release costs, which is the part of the upgrade decision that the main page does not spell out. A `SECURITY.md` and an `AGENTS.md` sit alongside a `CONTRIBUTING.md` at the repository root, and the build badge at the top of the README points at a GitHub Actions build test.
Editorial conclusion
Adopt ffmpeg-build-script if you need one static FFmpeg binary that carries the codecs your distribution does not ship, and if you can wait through a full source compile on a machine with a C and C++ toolchain. Do not adopt it on Windows, on a distribution its maintainer does not support, or when you need to hand the resulting binary to customers, because a GPL and non-free build is unredistributable by the project's own warning. Before you start, check the GPL and non-free licensing page, confirm your platform appears in the support table, and read CONTRIBUTING.md for what an older release costs you.
Frequently asked questions
How do I build FFmpeg with GPL and non-free codecs using ffmpeg-build-script?
On macOS you run the GPL and non-free installer, which fetches the script and passes `--enable-gpl-and-non-free` to the build. From a clone the equivalent is `./build-ffmpeg --enable-gpl-and-non-free --build`.
Do I need Homebrew or Meson to use ffmpeg-build-script on macOS?
Homebrew is not required, because the script builds its own pkg-config, nasm, yasm, autotools and cmake into workspace/. The only stated prerequisite is XCode 14.x or greater, and `xcode-select --install` is enough. Meson and ninja are optional and only buy you dav1d and LV2 filters.
Can I build a specific FFmpeg version with ffmpeg-build-script?
Yes. Set `FFMPEG_BUILD_SCRIPT_REF` to a single release tag such as `v9.0.3` or to a branch name such as `main`. The README states that slashes are rejected, so only one tag or branch name works.
Does ffmpeg-build-script work on Windows?
No. The README lists Windows as not supported and points to Docker or WSL2 with the Linux instructions. The maintainer also asks that bug reports not be filed for systems other than Debian and macOS.
What license does ffmpeg-build-script use?
The repository is MIT licensed, which covers the script. The README warns separately that a GPL and non-free build produces a non-free and unredistributable binary, and points to the FFmpeg legal page.
What happens if the build is missing dav1d or rav1e on Linux?
Without python3, meson and ninja the build silently skips dav1d for AV1 decoding and the LV2 filters, and without cargo or rust it skips rav1e for AV1 encoding. The README describes these as optional tools whose absence quietly narrows the encoder set.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/markus-perl-ffmpeg-build-script)Was this useful?