Kit Cross

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

HEVC encoding on macOS Catalina now supports encoding an alpha channel, enabling many creative options on the web and inside apps.

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.

Videos on the web with an alpha channel open up many 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.

How do we use 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.

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 directly in Finder
  3. Encoding HEVC in the terminal with avconvert
  4. Encoding HEVC with Compressor
  5. Supporting other browsers with VP9
  6. 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.

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 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.

Encoding HEVC using Finder

Video encoding is built right into Finder. Just right click on a video file and choose ‘Encode Selected Video Files’.

Context menu option to encode video in Finder

You’re limited to a couple of HEVC presets, but at least you get the option to preserve the alpha channel.

Encoding HEVC in the terminal

Encoding HEVC using avconvert in the terminal

The same tool as above, but without the user interface. You get a few more options but you’re still limited to a couple of HEVC presets.

avconvert --preset PresetHEVC1920x1080WithAlpha --source source.mov --output output.m4v

Encoding HEVC with Compressor

For more flexibility, look to Compressor, a supplementary tool to Final Cut. 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 Chrome and Firefox are unable to play HEVC. But they have merged support for alpha transparency in VP9 back in 2013.

FFMPEG encoder supports encoding with VP9 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.

web video