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. 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 2022, I found that the -map_channel
option has been deprecated. FFmpeg throws 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 <b>-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 witharesample
filter. Useasetpts
filter if you need to re-generate timestamps.
Compilation
I am on an Ubuntu spin. So, I followed the FFmpeg wiki page for compiling on Ubuntu. I followed the steps as prescribed but I ran into problems once again when got to 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 fellers 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
How about a test?
I created an animated PNG and GIF of a video.
ffmpeg -ss 0:9:6 \
-i FULL-Tucker-Carlson-Tonight-End-Show-HD-Fox-Breaking-News-March.mp4 \
-t 0:0:50 \
-filter_complex \
"fps=7,scale=w=160:h=-1:flags=lanczos,split[v1][v2];
[v1]palettegen=stats_mode=diff[p];
[v2][p]paletteuse=dither=bayer:bayer_scale=4" \
tucker-carlson-j6-uncensored-footage-qanon-shaman-chaperoned-by-police-everywhere-160.gif
This 160-pixel-wide GIF file is 1.2 MB. I created a 100-pixel-wide APNG. It was 4 MB. I dare not host it.
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. In future, multi-threading will affect not just the muxer but also other parts of the FFmpeg chain — demuxer, decoder, filters and encoder. 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 your 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 final 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 grid. They had a limitation that the input video streams be the same dimensions. There are hardware-accelerated versions of these filters. The release mentions that there are new hstack_qsv
, vstack_qsv
and xstack_qsv
filters, which will resize the videos but 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 differences.
- Codecs: Same as decoders
- Decoders
media100
— Media 100vqc
— ViewQuest VQCadpcm_xmd
— ADPCM Konami XMDapac
— Marian's A-pac audiocbd2_dpcm
— DPCM Cuberoot-Delta-Exactbonk
— Bonk audioftr
— FTR Voicemisc4
— Micronas SC-4 Audiorka
— RKA (RK Audio)wady_dpcm
— DPCM Marble WADYwavarc
— Waveform Archiver
- Encoders: None. It could be a limitation of the external libraries that I had chosen.
- Filters
adrc
— Audio Spectral Dynamic Range Controllerdynaudnorm
— Dynamic Audio Normalizer (gains slicing support)surround
— Apply audio surround upmix filter (gains command support)afdelaysrc
— Generate a Fractional delay FIR coefficientsbackgroundkey
— Turns a static background into transparencycorr
— Calculate the correlation between two video streamscropdetect
— Auto-detect crop size (gains command support)ssim360
— Calculate the SSIM between two 360 video streamsthumbnail
— Select the most representative frame in a given sequence of consecutive frameshstack_vaapi
— "VA-API" hstack (hardware accelerated version ofhstack
)vstack_vaapi
— "VA-API" vstack (hardware accelerated version ofvstack
)xstack_vaapi
— "VA-API" xstack (hardware accelerated version ofxstack
)a3dscope
— Convert input audio to 3d scope video outputshowcwt
— Convert input audio to a CWT (Continuous Wavelet Transform) spectrum video output
- Formats
apac
— raw APACbonk
— raw Bonklaf
— LAF (Limitless Audio Format)rka
— RKA (RK Audio)sdns
— Xbox SDNSwady
— Marble WADYwavarc
— Waveform Archiverxmd
— Konami XMD
Unfortunately, I did not create lists for muxers and demuxers. The release announcement mentions a few.