FFmpeg is the tool I reach for when I need to transcode, remux, filter, inspect, stream, or generate audio and video. Ubuntu’s packaged build is the right choice for most machines, but a source build is useful when I need a newer release or an exact set of external libraries.
This guide builds FFmpeg 9.0.1 on Ubuntu 24.04 LTS (Noble). It installs into a versioned directory under the current user’s home directory. That choice avoids overwriting /usr/bin/ffmpeg, avoids an untracked sudo make install into /usr/local, and makes it possible to test a new build before changing PATH.
The package names and release links were checked against the official Ubuntu and FFmpeg sources on September 1, 2026. This is a broad, practical build, not literally “every FFmpeg feature”: FFmpeg has many optional libraries, mutually incompatible licensing choices, and hardware-specific SDKs.
Table of Contents
First decide whether you need a source build
Check what is already installed:
if command -v ffmpeg >/dev/null 2>&1; then
command -v ffmpeg
ffmpeg -version | sed -n '1p'
fi
If Ubuntu’s build has the codecs and filters you need, use the maintained package and stop here:
sudo apt update
sudo apt install ffmpeg
An Ubuntu package receives updates through APT. A source build does not. Once you choose the source route, you are responsible for watching new FFmpeg releases and rebuilding for important fixes.
What this build enables
The configuration below adds common CPU codecs and text/audio features:
- H.264 and HEVC encoding through x264 and x265
- VP8 and VP9 through libvpx
- AV1 decoding through dav1d
- MP3, Opus, Vorbis, and Theora support
- ASS subtitles and
drawtext-related font shaping - SoX Resampler and HTTPS through GnuTLS
FFmpeg’s native AAC encoder remains enabled, so this build does not require Fraunhofer FDK AAC or --enable-nonfree. Hardware encoders are deliberately outside the base recipe because their requirements depend on the GPU, driver, headers, and FFmpeg release.
Step 1: Install the exact build dependencies
The following package names exist in the Ubuntu 24.04 official package index. Some external codec development packages are in Ubuntu’s universe component, so make sure your official Noble repositories are enabled.
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
gpg \
libass-dev \
libdav1d-dev \
libfreetype-dev \
libfribidi-dev \
libgnutls28-dev \
libharfbuzz-dev \
libmp3lame-dev \
libopus-dev \
libsoxr-dev \
libtheora-dev \
libvorbis-dev \
libvpx-dev \
libx264-dev \
libx265-dev \
nasm \
pkg-config \
xz-utils \
zlib1g-dev
If APT cannot locate a package, do not paste in an unrelated PPA. Confirm the Ubuntu release and configured repositories first:
. /etc/os-release
printf '%s %s\n' "$NAME" "$VERSION_ID"
apt-cache policy libx264-dev libx265-dev libass-dev
These instructions target Ubuntu 24.04 specifically. Recheck package names against the official index before applying the recipe to another Ubuntu release.
Step 2: Download and verify the signed source release
Use variables for the version, work directory, and installation prefix. Keep an old or modified source tree separate rather than extracting over it.
FFMPEG_VERSION='9.0.1'
FFMPEG_WORK_DIR="$HOME/src/ffmpeg-$FFMPEG_VERSION-build"
FFMPEG_PREFIX="$HOME/.local/ffmpeg-$FFMPEG_VERSION"
mkdir -p "$FFMPEG_WORK_DIR"
cd "$FFMPEG_WORK_DIR"
curl --fail --location \
--output "ffmpeg-$FFMPEG_VERSION.tar.xz" \
"https://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.xz"
curl --fail --location \
--output "ffmpeg-$FFMPEG_VERSION.tar.xz.asc" \
"https://ffmpeg.org/releases/ffmpeg-$FFMPEG_VERSION.tar.xz.asc"
curl --fail --location \
--output ffmpeg-devel.asc \
https://ffmpeg.org/ffmpeg-devel.asc
Verify the signing key fingerprint as well as the tarball signature. A temporary GnuPG home keeps this check separate from the user’s normal keyring:
FFMPEG_GPG_HOME="$(mktemp -d)"
chmod 700 "$FFMPEG_GPG_HOME"
gpg --homedir "$FFMPEG_GPG_HOME" --import ffmpeg-devel.asc
gpg --homedir "$FFMPEG_GPG_HOME" --with-colons --fingerprint \
| awk -F: '$1 == "fpr" {print $10}' \
| grep -Fx 'FCF986EA15E6E293A5644F10B4322F04D67658D8'
gpg --homedir "$FFMPEG_GPG_HOME" --verify \
"ffmpeg-$FFMPEG_VERSION.tar.xz.asc" \
"ffmpeg-$FFMPEG_VERSION.tar.xz"
Do not continue if the fingerprint comparison or signature verification fails. After both succeed, extract the archive:
tar -xf "ffmpeg-$FFMPEG_VERSION.tar.xz"
cd "$FFMPEG_WORK_DIR/ffmpeg-$FFMPEG_VERSION"
Step 3: Configure a versioned, user-local build
Run the release’s own configure script:
./configure \
--prefix="$FFMPEG_PREFIX" \
--disable-doc \
--enable-gpl \
--enable-gnutls \
--enable-libass \
--enable-libdav1d \
--enable-libfreetype \
--enable-libfribidi \
--enable-libharfbuzz \
--enable-libmp3lame \
--enable-libopus \
--enable-libsoxr \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265
This intentionally does not use --enable-shared. The installed FFmpeg programs still use Ubuntu’s external codec libraries, but the recipe does not add custom FFmpeg shared libraries to a system loader path and does not need sudo ldconfig.
Before adding another flag, check the configure help belonging to the source release you downloaded:
./configure --help
If configure fails, the useful evidence is normally near the end of ffbuild/config.log. For one expected library, also ask pkg-config directly:
tail -n 80 ffbuild/config.log
pkg-config --modversion x264
pkg-config --modversion libass
Do not fix a missing NASM message with --disable-x86asm unless you deliberately want to lose the optimized x86 assembly. Install the Noble nasm package and rerun configure instead.
Step 4: Build and install without sudo
Choose a parallel job count appropriate for the machine. Four is a conservative starting point; lower it on a small VM or raise it only when memory allows.
FFMPEG_JOBS="${FFMPEG_JOBS:-4}"
make -j"$FFMPEG_JOBS"
make install
Because FFMPEG_PREFIX is under the current user’s home directory, make install should not need root privileges. If it asks for permission, stop and check the prefix printed by ./configure rather than adding sudo.
Step 5: Verify the exact binary you built
Use absolute paths during verification so an older /usr/bin/ffmpeg cannot hide a problem:
FFMPEG_BIN="$FFMPEG_PREFIX/bin/ffmpeg"
FFPROBE_BIN="$FFMPEG_PREFIX/bin/ffprobe"
"$FFMPEG_BIN" -version
"$FFMPEG_BIN" -buildconf
"$FFMPEG_BIN" -hide_banner -encoders \
| grep -E 'libx264|libx265|libvpx|libmp3lame|libopus'
"$FFMPEG_BIN" -hide_banner -filters \
| grep -E 'drawtext|subtitles|aresample'
The following smoke test generates its own short video and tone, encodes them, and inspects the result. It does not need a personal media file:
FFMPEG_TEST_OUTPUT="$FFMPEG_WORK_DIR/ffmpeg-smoke-test.mp4"
"$FFMPEG_BIN" -hide_banner \
-f lavfi -i 'testsrc2=size=640x360:rate=30' \
-f lavfi -i 'sine=frequency=1000:sample_rate=48000' \
-t 3 \
-c:v libx264 -preset veryfast -pix_fmt yuv420p \
-c:a aac -shortest -y "$FFMPEG_TEST_OUTPUT"
"$FFPROBE_BIN" -v error \
-show_entries stream=index,codec_name,codec_type \
-show_entries format=duration \
-of json "$FFMPEG_TEST_OUTPUT"
A successful build command alone is not proof that every codec, filter, device, or driver works. Check the specific path you intend to use.
Put this build to work with LazyEdit
Compiling FFmpeg is usually setup, not the finished workflow. I maintain LazyEdit, LazyingArt’s open-source video workflow for preprocessing, transcription, multilingual subtitles, keyframes, metadata, and optional publishing.
- Inspect LazyEdit’s source and installation notes
- Inspect a project-owned story-clip delivery sample, including candidate moments, captions, a source ledger, output probes, and hashes
LazyEdit normally works with Ubuntu’s packaged FFmpeg; it does not require FFmpeg 9.0.1 specifically. A source build is useful only when a codec or filter you actually need is missing. If you use the custom prefix from this guide, verify that both ffmpeg and ffprobe resolve to it inside the exact shell, tmux session, container, or service that runs LazyEdit. Changing PATH in one interactive shell does not prove that a service uses the same binary.
Use the custom build without replacing Ubuntu’s package
For the current shell only:
export PATH="$FFMPEG_PREFIX/bin:$PATH"
hash -r
type -a ffmpeg
ffmpeg -version | sed -n '1p'
Keep the versioned prefix in the persistent PATH only after verification. When upgrading, build into a new prefix, test it by absolute path, and then switch the PATH entry. Keeping Ubuntu’s packaged binary in /usr/bin provides a clear fallback.
Licensing: GPL versus non-free options
FFmpeg is LGPL by default, but this recipe enables x264 and x265 and therefore uses --enable-gpl. If you distribute the resulting binary, review FFmpeg’s GPL compliance guidance and the licenses of every linked library.
This base recipe uses FFmpeg’s native AAC encoder. If you add libfdk-aac-dev, FFmpeg’s codec documentation requires --enable-libfdk-aac; combining it with this GPL configuration also requires --enable-nonfree. FFmpeg marks such a build as non-redistributable. Do not add those flags merely because an old “enable everything” list contained them.
If you do not need x264 or x265, you can omit their development packages and configure flags, and remove --enable-gpl. Always judge the final license from the complete configuration, not from one flag in isolation.
Hardware acceleration is a separate build decision
Do not assume that one configure flag makes GPU acceleration work. VAAPI, NVENC/NVDEC, Vulkan, and other paths depend on different headers, drivers, devices, and runtime permissions. Start with the exact FFmpeg release’s ./configure --help, install only the official dependencies for the chosen path, and test on the target machine.
After building, this command shows interfaces compiled into FFmpeg:
"$FFMPEG_BIN" -hide_banner -hwaccels
That list does not prove that a compatible GPU and working driver are present. Verify with a small decode or encode using the actual device before relying on it in production.
Maintenance checklist
For a source build I keep these habits:
- Watch the official FFmpeg download and security pages for new releases.
- Download the new tarball and signature, then verify the published fingerprint again.
- Build into a new versioned prefix instead of overwriting the working build.
- Save the output of
ffmpeg -versionandffmpeg -buildconfwith deployment notes. - Repeat a representative media test, not only the synthetic smoke test.
- Switch
PATHonly after the new binary passes those checks.
This takes a little more care than apt install ffmpeg, but it gives you a traceable source release, an explicit feature set, and a clean rollback path without modifying Ubuntu’s system binary.
Primary references
Checked September 1, 2026:
