Search Docs
Loading...
Skip to content

To WebM

Export video compositions as WebM files with VP8, VP9 or AV1 video and Opus or Vorbis audio, and keep the transparency of the page.

5 mins
estimated time
GitHub

WebM is an open video format. Its codecs are royalty-free, so you can encode and publish them without a patent license. The engine bundles the VP8, VP9, AV1, Opus and Vorbis encoders, so a WebM export works the same on iOS and macOS, with no system codec.

This guide covers how to export a page to WebM, choose the codecs and keep the transparency of the page.

Export to WebM#

Call engine.block.exportVideo(_:mimeType:options:) with a page block and MIMEType.webm. The call returns an AsyncThrowingStream<VideoExport, Error> that yields .progress events while it encodes, and a final .finished(video:) event with the encoded Blob.

let videoStream = try await engine.block.exportVideo(page, mimeType: .webm)
for try await event in videoStream {
switch event {
case let .progress(_, encoded, total):
print("Encoded \(encoded) of \(total) frames")
case let .finished(video: blob):
try blob.write(to: exportsDirectory.appendingPathComponent("video.webm"))
}
}

Without options, the export encodes VP9 video and Opus audio. Every other VideoExportOptions value, such as targetWidth, framerate, videoBitrate, timeOffset and duration, works the same as for an MP4 export. So does cancellation.

Choose the Codecs#

Set videoCodec and audioCodec in VideoExportOptions to choose the codecs. A WebM file holds .vp8, .vp9 or .av1 video and .opus or .vorbis audio.

let codecOptions = VideoExportOptions(
videoBitrate: 4_000_000,
videoCodec: .vp8,
audioCodec: .vorbis,
)
let codecStream = try await engine.block.exportVideo(page, mimeType: .webm, options: codecOptions)
for try await event in codecStream {
if case let .finished(video: blob) = event {
try blob.write(to: exportsDirectory.appendingPathComponent("video-vp8.webm"))
}
}
  • VP8 is the oldest of the three video codecs, and almost every player decodes it.
  • AV1 makes the smallest file at the same quality, but it takes the longest to encode.
  • A codec that WebM cannot hold, such as .h264 or .aac, fails the export. The engine does not change the codec for you.

Keep the Transparency#

Set exportAlpha: true to keep the transparent areas of the page. The WebM file then has a second video stream with the transparency. Only .vp8 and .vp9 keep it.

// Shrink the video and hide the page background, so the area around the video is transparent.
try engine.block.setFillEnabled(page, enabled: false)
try engine.block.setWidth(video, value: 640)
try engine.block.setHeight(video, value: 360)
let alphaOptions = VideoExportOptions(videoCodec: .vp9, exportAlpha: true)
let alphaStream = try await engine.block.exportVideo(page, mimeType: .webm, options: alphaOptions)
for try await event in alphaStream {
if case let .finished(video: blob) = event {
try blob.write(to: exportsDirectory.appendingPathComponent("video-alpha.webm"))
}
}
  • Hide the page fill, and leave part of the page uncovered. Otherwise no area of the page is transparent.
  • exportAlpha with .av1 or with MIMEType.mp4 fails the export.
  • Whether a player shows the transparency depends on the player. AVFoundation does not play WebM.

Troubleshooting#

  • The export fails with ENCODE.VIDEO_CODEC_CONTAINER_MISMATCH or ENCODE.AUDIO_CODEC_CONTAINER_MISMATCH: The codec does not fit the file type. Use .vp8, .vp9 or .av1 with .opus or .vorbis for WebM, or leave the codecs at .auto.
  • The export fails with ENCODE.VIDEO_ALPHA_UNSUPPORTED: Use .vp8 or .vp9 with MIMEType.webm when exportAlpha is true.
  • The export is slow: The engine encodes WebM in software. Use VP9 or VP8 instead of AV1, or lower targetWidth, targetHeight and framerate.

API Reference#

Method Description
engine.block.exportVideo(_:mimeType:options:) Export a page block as a video. Returns an AsyncThrowingStream<VideoExport, Error>.
VideoExportOptions(videoBitrate:videoCodec:audioCodec:exportAlpha:) Select the codecs, the transparency stream and the bitrate.
engine.block.setFillEnabled(_:enabled:) Hide the page fill before a transparent export.

WebM Export Options#

Option Type Default Description
videoCodec VideoCodec .auto .vp8, .vp9 or .av1. .auto picks VP9 for .webm.
audioCodec AudioCodec .auto .opus or .vorbis. .auto picks Opus for .webm.
exportAlpha Bool false Keeps the transparency of the page. Only .vp8 and .vp9.

Next Steps#