Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Bash

How to Compile FFmpeg 6.0 in Linux and What New Things Can Be Done With It

5.00/5 (1 vote)
8 Mar 2023CPOL6 min read 13.9K  
How to get compile the latest FFmpeg source code and try out some new features
Download source code from the FFmpeg git repository, follow the official compilaition wiki, get past error messages and try out some new features.

Introduction

In this article, you will learn to compile FFmpeg from the source code on Linux. You will follow the official FFmpeg wiki for this. There is, however, an error waiting for you. It can be fixed. Then, you can try out the new features in the latest 'Von Neuman' release.

Background

The new version is named after the computer scientist John von Neumann. I should welcome this version with as much warmth as Jerry Seinfeld showed the rotund postman in the sitcom. This new version came out less than a month after the release of my FFmpeg book. Fortunately, I tested the book with a binary built from git source code in September last year. In any case, the version released in July was declared LTS (Long Term Support). In other words, my code examples are safe for two years.

New Release Schedule

The FFmpeg project has decided that in the beginning of the year, they will release a major version and in the middle, a minor one. Another thing that they decided was that deprecated features will be removed after three releases (including major and minor releases).

Deprecated Features

When updating my book in September, I found that the -map_channel option has been deprecated. FFmpeg threw a warning when using it.

The -map_channel option is deprecated and will be removed. 
It can be replaced by the 'pan' filter, or in some cases by combination s 
of 'channelsplit', 'channelmap', 'amerge' filters.

Instead of …

ffmpeg -i wrong-channels.mp4 \
       -c:v copy \
       -map_channel 0.1.1 -map_channel 0.1.0 \
       fine-channels.mp4

ffmpeg -i moosic.mp3 \
       -map_channel 0.0.0 -map_channel -1 \
       moosic4lefty.mp3

ffmpeg -y -i zombie.mp4 \
       -map 0:0 -map 0:1 -map 0:1 -map 0:1 \
       -map_channel 0.1.0:0.1 -map_channel 0.1.1:0.2 \
       -c:v copy \
       zombie-tracks.mp4

… you have to use …

# Switch right and left channels of stereo audio
ffmpeg -i wrong-channels.mp4 \
       -c:v copy \
       -filter_complex "channelmap=map=FR-FL|FL-FR" \
       fine-channels.mp4
# Silence right channel
ffmpeg -i moosic.mp3  \
       -c:v copy \
       -filter_complex "pan=stereo|FL=FL|FR=0" \
       moosic4lefty.mp3
# Split channels to separate audio streams 
# and also preserve existing audio stream
ffmpeg -y -ss 0:0:20 -t 0:0:20 -i zombie.mp4 \
       -c:v copy \
       -filter_complex "channelsplit[L][R]" \
       -map 0:v:0  -map '[L]' -map '[R]' -map 0:a:0 \
       -codec:a:0 aac -ac:a:0 1 \
       -codec:a:1 aac -ac:a:1 1 \
       -codec:a:2 copy \
       zombie-tracks.mp4

Some of the options of these channel filters may have similar names but are formatted quite differently. Be careful.

Other Deprecated Stuff

  • -async: Replace with aresample filter. Use asetpts filter if you need to re-generate timestamps.

Compilation

I am using an Ubuntu-based distro. So, I read the FFmpeg wiki page for compiling on Ubuntu. I followed the steps as prescribed but I encountered problems when building the libvmaf external library.

meson.build:1:0: ERROR: The value of the 'bindir' option is 
'/home/ya-username/bin' which must be a subdir of the prefix 
'/home/ya-username/ffmpeg_build'.
Note that if you pass a relative path, it is assumed to be a subdir of prefix.

I fixed it by changing the --bindir option of the vmaf build from:

--bindir="$HOME/bin"

… to …

--bindir="$HOME/ffmpeg_build/bin" 

After compilation, I manually copied the newly built vmaf file to the ${HOME}/bin directory. I do not know if it is required but I just did not want to take chances this way or that way.

I studied ffmpeg_sources/ffmpeg/configure script and installed several external libraries that FFmpeg could use.

sudo apt install gnutls-dev libgnutls30 
frei0r-plugins-dev libchromaprint-devlibchromaprint-dev libgme-dev 
flite-dev libcaca-dev libbs2b-dev libopenjp2-7-dev 
libopencore-amrnb-dev librubberband-dev libopenmpt-dev libshine-dev 
libsmbclient-dev libsnappy-dev libsoxr-dev libspeex-dev libtheora-dev 
libtwolame-devlibv4l-dev libvidstab-dev libvo-amrwbenc-dev 
libxvidcore-dev liblzma-dev libbluray-dev libcdparanoia-dev 
libcdio-dev opencl-dev libcdio-paranoia-dev

When you compile FFmpeg from source, its version number defaults to a meaningless git snapshot label.

FFmpeg version is not meaningful

I made changes to a few downloaded source files. I modified the version number in the ffmpeg_sources/ffmpeg/RELEASE to 6.0.git. (The FFmpeg project forgot to update it. Usually, you do not have to do this.) After that, I made the ffmpeg_sources/ffmpeg/VERSION file more meaningful.

# Backup the file containing the git label
cp VERSION VERSION.bak

# Suffix the current date and release version number to the label
echo -e "$(cat VERSION.bak) [$(date +%Y-%m-%d)] [$(cat RELEASE)] " > VERSION

Now, I was ready to compile. I modified the configure statement to take advantage of the external libraries that I had installed.

PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure 
  --prefix="$HOME/ffmpeg_build"   --pkg-config-flags="--static"  
  --extra-cflags="-I$HOME/ffmpeg_build/include"  
  --extra-ldflags="-L$HOME/ffmpeg_build/lib" 
  --extra-libs="-lpthread -lm"   --ld="g++" 
  --bindir="$HOME/bin"   --enable-gpl --enable-static 
  --enable-gnutls   --enable-libaom   --enable-libass 
  --enable-libfdk-aac   --enable-libfreetype 
  --enable-libmp3lame   --enable-libopus 
  --enable-libsvtav1   --enable-libdav1d 
  --enable-libvorbis  --enable-libvpx --enable-libwebp 
--enable-libjxl --enable-libopenjpeg --enable-libpulse 
--enable-libx264   --enable-libx265   --enable-chromaprint 
--enable-frei0r   --enable-libbluray --enable-libbs2b 
--enable-libcdio --enable-librubberband --enable-libspeex 
--enable-libtheora --enable-libfontconfig   
--enable-libfribidi --enable-libxml2 --enable-libxvid 
--enable-libsmbclient --enable-version3   
--enable-libv4l2 --enable-libvidstab --enable-libcaca 
--enable-opencl --enable-libopenmpt --enable-libmodplug 
--enable-libgme --enable-libopencore-amrwb --enable-opengl 
--enable-libsnappy --enable-libmysofa --enable-libshine 
--enable-libopencore-amrnb --enable-libtheora 
--enable-libtwolame --enable-libvo-amrwbenc 
--enable-libflite --enable-libsoxr --enable-ladspa --enable-nonfree

The above statement is good for DEB- or Ubuntu-based distros. In Windows, not all of the above -enable-prefixed options are relevant. Some other Windows-only library options can be added. Study the configure script carefully and install all possible external libraries. You never know what you might need later. Here, I should note that building from source in Windows is difficult. You are better off downloading the pre-built Windows executables from ffmpeg.org.

I then built the source.

PATH="$HOME/bin:$PATH" make
make install && hash -r

More meaningful FFmpeg version number

What is New for FFmpeg CLI Users?

There are lots of behind-the-scenes changes such as threading improvements. FFmpeg will create the output in a separate thread. Some new codecs and formats are supported. Check the end of this article for the grisly details. Changes for users of the command-line tools are only a subset.

Load Filter Option Value From a File

Instead of:

ffmpeg -filter_complex \
          "testsrc,
           colorhold=color=yellow:similarity=0.2" \
       -t 6 \
       hold-yellow.mp4 && ffplay hold-yellow.mp4

… you can do …

printf "yellow" > color-value.txt
ffmpeg -filter_complex \
          "testsrc,
           colorhold=/color=color-value.txt:similarity=0.2" \
       -t 6 \
       hold-yellow.mp4 && ffplay hold-yellow.mp4

What is the difference? You see that slash ( / ) before the color option of the colorhold filter? That is how you specify a filter option whose value needs to be loaded from a file.

The file can contain option value for one filter option. This file has to be written in binary. No hand-coding.

# This throws errors
echo "yellow" > color-value.txt

If you use a text editor or an echo command, you will add line endings — newline, carriage return or both, depending on you OS.

# This does fine
printf "yellow" > color-value.txt

Maybe the new filters are something you can play with.

a3dscope Filter

Documentation says:

Convert input audio to 3d scope video output.

ffmpeg -i "cow-say-moo.mp3" \
       -filter_complex "a3dscope=s=nhd[v]" \
       -c:a copy \
       -map '[v]' -map 0:a:0 \
       ffmpeg-filter-a3dscope-for-cow-say-moo.mp4

Well, the output is something. I do not know what.

Animation showing video

showcwt Filter

The fine manual says:

Convert input audio to video output representing frequency spectrum using Continuous Wavelet Transform and Morlet wavelet.

So, I try:

ffplay -f lavfi "amovie=jack-thanks.mp3,asplit[a1][out0];
[a1]showcwt=s=nhd:slide=replace:mode=stereo:scale=log2[out1]"

And, I get:

Spectrum image

Another bummer! Maybe it has some application for one pehson(s). Maybe one meellion! I am jesting, of course. Not everything has to be shiny or cool.

New Video Stacking Filters

The old hstack, vstack and xstack allowed you to stack videos side-by-side, one above another or in a matrix. They all had a limitation — the input video streams had to have the same dimensions. The release mentions that there are new hstack_qsv, vstack_qsv and xstack_qsv filters, which will resize the videos and also maintain the aspect ratio. I have an AMD CPU so these Intel QuickSync Video hardware acceleration filters did not get built.

Other New Stuff

As I build FFmpeg from git, it is newer than the 6.0 release. I did a comparison of the annexures of my book containing lists of encoders, decoders, codecs, formats and filters with one I generated (I have a shell script) for the latest version. There were some additions.

  • Codecs: Same as decoders
  • Decoders
    • media100 — Media 100
    • vqc — ViewQuest VQC
    • adpcm_xmd — ADPCM Konami XMD
    • apac — Marian's A-pac audio
    • cbd2_dpcm — DPCM Cuberoot-Delta-Exact
    • bonk — Bonk audio
    • ftr — FTR Voice
    • misc4 — Micronas SC-4 Audio
    • rka — RKA (RK Audio)
    • wady_dpcm — DPCM Marble WADY
    • wavarc — Waveform Archiver
  • Encoders: None. It could be a limitation of the external libraries that I had chosen.
  • Filters
    • adrc — Audio Spectral Dynamic Range Controller
    • dynaudnorm — Dynamic Audio Normalizer (gains slicing support)
    • surround — Apply audio surround upmix filter (gains command support)
    • afdelaysrc — Generate a Fractional delay FIR coefficients
    • backgroundkey — Turns a static background into transparency
    • corr — Calculate the correlation between two video streams
    • cropdetect — Auto-detect crop size (gains command support)
    • ssim360 — Calculate the SSIM between two 360 video streams
    • thumbnail — Select the most representative frame in a given sequence of consecutive frames
    • hstack_vaapi — "VA-API" hstack (hardware accelerated version of hstack)
    • vstack_vaapi — "VA-API" vstack (hardware accelerated version of vstack)
    • xstack_vaapi — "VA-API" xstack (hardware accelerated version of xstack)
    • a3dscope — Convert input audio to 3d scope video output
    • showcwt — Convert input audio to a CWT (Continuous Wavelet Transform) spectrum video output
  • Formats
    • apac — raw APAC
    • bonk — raw Bonk
    • laf — LAF (Limitless Audio Format)
    • rka — RKA (RK Audio)
    • sdns — Xbox SDNS
    • wady — Marble WADY
    • wavarc — Waveform Archiver
    • xmd — Konami XMD

Unfortunately, I did not create lists for muxers and demuxers. The release announcement mentions a few.

History

  • 8th March, 2023: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)