MP4 to VP9 WebM encoding with FFmpeg

WebM the modern video container encoded by libvpx-vp9 or VP9 for short, handles differently to h264 when encoding with FFmpeg. Here is a shorter guide derived from the FFmpeg VP9 docs.

The basis of these commands needs to call FFmpeg, specify the input file and then the video codec which is libvpx-vp9

ffmpeg -i in.mp4 -c:v libvpx-vp9

Bitrate control modes

The main part is the rate control mode, there are multiple with some being more specific and controlling in the outcome.

Average bitrate

This mode will try and achieve close to a set bitrate throughout the whole video, which means it is not an efficient choice.

ffmpeg -i in.mp4 -c:v libvpx-vp9 -b:v 1.5M output.webm

The example is for a target bitrate of 1.5MBit/s

Two-pass

This mode is recommended, with the method being a target bitrate is set and targeted twice for max effectivness by using -pass 1 and -pass 2.

Target bitrate:

ffmpeg -i in.mp4 -c:v libvpx-vp9 -b:v 1.5M -pass 1 -f null /dev/null && \
ffmpeg -i in.mp4 -c:v libvpx-vp9 -b:v 1.5M -pass 2 out.webm

Constant quality:

ffmpeg -i in.mp4 -c:v libvpx-vp9 -b:v 0 -crf 28 -pass 1 -f null /dev/null && \
ffmpeg -i in.mp4 -c:v libvpx-vp9 -b:v 0 -crf 28 -pass 2 out.webm

Pass 1 can skip audio encoding with -an.

Constant quality

A popular option from h264 encoding, a quality value is given between 0 and 63 with lower values meaning higher quality. It is recommended to use a value between 15 and 35. To use constant quality -b:v must be set and at zero: -b:v 0

ffmpeg -i in.mp4 -c:v libvpx-vp9 -crf 28 -b:v 0 out.webm

Constrained quality

This mode uses the quality value from constant quality but also keeps the bitrate below a specified upper bound. This method is said as a best case for consistency when bulk encoding.

Max upper:

ffmpeg -i in.mp4 -c:v libvpx-vp9 -crf 28 -b:v 1500k out.webm

Min and max:

ffmpeg -i in.mp4 -c:v libvpx-vp9 -minrate 400k -b:v 1500k -maxrate 2200k out.webm

Constant Bitrate

Encodes your video to a set bitrate

ffmpeg -i in.mp4 -c:v libvpx-vp9 -minrate 1.5M -maxrate 1.5M -b:v 1.5M out.webm

Lossless

Lossless encoding can be achieved with -lossless 1

ffmpeg -i in.mp4 -c:v libvpx-vp9 -lossless 1 out.webm

Speed and quality

-deadline is the main option for VP9 encoding speed, as per media encoding lore the slower options do a more efficient encode.

  • good (default) is the recommended.
  • best has the finest compression (slow).
  • realtime live and fast encoding.

-cpu-used is how efficient the compression will be, when using a deadline of good or best the value that can be set must be between 0 and 5.

Default it is 0, 1 or 2 will increase speed but cost in quality and rate control. A value of 4 or 5 disables rate-distortion optimization thus having a greater impact on quality.

To further utilize modern CPU’s when encoding row-based multithreading can be turned on with -row-mt 1 this can help dramatically.

More encoding speed can be achieved with specifying the CPU threads to use when encoding with -threads an example being: -threads 16.

ffmpeg -i in.mp4 -c:v libvpx-vp9 -row-mt 1 -threads 16 -cpu-used 2 -deadline good -crf 21 -b:v 0 out.webm