Mux H.265 and Opus into WebM Using FFmpeg
This article provides a concise guide on handling raw H.265 (HEVC) video and Opus audio streams with FFmpeg. Due to strict format specifications enforced by FFmpeg, muxing an H.265 stream directly into a WebM container without re-encoding is not supported. Below, you will find the technical reason for this limitation, the recommended lossless solution using Matroska (MKV), and the command required to produce a valid WebM file by transcoding the video stream.
The WebM Specification Constraint
The WebM container is an open-source format built as a restricted subset of the Matroska (MKV) specification. To guarantee broad compatibility across web browsers, the WebM format strictly permits only specific codecs:
- Video: VP8, VP9, and AV1
- Audio: Vorbis and Opus
Because H.265 is not part of the WebM specification, FFmpeg's WebM
muxer will reject the operation and return an error if you attempt a
stream copy (-c copy) with an H.265 source. Depending on
your needs, you must either wrap the streams in an MKV container to
avoid re-encoding or transcode the video to a supported WebM codec.
Option 1: Lossless Muxing Using Matroska (Recommended)
If you must preserve the original H.265 stream without re-encoding or
quality loss, use the Matroska (.mkv) container. Matroska
uses the same underlying structure as WebM but natively supports H.265
and Opus together.
Run the following command:
ffmpeg -f hevc -i input.h265 -i input.opus -c copy output.mkvCommand Breakdown:
-f hevc: Explicitly declares the format of the raw H.265/HEVC elementary stream (useful if FFmpeg cannot detect the raw stream format automatically).-i input.h265: The input video file.-i input.opus: The input audio file.-c copy: Direct stream copy mode; packages the streams into the container without re-encoding, preserving original quality and finishing almost instantly.
Option 2: Transcoding H.265 to VP9 for a True WebM File
If your target application strictly requires a .webm
file extension and container, the H.265 video must be transcoded to VP9
(or AV1). The Opus audio stream can still be copied directly without
re-encoding.
Run the following command:
ffmpeg -f hevc -i input.h265 -i input.opus -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a copy output.webmCommand Breakdown:
-c:v libvpx-vp9: Encodes the video stream into the standard VP9 codec.-crf 30 -b:v 0: Enables Constant Quality mode (CRF values for VP9 typically range from 15–35, where lower values yield higher quality).-c:a copy: Copies the Opus audio stream directly into the container without re-encoding.