DEV Community

Cover image for How to install FFmpeg on Linux from Source
Mirza Bilal
Mirza Bilal

Posted on • Edited on • Originally published at mirzabilal.com

2 1 1

How to install FFmpeg on Linux from Source

Tailoring your multimedia toolkit for best performance on Ubuntu, CentOS, RedHat, or any other Linux Distribution

Introduction

It was probably 2006 when I first heard about FFmpeg, and I was amazed by its capabilities. FFmpeg is a go-to solution for transcoding, and video manipulation, from trimming to burning the subtitles, adding a watermark, and more. Since FFmpeg was first launched, it has come a long way and has become the industry leader for multimedia workload for desktop apps, web, and especially on the backend.
In this article, we will discuss, Why you need to customize FFmpeg to match your requirements? and How you can compile FFmpeg from source along with various essential libraries and codes needed for video processing on different Linux distributions, from Ubuntu to Redhat based systems.

Problem

Installing FFmpeg directly from a Linux distribution's default repositories may seem like a no-brainer, but this method is filled with potential drawbacks. For one, these repositories might not offer the most recent versions of FFmpeg and essential codecs or libraries, possibly exposing users to security risks and preventing them from accessing the latest features. Moreover, these default builds can be burdened with unnecessary codecs and libraries that many users may never use, or you might stranded in a scenario where the package has everything but does not come with the library you need.
But the challenges don't stop here; in today's diverse device ecosystem, which spans across ARM and x86_64 architectures, a one-size-fits-all build from the repository might not be optimized for a specific device with a specific instruction set. This is especially concerning for multimedia tasks that demand real-time processing, and you want to make the most out of the hardware you have.
Furthermore, for young developers or those new to the Linux landscape, crafting a custom FFmpeg build tailored to their requirements can be a daunting experience. The sea of options, configurations, and dependencies can be overwhelming, leading them to settle for suboptimal, generic builds rather than extracting the true potential of FFmpeg.

Why Compile from Source?

To overcome discussed problems for newbies to experts, the importance of comprehensive guides and resources to bridge the knowledge gap and empower the next generation of developers to confidently customize their multimedia tools. Following are the notable advantages of using source code as the starting point.

  1. Customization: By compiling from the source, you can choose the exact features and codecs you want, leading to a personalized FFmpeg build tailored to your needs.

  2. Smaller Footprint: When you include only the components you need, the resultant build will often be leaner and require less disk space.

  3. Access to the Latest Code: Official channels might not always have the latest version of FFmpeg. Compiling from source ensures you're working with the most recent codebase.

  4. Performance Optimizations: Building from source code can enable certain optimizations specific to your machine's architecture and instruction set, potentially enhancing performance.

  5. Greater Learning Opportunity: Compiling software from a source provides a deeper understanding of the software and its dependencies.

Installing Dependencies

Before we jump into the installation process, it's essential to set up our system with the necessary dependencies.

On Ubuntu:

sudo apt update
sudo apt install -y build-essential yasm cmake libtool libc6 libc6-dev unzip wget
Enter fullscreen mode Exit fullscreen mode

On RedHat-based distributions:

sudo yum groupinstall "Development Tools"
sudo yum install -y yasm cmake libtool unzip wget
Enter fullscreen mode Exit fullscreen mode

Installing dependencies and codes:

Once your build environment is set up, the next critical step is to install the various codecs and libraries that FFmpeg relies upon or that you wish to utilize for specific multimedia tasks. Remember, one of the key benefits of building from source is the ability to customize your FFmpeg installation, ensuring it's streamlined to your needs; here you can pick and drop or even add codecs or libraries that you wish to use.

In the final script, we have provided a comprehensive list of dependencies and libraries, ensuring that you have a broad spectrum of multimedia capabilities at your fingertips.

Installing FFmpeg

You can obtain the latest source code from FFmpeg's official website or use git:

git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
Enter fullscreen mode Exit fullscreen mode

Configuration

This step is crucial. The ./configure script allows you to select which features and codecs to include. For a basic setup, you can run:

./configure \
            --prefix="$USR_LOCAL_PREFIX" \
            --disable-static --enable-shared \
            --extra-cflags="-I$USR_LOCAL_PREFIX/include $NVIDIA_CFLAGS" \
            --extra-ldflags="-L$USR_LOCAL_PREFIX/lib $NVIDIA_LDFLAGS" \
            --extra-libs='-lpthread -lm' \
            --bindir="$USR_LOCAL_PREFIX/bin" \
            --enable-gpl --enable-libaom --enable-libass \
            --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame \
            --enable-libopus --enable-libvorbis --enable-libvpx \
            --enable-libx264 --enable-libx265 --enable-nonfree \
            --enable-openssl
Enter fullscreen mode Exit fullscreen mode

However, for a more customized setup, use flags like --enable-codec, --disable-codec, --enable-libx264, etc. Check ./configure --help for a full list of options.

Compilation & Installation

Once configured, compile and install FFmpeg here:

make -j$(nproc)
sudo make install
Enter fullscreen mode Exit fullscreen mode

This will use all your CPU cores for the compilation (-j$(nproc)) and then install the software.

Verification

To verify your FFmpeg installation:

ffmpeg -version
Enter fullscreen mode Exit fullscreen mode

Wrap up & the magic script:

By now, you should have a basic understanding of how to customize FFmpeg. If so, that was our goal. If you have any confusion, leave a comment and I'll be happy to discuss. To streamline everything and every step mentioned here, there's a script for you to simply run, and it will handle the entire process.

#!/bin/bash
set -e # Exit on any error
if [ "$EUID" -ne 0 ]; then
echo "This script must be run as root."
exit 1
fi
USR_LOCAL_PREFIX="/usr/local"
HOME_DIR=$HOME
DOWNLOAD="wget"
SRC_DIR=$HOME_DIR/sources
CPUS=$(nproc)
LOG_FILE="$HOME_DIR/install.log"
LOCAL_TMP=$HOME_DIR/sources/local-tmp
mkdir -p $LOCAL_TMP
if [[ "$1" != "--stdout" ]]; then
exec >>"$LOG_FILE" 2>&1
fi
OPUS_VER="opus-1.4"
LIBAOM_VER="v3.7.0"
LIBOGG_VER="libogg-1.3.5"
LIBVORBIS_VER="libvorbis-1.3.7"
LIBASS_URL=$(curl -s "https://api.github.com/repos/libass/libass/releases/latest" | awk -F'"' '/browser_download_url.*.tar.gz"/{print $4}')
# Create source directory
mkdir -p $SRC_DIR
pushd $SRC_DIR
# Helper functionS to check installation status
check_installation() {
if [ -f "$1" ]; then
echo "Success : $2 Installed"
else
echo "Error : $2 Installation Failed"
echo "Exiting script due to installation failure."
exit 1
fi
}
# Helper function to check installation based on exit code
check_exit_code() {
if [ $1 -eq 0 ]; then
echo "Success : $2 Installed"
else
echo "Error : $2 Installation Failed (Exit Code: $1)"
echo "Exiting script due to installation failure."
exit 1
fi
}
# Utility function to push a wildcard
pushdw() {
pushd "$(find $HOME_DIR -type d -name "$1" | head -n 1)"
}
install_utils() {
if [ -n "$(command -v dnf)" ]; then
package_manager="dnf"
elif [ -n "$(command -v apt-get)" ]; then
package_manager="apt-get"
else
echo "Neither DNF nor APT package manager found. Exiting."
exit 1
fi
echo "Updating packages..."
$package_manager -y update
echo "Installing packages..."
if [ "$package_manager" = "dnf" ]; then
$package_manager -y groupinstall "Development Tools"
$package_manager install -y git autoconf openssl-devel cmake3 htop iotop yasm nasm jq freetype-devel fribidi-devel harfbuzz-devel fontconfig-devel bzip2-devel
elif [ "$package_manager" = "apt-get" ]; then
$package_manager install -y git autoconf libtool libssl-dev cmake htop iotop yasm nasm jq libfreetype6-dev libfribidi-dev libharfbuzz-dev libfontconfig1-dev libbz2-dev
fi
echo "Success: Updates and packages installed."
echo "$USR_LOCAL_PREFIX/lib" | sudo tee /etc/ld.so.conf.d/usr-local-lib.conf
echo "$USR_LOCAL_PREFIX/lib64" | sudo tee -a /etc/ld.so.conf.d/usr-local-lib.conf
ldconfig
}
install_ffmpeg_prereqs() {
# Install LIBAOM (AV1 Codec Library)
mkdir -p libaom &&
pushd libaom &&
git -c advice.detachedHead=false clone --depth 1 --branch $LIBAOM_VER https://aomedia.googlesource.com/aom &&
cmake \
-DBUILD_SHARED_LIBS=ON \
-DENABLE_DOCS=OFF \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_INSTALL_PREFIX:PATH=$USR_LOCAL_PREFIX ./aom &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libaom.so" "LIBAOM"
# Install LIBASS (portable subtitle renderer)
$DOWNLOAD ${LIBASS_URL} &&
tar -zxf libass*.tar.gz &&
pushdw "libass*" &&
./configure --prefix="$USR_LOCAL_PREFIX" &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libass.so" "LIBASS"
# Install libmp3lame (MP3 Encoder)
curl -L https://sourceforge.net/projects/lame/files/latest/download -o lame.tar.gz &&
tar xzvf lame.tar.gz &&
pushdw "lame*" &&
./configure --prefix="$USR_LOCAL_PREFIX" \
--bindir="/usr/bin" \
--enable-nasm &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libmp3lame.so" "libmp3lame"
# Install opus video codec
$DOWNLOAD https://ftp.osuosl.org/pub/xiph/releases/opus/$OPUS_VER.tar.gz &&
tar xzvf $OPUS_VER.tar.gz &&
pushd $OPUS_VER &&
./configure --prefix="$USR_LOCAL_PREFIX" &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libopus.so" "opus"
# Install libogg (OGG Container format)
$DOWNLOAD http://downloads.xiph.org/releases/ogg/$LIBOGG_VER.tar.gz &&
tar xzvf $LIBOGG_VER.tar.gz &&
pushd $LIBOGG_VER &&
./configure --prefix="$USR_LOCAL_PREFIX" &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libogg.so" "libogg"
ldconfig
# Install libvorbis (vorbis audio codec)
$DOWNLOAD http://downloads.xiph.org/releases/vorbis/$LIBVORBIS_VER.tar.gz &&
tar xzvf $LIBVORBIS_VER.tar.gz &&
pushd $LIBVORBIS_VER &&
./configure --prefix="$USR_LOCAL_PREFIX" \
--with-ogg="$USR_LOCAL_PREFIX" &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libvorbis.so" "libvorbis"
# Install FDKAAC (AAC audio codec)
git clone --depth 1 https://github.com/mstorsjo/fdk-aac &&
pushd fdk-aac &&
autoreconf -fiv &&
./configure --prefix="$USR_LOCAL_PREFIX" &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libfdk-aac.so" "FDKAAC"
# Install WEBM
git clone --depth 1 https://chromium.googlesource.com/webm/libvpx.git &&
pushd libvpx &&
./configure --prefix="$USR_LOCAL_PREFIX" \
--disable-static --enable-shared \
--disable-examples --disable-unit-tests \
--enable-vp9-highbitdepth --as=yasm &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libvpx.so" "WEBM"
# Install X264 (H.264 Codec)
git clone --depth 1 https://code.videolan.org/videolan/x264.git &&
pushd x264 &&
PKG_CONFIG_PATH="$USR_LOCAL_PREFIX/lib/pkgconfig" ./configure \
--enable-shared --disable-static \
--prefix="$USR_LOCAL_PREFIX" \
--bindir="/usr/bin" &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libx264.so" "X264"
# Install X265 (H.265 Codec)
git clone https://bitbucket.org/multicoreware/x265_git.git &&
pushd x265_git/build/linux &&
cmake -G "Unix Makefiles" \
-DCMAKE_INSTALL_PREFIX="$USR_LOCAL_PREFIX" \
-DBUILD_SHARED_LIBS=ON \
../../source &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/lib/libx265.so" "X265"
}
install_ffmpeg() {
# Install FFMPEG (AV1 Codec Library)
$DOWNLOAD https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 &&
tar -jxf ffmpeg-snapshot.tar.bz2 &&
pushd ffmpeg &&
PKG_CONFIG_PATH="$USR_LOCAL_PREFIX/lib/pkgconfig:/usr/lib64/pkgconfig:/usr/share/pkgconfig:/usr/lib/pkgconfig:$USR_LOCAL_PREFIX/lib/pkgconfig" \
./configure \
--prefix="$USR_LOCAL_PREFIX" \
--disable-static --enable-shared \
--extra-cflags="-I$USR_LOCAL_PREFIX/include" \
--extra-ldflags="-L$USR_LOCAL_PREFIX/lib" \
--extra-libs='-lpthread -lm' \
--bindir="$USR_LOCAL_PREFIX/bin" \
--enable-gpl \
--enable-libaom \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-nonfree \
--enable-openssl &&
make -j $CPUS &&
make install
popd
check_installation "$USR_LOCAL_PREFIX/bin/ffmpeg" "ffmpeg"
check_installation "$USR_LOCAL_PREFIX/bin/ffprobe" "ffprobe"
ldconfig
}
# Execute Functions
install_utils
source $HOME_DIR/.bashrc
install_ffmpeg_prereqs
install_ffmpeg
popd
rm -fr $SRC_DIR

Conclusion

Now that we've gone through the process, I'm curious: Where do you plan to use your custom-tailored FFmpeg? Are you working on an innovative multimedia project, developing a web application, or just experimenting with video processing for personal use? FFmpeg's versatility excels in a multitude of applications, from large-scale video platforms to hobbyist projects. Share your plans or current FFmpeg projects in the comments below. Let's learn from one another and discover even more unique use cases for this powerful tool. Remember, the world of multimedia is vast, and with FFmpeg, the possibilities are endless.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay