How to make HEVC, H265 and VP9 videos with an alpha channel for the web

Next generation video codecs create interesting web design possibilities. Here’s how to create these videos with the widest possible browser support

We’re well into the second decade of widespread video on the web. Video is used everywhere, and it’s slowly becoming part of the fabric of web design. Think full page background videos, cinemagraphs, explainer graphics and so on. Safari now even supports video inside the img tag.

However, having videos on the web which contain an alpha channel opens up interesting possibilities. It’s now possible to achieve green screen effects just using CSS and a video! I can think of many other good use cases for games, interactive videos and animations.

So how do we go about implementing this today? We’ll need to use a video codec called HEVC, the successor to H264 that delivers the same performance at 50% of the file size.

As for browser support, HEVC is only supported in Safari on iOS 11 and macOS High Sierra. For HEVC with alpha channel, users will need iOS 13 and macOS Catalina. HEVC is unsupported in Chrome, Firefox, Opera and Edge – so we’ll have to fall back to VP9 which has had alpha channel support since 2013.

However if my visitors are anything to go by, Catalina is being adopted quickly. The early adopters visiting Aura love to live on the bleeding edge, and over half of them are already running macOS 10.15.

This is a relatively involved process, so I’ll break it down into a number of steps.

  1. Creating a composition with an alpha channel
  2. Encoding HEVC with an alpha channel using Compressor
  3. Supporting other browsers with VP9
  4. Playback on the web

Creating a composition with an alpha channel

We’ll need source material with an alpha channel. I’m using After Effects, but any animation tool that can export an image sequence will do. It’s important to use an image format that supports fully variable alpha channels like TIFF or PNG.

A simple After Effects composition of a bouncing ball against a transparent background

When you add the composition to the render queue, you’ll also need to ensure that you export the image sequence with RGB + Alpha. You can find this in the output settings of the render queue.

I’ve created a simple animation of a semi-opaque ball bouncing along a path to demonstrate the technique, but almost anything is possible, including layering multiple videos on top of one another, or stacking videos on top of HTML content.

Encoding HEVC with an alpha channel using Compressor

Now we need to convert the image sequence into a video. For most of my video encoding tasks I turn to the excellent FFMPEG which allows creation of almost any permissable combination of codecs and containers. FFMPEG uses the open source x265 project for HEVC encoding.

Unfortunately I’ve been unable to create a video with an alpha channel using this codec, and browsing the source code or the open issues has not yielded any answers. I suspect it’s an issue with the pixel format but if you know the answer please let me know.

Apple provides a supplementary tool to Final Cut Pro called Compressor which ships with its own HEVC encoder. Nestled in amongst the release notes for 4.4.5 you’ll find the following:

Supports HEVC playback with alpha channel

Encodes HEVC with alpha channel in a QuickTime movie file

Compressor is not free, but is available separately from Final Cut Pro on the Mac App Store.

Ensure that the alpha channel is preserved when configuring the video properties

Using Compressor is straightforward, the only thing to note is that you can only create alpha channel videos when exporting a Quicktime movie. The setting to preserve alpha is not checked by default, ensure you set it as above.

Supporting other browsers with VP9

We’re in the throes of yet another format war, and as it stands Chrome and Firefox are unable to play HEVC video. But they have been well ahead of the curve and merged in support for alpha transparency in VP9 all the way back in 2013.

Even better, the FFMPEG encoder supports encoding with alpha transparency. Using the libvpx-vp9 encoder, creating a video is as easy as this:

ffmpeg -framerate 60
       -i frame_%05d.tif
       -pix_fmt yuva420p
       -an
       output.webm

There’s only a few things to note here. I’m setting the framerate to 60 frames per second. The i flag tells FFMPEG what the input frames are. pix_fmt sets the pixel format. We want the alpha channel, so we use yuva420p as opposed to yuv420p. Finally, an ensures that we won’t add an audio track.

Playback on the web

The final stage is supporting this on the web. I’m just layering this video onto a background image pattern. The code is very straightforward.

<div style="background-image: url('pattern.png'); background-size: 50%;">
  <video width="640" height="360" autoplay muted loop playsinline>
    <source src="bounce.mov" type="video/quicktime">
    <source src="bounce.webm" type="video/webm">
  </video>
</div>

And when rendered in browser it looks like this:

It’s an exciting step forward for video on the web, and I can’t wait to see how other web designers will use it. I will be using this technique on Aura soon, both in the app and on this site.

Useful Resources

Found this useful? Any questions or comments, let me know on Twitter. For more like this, take a look at other articles about macOS development.