Skip to content

Repository files navigation

Owncast FFmpeg builds

The FFmpeg build script provides an easy way to build a static build of FFmpeg for Linux. Builds currently track the FFmpeg 9.0 release branch.

Background

The Owncast project offers a quick installer script as an option to install the live video streaming server. A part of this script is determining if FFmpeg is already downloaded on the target machine. If not, it will download a static build of FFmpeg for Linux for either amd64 or arm64.

However, as of recent versions of Debian that no longer supports old versions of glib, the static builds that this script has relied on to download are no longer compatible and will segfault. Additionally, any alternative static builds that are available are outdated or not maintained.

To solve this issue, it is necessary to create our own FFmpeg builds that are compatible with the latest Debian releases. These builds are based on the FFmpeg source code and are compiled with the necessary dependencies to ensure compatibility with modern systems.

These builds are available for download and can be used as a drop-in replacement for the existing FFmpeg linux builds used by the Owncast installer script.

Original work

This repository is a fork of ffmpeg-build-script by markus-perl.

Run

  1. Install Earthly build tools.
  2. Install QEMU for cross-compilation.
  3. run earthly --ci +multi-platform to build for amd64 and arm64 architectures.
  4. Wait.
  5. The build archives will be available in the builds directory.

+multi-platform builds six artifacts at once, and on a single-architecture machine half of them run under emulation, so it needs a lot of free disk. It is intended for the release runner. On a developer machine prefer building one target at a time for your own architecture, for example earthly --output +build or earthly --output +build-vaapi.

On Docker Desktop the VM's virtual disk is sparse and its size limit is independent of the host's real free space. When the host runs out, the guest still believes it has room and the build fails partway through with error committing ...: read-only file system rather than a clear out-of-space error. If you see that, free space on the host and reclaim the VM image (earthly prune --reset, then docker run --privileged --pid=host docker/desktop-reclaim-space) before retrying.

Verifying the builds

Every published release is tested automatically by the Test release assets workflow. For each release asset it verifies linkage (static builds must have no dynamic interpreter), checks that every capability Owncast's transcoder requires is compiled in, runs a short encode, and then streams through a real Owncast server end to end. A separate job runs each Linux binary inside a matrix of distribution containers, from Debian 11 and Ubuntu 20.04 up through Debian 13, Fedora, and Alpine. A weekly soak workflow streams through Owncast for 30 minutes to catch leaks and mid-stream crashes.

The same checks can be run locally:

  • ./test-builds.sh runs the distro container matrix against the latest release. Use --arch, --tag, and --linux-only to narrow it.
  • ./e2e-owncast.sh <path-to-ffmpeg> [seconds] downloads the latest Owncast release, makes it use the given ffmpeg binary, pushes a live test stream in, and verifies HLS output. Durations over two minutes switch to soak mode.
  • ./parity-check.sh <baseline|-> <candidate> [vaapi] verifies a binary has everything Owncast's transcoder needs and optionally diffs its full capability set against another build, such as the one the installer ships today.

VAAPI Support

There are two builds for each Linux architecture: one portable static build without VAAPI, and one dynamically linked VAAPI build. The VAAPI build is only appropriate on a host with compatible VAAPI runtime libraries, drivers, and /dev/dri hardware. A host without VAAPI support must use the static build.

The VAAPI build is based on Ubuntu 22.04 and currently requires glibc 2.35 or newer. This covers Ubuntu 22.04 and Debian 12, subject to the host's VAAPI driver stack. It remains dynamically linked because VAAPI drivers are loaded at runtime. VAAPI hardware encoding is not exercised in the build containers because they do not provide a GPU.

Thread stack size on static builds

The static builds are linked against musl with -Wl,-z,stack-size=8388608. This is load bearing, not cosmetic. FFmpeg's command line tool demuxes, decodes, encodes and muxes on separate threads, and musl takes its default thread stack size from the ELF PT_GNU_STACK header, falling back to 128KB when the linker leaves it unset. glibc reserves 8MB instead. FFmpeg 9's mpegts demuxer needs more than 128KB, so without this flag the static binaries segfault on any mpegts input, including simply reading back an HLS segment they just wrote, while encoding continues to look fine. If you change the link flags, keep a generous stack size and make sure the mpegts read-back check still passes.

Non-free codecs

While it's possible to create a build that includes non-free codecs, it's not recommended due to potential legal issues. If you find this binary is shipping a non-free codec, or any other please licensing incompatibility please open an issue, or better yet, a PR to improve this build so everyone can benefit from it.

Possible TODOs

  • Add support for more ARM architectures (e.g. armhf, etc).
  • Create macOS binaries as well while we're at it, though this is not necessary since the existing macOS FFmpeg binaries are working fine.
  • Allow people to manually run the build script with custom options to enable NVIDIA NVENC support. We can't ship this, but people can build it themselves.
  • Enable cross-compilation without emulation.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages