Using AV1 video codec to reduce web page size
This post is part of the series 'Web Performance'. Be sure to check out the rest of the blog posts of the series!
- Website performance: Why and how to measure?
- Website performance: How I've improved the performance of this website?
- Using AV1 video codec to reduce web page size (this post)
- Using Avif codec for images to reduce web page size
Videos represent a large part of the internet traffic. According to Cisco, it represents about 80% of the total traffic! So, reducing the size of video files can help to reduce the amount of data that is transferred over the internet, and it may reduce the hosting costs of your website.
AV1 is the next-generation codec developed by the Alliance for Open Media (AOM). AV1 improves compression efficiency by ~30% over the previous state-of-the-art video codec, VP9, and by ~50% over x264.
AV1 is currently supported by Chrome, Firefox, Opera, and Edge, so about 75% of usages. Apple should support AV1 in the future.
As web supports progressive enhancement, you can provide multiple versions of the same video. This means you can provide an AV1 and a H.264 version of the same video to support all browsers. The browser will choose the best video for the user. So, there is no reason to not use AV1 today!
Can I use: MPEG-4/H.264 video format
#Encoding videos to AV1
You can use ffmpeg
to convert video to AV1.
Download ffmpeg: https://ffmpeg.org/download.html
Convert the video to AV1:
Shell# Adjust the crf value to change the quality and size of the video. # The valid CRF value range is 0-63, with the default being 50. # Lower values correspond to higher quality and greater file size. ffmpeg -i input.mp4 -c:v libsvtav1 -crf 50 -b:v 0 -c:a libopus -movflags faststart output.mp4
You can better control the output size using a 2-pass encoding:
Shell# Change -b:v 2M to change the bitrate and control the output size # Linux ffmpeg -i input.mp4 -c:v libsvtav1 -b:v 2M -pass 1 -an -f null /dev/null ffmpeg -i input.mp4 -c:v libsvtav1 -b:v 2M -pass 2 -c:a libopus -movflags faststart output.mp4 # Windows ffmpeg -i input.mp4 -c:v libsvtav1 -b:v 2M -pass 1 -an -f null NUL ffmpeg -i input.mp4 -c:v libsvtav1 -b:v 2M -pass 2 -c:a libopus -movflags faststart output.mp4
The documentation of all available options for AV1 can be found at:
#Updating the <video>
element
You now have 2 video files. One using the H264 codec and another one using the AV1 codec. You have to set both sources for the <video>
element.
Both videos having the same mime type video/mp4
, the browser is not able to choose the best video for the user. The solution is to set the codecs
parameter of the mime type (e.g. video/mp4; codecs="av01.0.04M.08"
).
<video>
<source src="./demo-av1.mp4" type='video/mp4; codecs="av01.0.04M.08"; profiles="isom,av01,iso2,mp41"'>
<source src="./demo-x264.mp4" type="video/mp4">
</video>
However, the codecs
is not trivial to determine. The first part av01
is constant for AV1. The next parts depend on how the file is encoded (documentation). This means you may need a tool to get the right value for the codecs
parameter.
##Finding the codecs
parameter
To find the value of the codecs
parameter, you can use the following website: https://gpac.github.io/mp4box.js/test/filereader.html:
Or you can use some nodejs code to get it:
npm install mp4box@0.5.2
import { createFile } from 'mp4box';
import fs from 'fs';
const filePath = process.argv[2];
const content = await fs.promises.readFile(filePath);
let buffer = content.buffer;
buffer.fileStart = 0;
var mp4boxfile = createFile();
mp4boxfile.onError = e => console.error(e);
mp4boxfile.onReady = info => console.log(info.mime);
mp4boxfile.appendBuffer(buffer);
mp4boxfile.flush();
You can now call the application to get the mime type:
node index.mjs input.mp4
##Validating the browser use the AV1 video
You can check your browser is using the right source using the Dev Tools. The property currentSrc
shows the source used by the browser:
#Microsoft Edge
It seems Microsoft Edge selects the av1 video. However, it cannot play it unless the AV1 Video Extension is installed. The resulting experience is bad, as most users won't see the video. A possible workaround is to detect Microsoft Edge and remove the av1 source.
(function () {
for (let brand of navigator.userAgentData.brands) {
if (brand.brand == "Microsoft Edge") {
for (let element of document.querySelectorAll("video>source[type*='av01.']")) {
let parentElement = element.parentElement;
// Remove the <source> element
element.remove();
// force reload the video, so the browser loads the new sources
parentElement.load();
}
}
}
})();
#Additional resources
- Wikipedia - AV1
- Web video codec guide
- The "codecs" parameter in common media types
- AV1 Video Encoding Guide
- ffmpeg codecs - libsvtav1
Do you have a question or a suggestion about this post? Contact me!