This guide installs FFmpeg 8.1.2 from source on Ubuntu (24.04 LTS) for servers that process user-uploaded media, such as Pixelfed or Loops.
This fixes the pixelsmash vulnerability.
It installs FFmpeg into:
/opt/ffmpeg/8.1.2Then symlinks the active binaries to:
/usr/local/bin/ffmpeg
/usr/local/bin/ffprobeThis avoids replacing Ubuntu’s packaged /usr/bin/ffmpeg directly and makes rollback easier.
Ubuntu 24.04 LTS may not ship the latest upstream FFmpeg release through apt.
For Pixelfed and Loops services, staying current matters because FFmpeg parses untrusted media files during transcoding, thumbnailing, probing, and metadata extraction.
which ffmpeg
ffmpeg -version
which ffprobe
ffprobe -versionYou may see something like:
/usr/bin/ffmpeg
ffmpeg version 6.xAfter this guide, you should see:
/usr/local/bin/ffmpeg
ffmpeg version 8.1.2sudo apt update
sudo apt install -y \
build-essential pkg-config yasm nasm git curl wget ca-certificates gnupg \
autoconf automake libtool cmake meson ninja-build \
zlib1g-dev liblzma-dev libbz2-dev \
libx264-dev libx265-dev libvpx-dev libopus-dev \
libaom-dev \
libass-dev libfreetype6-dev libfontconfig1-dev \
libwebp-dev libvorbis-dev libnuma-devThis build includes support for common Pixelfed / Loops-style transcoding needs:
- H.264 via
libx264 - H.265 via
libx265 - VP8/VP9 via
libvpx - AV1 via
libaom - Opus audio
- WebP
- subtitles / text rendering support
- MP4 output
This intentionally does not require libsvtav1 or libdav1d, because those optional dependencies may not be available or correctly detected on every Ubuntu server.
cd /usr/local/src
sudo wget https://ffmpeg.org/releases/ffmpeg-8.1.2.tar.xz
sudo tar -xf ffmpeg-8.1.2.tar.xz
cd ffmpeg-8.1.2sudo ./configure \
--prefix=/opt/ffmpeg/8.1.2 \
--enable-gpl \
--enable-libx264 \
--enable-libx265 \
--enable-libvpx \
--enable-libopus \
--enable-libaom \
--enable-libass \
--enable-libfreetype \
--enable-libfontconfig \
--enable-libwebp \
--enable-libvorbis \
--enable-zlib \
--enable-lzma \
--enable-pthreadsNotes:
--enable-gplis required forlibx264andlibx265.- This is generally fine for internal server-side transcoding.
- Do not redistribute the compiled binary unless you understand the GPL licensing implications.
sudo make -j"$(nproc)"
sudo make installsudo ln -sfn /opt/ffmpeg/8.1.2/bin/ffmpeg /usr/local/bin/ffmpeg
sudo ln -sfn /opt/ffmpeg/8.1.2/bin/ffprobe /usr/local/bin/ffprobe
hash -rVerify:
which ffmpeg
ffmpeg -version
which ffprobe
ffprobe -versionExpected path:
/usr/local/bin/ffmpeg
/usr/local/bin/ffprobeExpected version:
ffmpeg version 8.1.2Check H.264 encoding:
ffmpeg -hide_banner -encoders | grep libx264Check MP4 output support:
ffmpeg -hide_banner -muxers | grep mp4Check common decoders:
ffmpeg -hide_banner -decoders | grep -E "h264|hevc|vp8|vp9|av1|aac|opus"ffmpeg -hide_banner \
-f lavfi \
-i testsrc2=size=1080x1920:rate=30 \
-t 5 \
-c:v libx264 \
-preset veryfast \
-crf 23 \
-pix_fmt yuv420p \
-movflags +faststart \
-an \
/tmp/ffmpeg-test.mp4
ffprobe -hide_banner /tmp/ffmpeg-test.mp4If this succeeds, FFmpeg can generate a basic H.264 MP4 file.
Edit your Pixelfed .env file:
nano .envSet:
FFMPEG_BINARIES=/usr/local/bin/ffmpeg
FFPROBE_BINARIES=/usr/local/bin/ffprobeThen refresh Laravel config and restart workers:
php artisan config:cache
php artisan cache:clear
php artisan horizon:terminateIf you use Supervisor workers instead of Horizon, restart them too:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl restart allIf needed, restart PHP-FPM:
sudo systemctl restart php8.3-fpmAdjust the PHP-FPM service name if your server uses a different PHP version.
For Loops, set the same binary paths in .env:
FFMPEG_BINARIES=/usr/local/bin/ffmpeg
FFPROBE_BINARIES=/usr/local/bin/ffprobeAfter editing .env, refresh config and restart workers:
php artisan config:cache
php artisan cache:clear
php artisan horizon:terminateRemove this configure flag:
--enable-libsvtav1SVT-AV1 is only needed if you intentionally want AV1 encoding through SVT-AV1.
For Pixelfed / Loops MP4 transcoding, it is not required.
Remove this configure flag:
--enable-libdav1ddav1d is an optional AV1 decoder.
For Pixelfed / Loops MP4 transcoding, it is not required.
Install the missing package:
sudo apt update
sudo apt install -y libx264-devThen rerun the ./configure command.
Check the symlink:
ls -lah /usr/local/bin/ffmpeg
ls -lah /opt/ffmpeg/8.1.2/bin/ffmpegRecreate it:
sudo ln -sfn /opt/ffmpeg/8.1.2/bin/ffmpeg /usr/local/bin/ffmpeg
sudo ln -sfn /opt/ffmpeg/8.1.2/bin/ffprobe /usr/local/bin/ffprobe
hash -rTo temporarily go back to Ubuntu’s packaged FFmpeg:
sudo ln -sfn /usr/bin/ffmpeg /usr/local/bin/ffmpeg
sudo ln -sfn /usr/bin/ffprobe /usr/local/bin/ffprobe
hash -r
ffmpeg -versionOr remove the custom symlinks:
sudo rm /usr/local/bin/ffmpeg
sudo rm /usr/local/bin/ffprobe
hash -rThen verify:
which ffmpeg
ffmpeg -versionFinal verification:
which ffmpeg
ffmpeg -version
which ffprobe
ffprobe -version
ffmpeg -hide_banner -encoders | grep libx264
ffmpeg -hide_banner -muxers | grep mp4You should now be running FFmpeg 8.1.2 from:
/usr/local/bin/ffmpeg