Converting video to WebM with ffmpeg/avconv

Note: This information is based on the FFmpeg Wiki on VP9 encoding. Please refer to that article for more information – it will be continuously maintained and extended. For the best results you should use the a recent version of ffmpeg by downloading it from their website (a static build will suffice; it contains the libvps-vp9 encoder).

Variable Bit Rate

VBR encoding gives you the optimal overall quality, since the encoder can freely choose how many bits to assign to a frame. Choose this mode unless you are preparing videos for constant-bitrate streaming.

Option 1: Constant quality encoding

Typically, if you do not want to target a specific file size, you should let the bitrate vary freely, as that will lead to the highest quality. You can do this by setting the bitrate to 0 and the constant rate factor (CRF) to the target quality level:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 output.webm

CRF value can be from 0–63. Lower values mean better quality. Recommended values range from 15–35, with 31 being recommended for 1080p HD video. Google has a guide with more info on that.

Option 2: Two-pass encoding with a target bitrate

If you want your file to have a specific target bitrate or file size, you need to specify the rate and use two-pass encoding (which will ensure an optimal quality distribution). Here we're choosing 5 MBit/s, which should be enough for 1080p content.

ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 5M -pass 1 -f webm /dev/null && \
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 5M -pass 2 output.webm

Windows users need to use NUL instead of /dev/null, and a ^ instead of \.

Constant Bit Rate

First of all, libvpx offers constant bitrate and variable bitrate encoding modes. Constant bitrate should be avoided whenever possible (unless you target a specific file size or streaming scenario), since the average quality per file size will be worse. Still, you could try setting a constant bitrate if nothing else works for you, e.g. with 1 MBit/s:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -minrate 5M -maxrate 5M -b:v 5M output.webm

Look at the output and increase or decrease the bit rate to your liking (or file size constraints). For example, you can use 500K or 5M, et cetera.

You have to specify -minrate, -maxrate and the bitrate -b:v in order for the encoder to use CBR. They all have to have the same value—otherwise it'll choose a different target bitrate instead and do VBR encoding, but with bad quality.

Audio

The current audio codec of choice for VP9 encoding is Opus. FFmpeg will choose the necessary encoder and its options by default. If you want to explicitly set -c:a libopus, you can do that as well. Refer to the libopus documentation for more options.