This codelab is an introduction to encoding video content for the web using the VP9 codec. It is primarily for developers and media professionals who want to reduce the size of video assets.

Why Is Video Compression Important for the Web?

Video has long been an essential part of the web, and increases in the quality, quantity, and usage of videos has put more pressure on network bandwidth. Video currently accounts for 70% of internet traffic and is rising steadily. As processors and creation tools continue to improve, improved compression algorithms are a web essential for managing storage and bandwidth constraints.

What is VP9?

VP9 is a next-generation video compression format developed by the WebM Project. The codec is open source and royalty free. VP9 supports the full range of web and mobile use cases from low bitrate compression to high-quality ultra-HD, with additional support for 10/12-bit encoding and HDR.

VP9 can reduce video bit rates by as much as 50% compared with other known codecs. It is supported for adaptive streaming and is used by YouTube, Netflix, and other leading web video providers.

VP9 decoding is supported on over 2 billion endpoints including Chrome, Opera, Edge, Firefox and Android devices, as well as millions of smart TVs.

This codelab will walk you through creating your own VP9 encodes with FFMpeg.

What you'll learn

What you'll need

Step 1: Get Sample Source Video

The Tears of Steel short movie covers a range of test cases, including action sequences and animation.

To test low-bitrate encoding profiles (for web and mobile), we selected a 10 second clip from the WebM 1080p version of the movie. This file is encoded using VP8 video, compressed at about 6Mbps, and features both filmed and synthetic content -- a suitable starting point for web and mobile compression testing.

Right Click + Save 1080p Source Clip

Step 2: Get FFMpeg

A variety of encoding products and cloud service providers allow you to encode VP9 video. This codelab will use FFMpeg, an open source encoding tool. If you do not already have FFMpeg installed, it is available across a variety of platforms using the link below:

FFMpeg Downloads Page

FFMpeg is a command-line program. Once you have it installed, you can perform encodes from the command line.

Step 1: Encode the Source Video

To get started, we will encode the source video using a basic FFMpeg command line.

ffmpeg -i tears_of_steel_1080p--00_00_35-00_00_45.webm \
  -b:v 2000k -c:v libvpx-vp9 -c:a libopus output.webm

This command tells FFMpeg to:

Step 2: Play Back the VP9 File

You can play WebM/VP9 in most major browsers, including Firefox, Opera, Chrome and Microsoft Edge. In Chrome, you can drag the file into a browser tab.

Every video has a frame size (indicating the pixel width and height). The following FFMpeg command-line parameter can be used to control the output video frame size for VP9 encoding: -vf scale=<width>x<height>

Example:

ffmpeg -i tears_of_steel_1080p--00_00_35-00_00_45.webm -vf scale=640x480 \
  -b:v 750k -c:v libvpx-vp9 -c:a libopus res_output.webm

This command tells FFMpeg to resize the 1920x1080 video down to 640x480.

Smaller resolutions are lower quality, but larger resolutions require more bandwidth, more processing power to decode, and may not be supported on older devices. For VP9, 640x480 is considered a safe resolution for a broad range of mobile and web devices.

VP9 supports several different bitrate modes:

CQ mode is recommended for file-based video (as opposed to live streaming). The following FFMpeg command-line parameters are used for CQ mode:

CQ Mode Commands:

b:v <arg>

Sets target bitrate (e.g. 500k)

minrate <arg>

maxrate <arg>

Sets minimum and maximum bitrate.

crf <arg>

Sets maximum quality level. Valid values are 0-63, lower numbers are higher quality.

Use following FFMpeg command to create a medium-quality 640x480 video file using CQ mode, with an average bitrate of 750kbps and maximum quality constrained to 33.

ffmpeg -i tears_of_steel_1080p--00_00_35-00_00_45.webm -vf scale=640x480 \
  -b:v 750k -crf 33 -c:v libvpx-vp9 -c:a libopus bitrate_output.webm

Bitrate will vary depending upon the quality you wish to achieve, and the resolution of the video. A full set of recommendations for bitrates at various resolutions can be found here.

Compressing video is a trade-off between the quality of the output, and the amount of time it takes to create it. Generally speaking, you can always get higher quality by allowing more time to encode, but the time required to get the highest possible quality may be impractical.

VP9 offers several settings to balance quality and speed:

These two types of settings are controlled by several command-line parameters:

Speed/Quality Commands:

threads

Indicates the number of threads to use during encoding.

quality

May be set to good, best, or realtime

speed

This parameter has different meanings depending upon whether quality is set to good or realtime. good valid values are 0-5, with 0 being the highest quality and 5 being the lowest. realtime valid values are 0-15; lower numbers mean higher quality.

tile-columns

Tiling splits the video into rectangular regions, which allows multi-threading for encoding and decoding. The number of tiles is always a power of two. 0=1 tile, 1=2, 2=4, 3=8, 4=16, 5=32.

Use the following FFMpeg command to create a 640x480 file with quality set to good and speed set to 4 (medium quality):

ffmpeg -i tears_of_steel_1080p--00_00_35-00_00_45.webm -vf scale=640x480 \
  -b:v 750k -quality good -speed 4 -crf 33 -c:v libvpx-vp9 -c:a libopus \
  speed_output.webm

Your choices for quality and speed settings may vary depending upon resolution and available processing power. A full set of recommendations can be found here.

You've finished the VP9 compression code lab and successfully explored many key features of VP9 in FFMpeg!

Hopefully it's clear to you how VP9 can help make your video assets smaller and more efficient to transmit over the web. For more information consider following the WebM Mailing List.