38

It's time to replace GIFs with AV1 video

 4 years ago
source link: https://www.tuicool.com/articles/hit/QVBfa2a
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

It is 2019 and we need to make a decision about GIFs ( no, not that one! We’re never going to be able to decide that one! ). GIFs take up a massive amount of space (often multiple megabytes!) and if you’re a web developer, then that’s completely against your ethos! As a web developer, you want to minimize the bits your users need to download so that your website loads fast. That’s why you minify javascript, optimize PNGs, JPEGs and sometimes turn JPEGs to WebPs as well . But then what about the venerable GIF?

Where we are going, we don’t need no GIFs!

If your goal is to improve your website your loading performance, then a GIF needs to be yanked! But then how do you have moving pictures? The answer is a video. And in most cases, you’ll get better quality as well as almost 50-90% size savings! In life, most things have a pro and a con. When you’re replacing a GIF with a video, in majority of the cases you’ll be hard pressed to find a con

Replace all the GIFs!

Fortunately, replacing GIFs with video has now been common for a few years so the tools needed to pull off this trick are already in play. In this blog, I’m not going to break new ground, but improve upon what already exists. So, here’s the lowdown on what you can currently do:

  1. Take a GIF and convert it into video
  2. Encode it with H.264 or VP9 codec i.e. compress it and package in a MP4 of WebM container
  3. Replace animated GIF <img> elements with <video>
  4. Set the video to play automatically, sliently and in a loop to replicate the GIF functionality

Google has a good documentation page describing the process.

It is 2019

It’s 2019. Tech moves forward and we need to move with it. Until now you’ve had two choices of codecs that are widely adopted across all browsers and platforms for encoding the video:

  1. H.264 – Introduced in 2003 and the most widely used codec today
  2. VP9 – Introduced in 2013 and achieves 50% more compression compared to H.264

Remember, our goal is to reduce the humongous GIF to as small a size as possible to improve our webpage loading time. It wouldn’t be 2019 if we didn’t have a new video compression standard we could encode to. This is called AV1. With AV1, we are able to achieve ~30% more compression compared to VP9. So, now we’re up to about 80% better than H.264! Exciting! :)

Serving you AV1 since 2019

Recently, support for decoding AV1 video has been enabled in Google Chrome 70 and Mozilla Firefox 65 . Now, all we need to do is serve an AV1 video for our users and if they haven’t updated their browsers to the latest version (they really should!) , we’ll fall back to a H.264 or VP9 video. If you read my previous blog, this is what I did . I created a video tag like below which allowed me to serve the videos in this preference order - AV1 -> VP9 -> H.264 . If a user has a really old browser and cannot decode any of the videos, then they would just get the GIF file. :(

<video style="display:block; margin: 0 auto;" autoplay loop muted playsinline poster="RollingCredits.jpg">
  <source src="media/RollingCredits.av1.mp4" type="video/mp4">
  <source src="media/RollingCredits.vp9.webm" type="video/webm">
  <source src="media/RollingCredits.x264.mp4" type="video/mp4">
  <img src="media/RollingCredits.gif">
</video>

The AV1 recipe

Creating an AV1 video is pretty simple. Download the latest build of ffmpeg for your platform from here and use the below commandline. We’re going to be using a 2-pass encoding mode to achieve a target bitrate. For this, we’ll run ffmpeg twice. In the first pass we’ll output to a null file descriptor, not an actual file. This generates a logfile that ffmpeg needs for the second pass.

# Linux or Mac
## Pass 1
ffmpeg -i input.mp4 -c:v libaom-av1 -b:v 200k -filter:v scale=720:-1 -strict experimental -cpu-used 1 -tile-columns 2 -row-mt 1 -threads 8 -pass 1 -f mp4 /dev/null && \
## Pass 2
ffmpeg -i input.mp4 -pix_fmt yuv420p -movflags faststart -c:v libaom-av1 -b:v 200k -filter:v scale=720:-1 -strict experimental -cpu-used 1 -tile-columns 2 -row-mt 1 -threads 8 -pass 2 output.mp4

# Windows
## Pass 1
ffmpeg.exe -i input.mp4 -c:v libaom-av1 -b:v 200k -filter:v scale=720:-1 -strict experimental -cpu-used 1 -tile-columns 2 -row-mt 1 -threads 8 -pass 1 -f mp4 NUL && ^
## Pass 2
ffmpeg.exe -i input.mp4 -pix_fmt yuv420p -movflags faststart -c:v libaom-av1 -b:v 200k -filter:v scale=720:-1 -strict experimental -cpu-used 1 -tile-columns 2 -row-mt 1 -threads 8 -pass 2 output.mp4

Here’s an explanation of what the command line options do

-i - Used to specify the input file

-pix_fmt - Use to specify the 4:2:0 chroma subsampling for the color information in the video. There are many different pixel formats but 4:2:0 is the most compatible, hence we specify that here.

-c:v - Used to specify the encoder to use i.e. AV1 in this case

-b:v – Used to specify the average bitrate we want to achieve

-filter:v scale - ffmpeg’s scale filter to reduce the resolution of the video. We specify this in the X:-1 format which tells ffmpeg to reduce the width of the video to X while and automatically set height that maintains the aspect ratio 

-strict experimental - Used because AV1 is a fairly new encoder

-cpu-used - Horribly named parameter but this is way to select the level of quality we want to achieve. Valid values are 0-4. Lower values (i.e. closer to 0) mean more quality as well as more encoding time taken

-tile-columns - Used to achieve multi-threading. Tells the AV1 encoder to split the scene into separate columns which can then be encoded independently of each other, thereby increasing CPU usage 

-row-mt – Similar concept as columns above but for rows within those columns

-threads - # of threads the encoder can use

-pass - Which pass the command executes

-f - Only used in the first pass. Specifies the format of the output file in the second pass i.e. MP4 in this case

-movflags faststart - Enables fast start of video by moving some data to the beginning of the file. This  allows the video to be played before it is completely downloaded

Test Results

The proof is in the pudding, right? Let’s see why AV1 is the right codec for this choice of work. I took the open source video Tears of Steel available here https://mango.blender.org/ and encoded it to approximately similar bitrates for AV1, VP9, H.264 codecs. The resulting files are looping below so you can compare between them. For generating the GIF, I used the below command. To reduce the size of the GIF, I scaled the GIF to 720px wide and 12 fps instead of 24 fps source video.

./ffmpeg -i /mnt/c/Users/kasing/Desktop/ToS.mov -ss 00:08:08 -t 12
-filter_complex "[0:v] fps=12,scale=720:-1" -y scene2.gif
NOTE: If a file below doesn’t load for you, it’s possible you’ll need to update your browser. If your browser doesn’t work, I suggest using browsing in a Chromium based browser such as Chrome, Vivaldi, Brave or Opera

Scene 1 @ 200 Kbps

This is a high motion scene so it really stresses the encoders at low bitrates. We quickly see how bad H.264 is at this bitrate exhibiting extreme blockiness. VP9 improves things a bit but you can still notice some blockiness. AV1 clearly wins in this test rendering a clearly better image.

H.264

VP9

AV1

Scene 2 @ 200 Kbps

This scene shows off a lot of translucent CGI generated content. The results are a lot closer than the last scene but overall AV1 ends up being the best.

H.264

VP9

AV1

Scene 3 @ 100 Kbps

In this scene, we really dial down the bitrate to 100 Kbps and the results are no surprise. AV1 maintains it’s advantage at this low bitrate as well!

H.264

VP9

AV1

Encore

To really drive home the point of the amount of space savings compared to a GIF – The total size of all the videos embedded above is …. 1.62 MB!! That’s right. 1,708,032 freakin bytes! For comparison, here’s the GIF and AV1 video size for each of the scenes

GIF AV1 Scene 1 11.7 MB 0.33 MB Scene 2 9.06 MB 0.18 MB Scene 3 5.62 MB 0.088 MB

Absolutely mind blowing! Isn’t it?

Reach out if you have any questions! Feel free to follow me on


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK