Encoding webm Videos with ffmpeg: vp9 / av1
Videos are a very powerful media type of entertainment and visualisation, let's see hwo we can self host high compression videos that save bandwidth for your viewers/users and how to find out which codec to pick from.
A word of caution, lots of people, like me, do not prefer video over written text for many contexts, but to explain complex user interfaces or complex data types they're incredibly good.
This post does not apply if you are not responsible for the content distribution, if you are uploading your videos to YouTube or Vimeo that have their own transcoding machinery, you should just render what ever is convenient and high quality to you, because you have no control over the finished result that they transcode for you. This post is about producing end results that are similar to theirs.
There are lots of cases where you want to self-host video, for example if it's going to be part of a layout element or if you need more control over how your video is displayed or without third party branding and recommended videos at the end.
The video examples in this post are from our Norway Travel VLOG, that you can see in full below with a few epic drone shots and some dog and moose content:
Installing ffmpeg 5
If you're on an Ubuntu-like distro like Linux Mint or similar, you might want to ensure you have ffmpeg 5 installed for the stable version of the av1 encoder through the PPA if necessary.
You can check your locally installed version of
ffmpeg by running:
ffmpeg version 5.1.2-0ubuntu1~20.04.sav1 Copyright (c) 2000-2022 the FFmpeg developers built with gcc 9 (Ubuntu 9.4.0-1ubuntu1~20.04.1) configuration: --prefix=/usr --extra-version='0ubuntu1~20.04.sav1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-lcms2 --enable-libaom # [...]
and you want to look for
5.x and in the list of features for
--enable-libaom to confirm that you have the av1 encoder built into your ffmpeg binary.
If they don't show up or if you want to upgrade to the stable av1 encoder you can check out the ffmpeg 5 ppa and follow the installation instructions below:
sudo add-apt-repository ppa:savoury1/ffmpeg4 sudo add-apt-repository ppa:savoury1/ffmpeg5 sudo apt-get update sudo apt-get upgrade && sudo apt-get dist-upgrade sudo apt-get install ffmpeg
What Codec is Best? VP9 vs AV1
Great about both codecs is that they are rather unproblematic in terms of patent restrictions, which historically have been an issue in mp3, mp4, m4a and other formats.
If you don't care about Edge or Safari and iOS users, you can use av1 as your only video codec today, otherwise I would strongly recommend vp9. This is true for the time of writing, I would recommend checking caniuse: vp9/av1 for the up to date support of browsers and platforms.
Let's compare the size and quality of the different encoders below, we'll use an h/264 mp4 rendered by Adobe Premiere of a vertical video trailer for instagram promoting our NORWAY travel VLOG 😉.
Note: The video examples are cut to the beat of the music, they do not stutter randomly, please play with audio!
ffmpeg -i mobile-trailer.mp4 -c:v libvpx-vp9 -b:v 3M -cpu-used 8 mobile-trailer_vp9.webm
-i mobile-trailer.mp4specifies the input file
-c:v libvpx-vp9use the vp9 encoder for video
-b:v 3Mkeep the target bitrate per second under/at this
ffmpeg -i mobile-trailer.mp4 -c:v libaom-av1 -b:v 3M -cpu-used 8 mobile-trailer_av1.webm
-c:v liaom-av1use the av1 encoder for video
-cpu-used 8use 8 threads
The -cpu-used option was only necessary for av1 because otherwise it was excruciatingly slow to encode. I'm not sure if it just has a different default for now, but adding it helped it run at about the same speed of
vp9, on my AMD Ryzen 7 2700+ at about .4 the play time of the video, so about twice the time spent playing the video.
Now that we have produced two video files, we can compare them locally:
9.1M mobile-trailer_av1.webm 42M mobile-trailer.mp4 7.9M mobile-trailer_vp9.webm
As we can see they are both significantly smaller than the source file. The
av1 version is slightly larger, so we would have to tweak the averate bitrate setting to get a smaller result, we could decrease
-b:v 3M to something like
We can go with the result as is, which looks slightly sharper, especially in areas of the frame where a lot of motion happens (like the waterfall on dark rock).
Remove Audio Track from Video
If you want to use a video as a replacement for a GIF that auto plays on a loop for comedic effect or to visualise something, you can remove the audio track instead of just muting it on the video element itself, which is a requirement for some browsers to play it at all:
ffmpeg -i mobile-trailer.mp4 -an -c:v libvpx-vp9 -b:v 3M -cpu-used 8 mobile-trailer_vp9_no_audio.webm
-anoption will not encode any audio tracks
This will also reduce the file size slightly:
7.7M mobile-trailer_vp9_no_audio.webm 7.9M mobile-trailer_vp9.webm
Lastly, we can implement it as an auto-playing element with this HTML snippet:
<video muted autoplay loop playsinline> <source src="/assets/mobile-trailer_vp9.webm" type="video/webm" /> </video>
If your video is not auto-playing in Safari, you likely forgot the
Converting GIFs to WEBM
If you have a hand full of GIFs and you're trying to replace them, you can use the ffmpeg line below:
ffmpeg -y -i jeannie.gif -c:v libvpx-vp9 -cpu-used 8 -b:v 500K -pix_fmt yuv420p jeannie.webm
which saves you some bandwidth as well, which will have more extreme effects on larger GIFs with higher framerates, even though a GIF is limited to much fewer colours.
656K jeannie.gif 176K jeannie.webm
Let me know what sort of video you're producing and if the post was slightly useful
Music by Alexander Nakarada (www.serpentsoundstudios.com) Licensed under Creative Commons BY Attribution 4.0 License https://creativecommons.org/licenses/by/4.0/