The build scripts for the libmpv inside mpv_audio_kit. They compile mpv and FFmpeg without video, with a set of patches the package relies on (waveform, loudness scan, audio taps and more), for macOS, iOS, Android, Windows, Linux and the browser.
Everything runs from ./build, a terminal menu where you pick the targets and follow the builds.
git clone https://github.com/ales-drnz/libmpv-scripts
cd libmpv-scripts
./buildOn Windows use build.cmd. You need Go, plus Docker for Linux, Windows and Android, Xcode for Apple targets, and the emsdk for the web.
| Platform | Architectures | File in builds/release/ |
|---|---|---|
| macOS | arm64 and x86_64 (universal) | libmpv_macos.xcframework.zip |
| iOS | arm64 device, arm64 and x86_64 simulator | libmpv_ios.xcframework.zip |
| Android | arm64-v8a, armeabi-v7a, x86_64 | libmpv_android-<abi>.so |
| Linux | x86_64, aarch64 | libmpv_linux-<arch>.so |
| Windows | x86_64, arm64 | libmpv_windows-<arch>.dll |
| Web | wasm32 with threads | libmpv_web.zip |
- API: only
mpv_*, plus themak_pcm_*functions that feed live PCM to themak-pcmprotocol. No video decoders. - Linux and Android: the SONAME is
libmpv_audio_kit.so, so it can live next to another plugin's libmpv. Linux needs glibc 2.31 and ALSA; PipeWire (0.3.57 or later) and PulseAudio are loaded only when installed. - Web: Emscripten 6.0.12 with pthreads. The zip holds
libmpv.mjs,libmpv.wasm, the AudioWorkletmak_webaudio_processor.jsandbuild_web.json. The page must be cross-origin isolated (COOP and COEP), and a server of another origin must send CORS headers. No SMB. - Records: each build leaves
build_<target>.json(license, patches, filters) and its license texts. The Manifest action turns them intomanifest.jsonandlicenses.zip, and fails when the libraries disagree.
Versions are set in scripts/shared/_versions.sh. scripts/shared/_sources.sha256 pins every source by SHA-256 or by commit.
This repository is BSD-3-Clause, except the files NOTICE lists.
The libraries are LGPL-3.0-or-later. An app of any license can link them. In short, the app must:
- ship the license texts (
THIRD_PARTY_LICENSES.txtinlicenses.zipis ready to ship); - say that it uses libmpv under the LGPL;
- provide the source (
README.txtinlicenses.zipnames every source); - let the user replace the library.
Rubber Band is left out. LIBMPV_GPL=1 builds it in, and the library becomes GPL-3.0-or-later. The details, the runtimes of each toolchain and what licenses.zip holds are in doc/licenses.md.
| Tool | Needed for |
|---|---|
| Go | always, it runs ./build |
| Docker | Linux, Windows and Android (Android on macOS builds without it) |
| Xcode | macOS and iOS |
| emsdk 6.0.12, meson and ninja | the web |
The Android NDK is downloaded by the build, you don't need to install it.
| Host | Targets |
|---|---|
| macOS | all of them |
| Linux | all except macOS and iOS |
| Windows | all except macOS, iOS and the web |
Apple targets need a Mac, Linux builds only for the host's own architecture, and the web builds on the host with the emsdk. GitHub Actions builds everything, whatever you have.
Building needs only this repo. Everything it produces lands in builds/: the libraries, libmpv_web.zip and manifest.json in builds/release/, the logs in builds/logs/.
Run ./build. Arrow keys move, Space selects, Enter confirms, Q quits. The keys for each screen are listed at the bottom. There are three screens, switched with B, S and D.
Three tabs:
- Compile: pick platforms and architectures, then press Build. Each build shows its progress, time and warning count, and Enter opens its log.
- Tools: write
manifest.jsonfor the built libraries (Manifest), check them (Verify), and refresh the bundled CA certificates (Update CA). - Docker: see, build or delete the Docker images. The image a build needs is created automatically the first time.
Choose which audio decoders, audio filters and patches go into the build, and in the License tab whether to make the GPL build (see Licenses). Fewer decoders and filters make a smaller library, but a format you remove won't play. Your choices are saved separately from the defaults, and you can reset them at any time.
The main libraries of the build, with their version and license; the complete list for each target, with SPDX ids, is in its THIRD_PARTY_LICENSES.txt. Rubber Band is only in the GPL build.
On a Mac with Xcode:
./build macos # universal xcframework
./build ios # device and simulator xcframework
./build macos-arm64 # one architectureBoth build in Docker. Linux builds natively on Ubuntu 20.04, for the glibc 2.31 floor, so an x86_64 host builds linux-x86_64 and an arm64 host builds linux-aarch64. Windows cross-compiles both architectures from any host:
./build linux-x86_64 # on an x86_64 host
./build windows # x86_64 and arm64On macOS it builds directly on the host, which is the fastest option. Elsewhere it builds in Docker. The Docker tab can force Docker on macOS too.
./build android # all three ABIs
./build android-arm64-v8a # one ABIOn a Linux or macOS host, with the emsdk at 6.0.12 (./emsdk install 6.0.12 && ./emsdk activate 6.0.12) and meson and ninja on the PATH:
EMSDK=path/to/emsdk ./build webIt builds FFmpeg, mpv and their dependencies as WebAssembly archives in builds/work/Web/, then links the module into builds/release/libmpv_web/ and packs it into builds/release/libmpv_web.zip. scripts/build_libmpv_web.sh takes the same variables as the other builds, plus STAGE=link to relink only.
./build accepts targets as arguments and runs them in order, stopping at the first failure:
./build all # everything this host can build, then the manifest
./build macos verify # build macOS, then verify it
./build list # every targetThese variables are passed to the Docker builds:
| Variable | Effect |
|---|---|
JOBS=N |
parallel jobs, all cores by default |
ENABLE_LTO_DEPS=0 |
turn off link-time optimization for the dependencies |
FORCE_DOWNLOAD=1 |
download the sources again |
KEEP_BUILD=1 |
keep the build folders |
WIPE_ALL=1 |
also delete the downloaded sources |
STRICT_SOURCES=1 |
stop on a source that is not pinned, as CI does |
RECORD_SOURCES=<file> |
append the hash of every unpinned source to a file |
LIBMPV_GPL=1 |
the GPL build with Rubber Band (see Licenses) |
To build another version of a dependency, set MPV_VERSION, FFMPEG_VERSION and so on (see scripts/shared/_versions.sh).
Every push to a release/ branch runs .github/workflows/build.yml with STRICT_SOURCES=1:
- it builds all nine libraries and the web module, Apple included;
- it uploads them as the
libmpv-releaseartifact, with the records,licenses.zipandmanifest.json; - it runs
./build verify, the patch tests, a tone with the Linux library in a bare Debian 11, and the web checks in Node and Chrome.
A build stopped by an unpinned source uploads the line to add as an unpinned-sources-<job> artifact.
mpv_audio_kit gets libmpv through a build hook (hook/build.dart). When an app builds, the hook downloads the library for the target from the package's libmpv-rN GitHub release and checks its SHA-256. To point the package at a release, run this in mpv_audio_kit:
scripts/update_libmpv.sh r20 # a published release
scripts/update_libmpv.sh r20 path/to/manifest.json # before publishing itIt writes the release into lib/src/internals/libmpv_release.dart and the hashes from manifest.json into the hook, installs the web module of libmpv_web.zip in web/ once its hashes and ABI check, and copies the manifest to tool/codegen. Before publishing, libmpv_web.zip must sit beside manifest.json, as it does in the Build's libmpv-release artifact.
To try a local build in an app, point the hook at the file in the app's pubspec.yaml. The file is bundled as it is, without a checksum:
hooks:
user_defines:
mpv_audio_kit:
libmpv: path/to/libmpv_linux-x86_64.soThe Manifest action in the Tools tab writes builds/release/manifest.json for a local build, ready for update_libmpv.sh.
./build verify checks every library in builds/release/: architecture, API, patched properties, decoders and filters, no video code, dependencies and license. Where the host can load a library, it calls into it.
The patches, the network protocols and the web module have tests of their own. Their commands and requirements are in verify/README.md.
- Build all nine libraries and the web module, usually by pushing a
release/branch (see 3.6). - Create the
libmpv-rNrelease onmpv_audio_kitand upload the libraries,libmpv_web.zip,licenses.zipandmanifest.json. - In
mpv_audio_kit, runscripts/update_libmpv.sh rN.
./build is a small Go program (Bubble Tea) that runs the shell scripts in scripts/, one per platform. Apple targets build with Xcode on the host, the web with the emsdk on the host. Linux, Windows and Android build inside a Docker image from docker/Dockerfile, which has one stage per platform, so you only keep the toolchains you use.
Each build downloads the pinned sources, applies the patches in patches/ to mpv and FFmpeg, compiles only the audio parts, and strips the library down to the mpv_* and mak_pcm_* API. Every patch finds its place by exact text and stops the build if upstream has changed underneath it.
- "Go not found": install Go and run again.
- A Linux, Windows or Android build fails right away: Docker isn't running.
- macOS and iOS are greyed out: they need a Mac with Xcode. GitHub Actions can build them instead.
- The first Docker build is slow: it is building the image, later builds reuse it.
- "Unpinned source": a download is not in
scripts/shared/_sources.sha256. Add the line the error prints, or build withoutSTRICT_SOURCES=1and collect the lines withRECORD_SOURCES. - "the Linux build is native-only": Linux builds only for the host's architecture. Use a host of the other architecture, or GitHub Actions.
- Android in Docker is slow on Apple Silicon: the NDK is x86_64 only. Build on the host (the default), or turn on Rosetta in Docker Desktop.
The build pipeline, the Go TUI and the patches for mpv and FFmpeg were written with Claude Code.
Developed by Alessandro Di Ronza
