This project provides a build script for compiling universal (Intel + Apple Silicon) binaries of FFmpeg and FFprobe with rich codec support and static linking.
- Purpose
- Prerequisites
- Usage
- Build Process Overview
- Build Time
- Troubleshooting
- Version Management
- Verifying Universal Binaries
- License Considerations
- Additional Notes
The build-ffmpeg.sh script automates the process of:
- Downloading the latest stable FFmpeg source code
- Compiling essential codec libraries from source
- Building FFmpeg for both arm64 and x86_64 architectures
- Creating universal binaries using
lipo
The resulting binaries are self-contained with no external dependencies, making them suitable for distribution with applications.
First, ensure you have Xcode Command Line Tools installed. This provides essential build tools including git, make, lipo, and compilers:
xcode-select --installTo verify installation:
xcode-select -pThis should output a path like /Library/Developer/CommandLineTools or /Applications/Xcode.app/Contents/Developer.
The script requires Homebrew for installing build dependencies. If not already installed, get it from https://brew.sh.
Install the following build dependencies via Homebrew:
brew install nasm pkg-config cmake autoconf automake libtool yasm meson ninjaRequired system tools (installed via Xcode Command Line Tools):
- git: Version control system (required to clone x264 repository)
- curl: Command-line HTTP client (required to download source archives)
- make: Build automation tool
- lipo: Creates universal (fat) binaries from architecture-specific binaries
- C/C++ compilers: Apple Clang compiler toolchain
Required Homebrew packages:
- nasm: Assembler for x86/x86_64 assembly code (required for many codecs)
- pkg-config: Helper tool for compiling applications and libraries
- cmake: Build system generator (required for some codec libraries)
- autoconf: Generates configuration scripts
- automake: Tool for generating Makefile.in files
- libtool: Generic library support script
- yasm: Modular assembler (alternative to nasm for some components)
- meson: Build system (required for dav1d)
- ninja: Small build system used by meson
The build script will automatically check for the Homebrew packages and offer to install missing ones.
Simply run the script from this directory:
./build-ffmpeg.shThe script caches downloaded source archives in .source-cache/ to avoid re-downloading on subsequent builds.
If you want to force re-download all source archives (e.g., to get updated versions):
./build-ffmpeg.sh --force-downloadIf you encounter issues or want to start completely fresh:
rm -rf build/ output/ .source-cache/
./build-ffmpeg.shThe script will:
- Check for required dependencies
- Download FFmpeg 8.0 and all codec library sources (cached in
.source-cache/) - Build each codec library for both architectures
- Build FFmpeg for both architectures
- Create universal binaries
- Output the final binaries to the
output/directory
The universal binaries will be placed in:
output/ffmpeg- Main FFmpeg binaryoutput/ffprobe- FFprobe utility binary
Build artifacts and intermediate files are stored in the build/ directory. Source archives are cached in .source-cache/ to speed up subsequent builds.
The script performs the following steps:
Each codec library is built twice (once for arm64, once for x86_64) with static linking:
Audio Codecs:
- libogg - Container format for Vorbis and Theora
- libvorbis - Vorbis audio codec
- opus - Opus audio codec (modern, efficient)
- lame - MP3 audio encoder
- fdk-aac - High-quality AAC audio encoder
- speex - Speex audio codec (VoIP/telephony)
- soxr - High-quality audio resampling library
Video Codecs:
- x264 - H.264/AVC video encoder (widely compatible)
- x265 - H.265/HEVC video encoder (high efficiency)
- libvpx - VP8/VP9 video codecs (WebM)
- libaom - AV1 video encoder (next-gen compression)
- dav1d - Fast AV1 video decoder
- libtheora - Theora video codec (open format)
Subtitle & Font Rendering:
- freetype - Font rendering engine
- fontconfig - Font configuration library
- libass - Advanced subtitle renderer (ASS/SSA)
Image & Format Support:
- libwebp - WebP image format
- openjpeg - JPEG 2000 codec
- zimg - High-quality image scaling
- snappy - Fast compression library
FFmpeg is built with comprehensive codec and format support:
Video Encoding & Decoding:
- H.264/AVC (x264) - Industry standard, widely compatible
- H.265/HEVC (x265) - High efficiency video coding
- VP8/VP9 (libvpx) - WebM video codecs
- AV1 encoding (libaom) - Next-generation codec with superior compression
- AV1 decoding (dav1d) - Fast, optimized AV1 decoder
- Theora (libtheora) - Open video format
- VideoToolbox - macOS hardware acceleration for H.264/HEVC
Audio Encoding & Decoding:
- AAC (fdk-aac) - High-quality AAC encoder
- MP3 (lame) - Universal MP3 encoder
- Opus - Modern, low-latency audio codec
- Vorbis - Open audio format
- Speex - Optimized for speech/VoIP
- High-quality audio resampling (soxr)
- AudioToolbox - macOS native audio acceleration
Subtitle Support:
- Advanced SubStation Alpha (ASS/SSA) rendering (libass)
- TrueType/OpenType font rendering (freetype)
- System font integration (fontconfig)
Image & Container Formats:
- WebP images (libwebp)
- JPEG 2000 (openjpeg)
- High-quality image scaling (zimg)
- Snappy compression (libsnappy)
Build Configuration:
- GPL, non-free, and version3 licenses enabled for maximum codec support
- Static linking for all dependencies (no external library requirements)
- Minimum macOS version: 11.0 (Big Sur)
- Universal binary (runs natively on Intel and Apple Silicon)
The lipo tool combines the arm64 and x86_64 binaries into universal binaries that work on both Intel and Apple Silicon Macs.
If the build fails:
- Check that all dependencies are installed:
brew list - Ensure you have Xcode Command Line Tools:
xcode-select --install - Review the error messages for missing dependencies or configuration issues
- Try cleaning the build directory:
rm -rf build/ output/
If downloads fail, you may need to retry the script. The script caches downloaded source archives in the .source-cache/ directory, so re-running will skip already downloaded sources.
The script uses hardcoded default versions for all libraries that are known to work well together. The current defaults are:
Core:
- FFmpeg: 8.0
- x264: latest from git
Video Codecs:
- x265: 3.6
- libvpx: 1.15.2
- libaom: 3.13.1
- dav1d: 1.5.0
- libtheora: 1.2.0
Audio Codecs:
- opus: 1.5.2
- lame: 3.100
- fdk-aac: 2.0.3
- libogg: 1.3.6
- libvorbis: 1.3.7
- speex: 1.2.1
- soxr: 0.1.3
Subtitle & Fonts:
- freetype: 2.14.1
- fontconfig: 2.16.0
- libass: 0.17.4
Image & Format:
- libwebp: 1.6.0
- openjpeg: 2.5.4
- zimg: 3.0.5
- snappy: 1.2.1
You can override any version by setting environment variables before running the script:
# Pin FFmpeg to a specific version
export FFMPEG_VERSION="7.1"
./build-ffmpeg.sh
# Pin multiple libraries
export FFMPEG_VERSION="8.0"
export X265_VERSION="3.5"
export LIBVPX_VERSION="1.13.0"
./build-ffmpeg.shAvailable version variables:
Core:
FFMPEG_VERSION- FFmpeg version (note: x264 always builds from latest git)
Video Codecs:
X265_VERSION- x265 HEVC encoderLIBVPX_VERSION- VP8/VP9 encoderAOM_VERSION- AV1 encoderDAV1D_VERSION- AV1 decoderTHEORA_VERSION- Theora codec
Audio Codecs:
OPUS_VERSION- Opus audio codecLAME_VERSION- MP3 encoderFDK_AAC_VERSION- AAC encoderOGG_VERSION- Ogg containerVORBIS_VERSION- Vorbis audio codecSPEEX_VERSION- Speex codecSOXR_VERSION- Audio resampler
Subtitle & Fonts:
FREETYPE_VERSION- Font renderingFONTCONFIG_VERSION- Font configurationLIBASS_VERSION- Subtitle rendering
Image & Format:
WEBP_VERSION- WebP imagesOPENJPEG_VERSION- JPEG 2000ZIMG_VERSION- Image scalingSNAPPY_VERSION- Compression
After the build completes, you can verify the binaries contain both architectures:
lipo -info output/ffmpeg
lipo -info output/ffprobeExpected output:
Architectures in the fat file: output/ffmpeg are: x86_64 arm64
Architectures in the fat file: output/ffprobe are: x86_64 arm64
The binaries produced by this script include GPL, non-free, and version3 licensed components:
- GPL: x264, x265
- Non-free: fdk-aac (more restrictive licensing)
Ensure your application's licensing is compatible with these requirements before distributing the binaries.
- The build script uses
set -eto exit immediately if any command fails - All codec libraries are compiled with Position Independent Code (PIC) for compatibility
- Downloaded source archives are cached in
.source-cache/between runs to save time - The
build/directory contains extracted sources and compilation artifacts - After successful build, you can safely delete
build/to save disk space (keep.source-cache/to avoid re-downloading)