Skip to content

About

This repo builds the audio engine behind the mpv_audio_kit Flutter package: audio-only build of mpv for every platform: macOS, iOS, Android, Windows and Linux. You drive everything from one command, ./build, a friendly menu where you pick what to build and watch it happen.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Repository files navigation

libmpv-scripts

Audio-only libmpv, built for every platform.

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.


Quick start

git clone https://github.com/ales-drnz/libmpv-scripts
cd libmpv-scripts
./build

On Windows use build.cmd. You need Go, plus Docker for Linux, Windows and Android, Xcode for Apple targets, and the emsdk for the web.


What it produces

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 the mak_pcm_* functions that feed live PCM to the mak-pcm protocol. 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 AudioWorklet mak_webaudio_processor.js and build_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 into manifest.json and licenses.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.


Licenses

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.txt in licenses.zip is ready to ship);
  • say that it uses libmpv under the LGPL;
  • provide the source (README.txt in licenses.zip names 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.


Visuals


Guide

1. Requirements

1.1 Tools

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.

1.2 What each host can build

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.

1.3 Folder layout

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


2. The menu

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.

2.1 Build

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.json for 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.

2.2 Settings

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.

2.3 Dependencies

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.


3. Building

3.1 macOS and iOS

On a Mac with Xcode:

./build macos          # universal xcframework
./build ios            # device and simulator xcframework
./build macos-arm64    # one architecture

3.2 Linux and Windows

Both 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 arm64

3.3 Android

On 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 ABI

3.4 Web

On 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 web

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

3.5 From the command line

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

These 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).

3.6 On GitHub Actions

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-release artifact, with the records, licenses.zip and manifest.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.


4. Using the binaries

4.1 Installing into mpv_audio_kit

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 it

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

4.2 Local or downloaded libraries

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

The Manifest action in the Tools tab writes builds/release/manifest.json for a local build, ready for update_libmpv.sh.

4.3 Verifying

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

4.4 Publishing a release

  1. Build all nine libraries and the web module, usually by pushing a release/ branch (see 3.6).
  2. Create the libmpv-rN release on mpv_audio_kit and upload the libraries, libmpv_web.zip, licenses.zip and manifest.json.
  3. In mpv_audio_kit, run scripts/update_libmpv.sh rN.

5. How it works

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


Troubleshooting

  • "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 without STRICT_SOURCES=1 and collect the lines with RECORD_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.

Project background

The build pipeline, the Go TUI and the patches for mpv and FFmpeg were written with Claude Code.


Developed by Alessandro Di Ronza

About

This repo builds the audio engine behind the mpv_audio_kit Flutter package: audio-only build of mpv for every platform: macOS, iOS, Android, Windows and Linux. You drive everything from one command, ./build, a friendly menu where you pick what to build and watch it happen.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages