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.
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
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.
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:
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