Mux Audio and Video Into WebM¶
This topic describes how to use the TTranscoder::run method to mux Vorbis audio and VP8 video into a WebM file.
The code snippets in this article are from the mux_webm_file macOS sample.
Linux and Windows samples are also available:
Source Files¶
For source we use the big-buck-bunny_trailer_vp8_vorbis.aud.webm and big-buck-bunny_trailer_vp8_vorbis.vid.webm files from the AVBlocks Assets repository. After downloading and unzipping you will find them in the aud and vid subdirectories.
Code¶
This code multiplexes two single-stream WebM files, one containing Vorbis audio and one containing VP8 video, into a WebM container file.
Initialize AVBlocks¶
Initialize the AVBlocks library before creating the transcoder, and shut it down after the muxing operation is complete.
int main(int argc, char* argv[])
{
Options opt;
switch(prepareOptions(opt, argc, argv))
{
case Command: return 0;
case Error: return 1;
case Parsed: break;
}
TLibrary library;
return mux(opt) ? 0 : 1;
}
Create the WebM Output Socket¶
The output socket is configured as StreamType::WebM. The sample adds one output pin for each input audio or video stream.
TMediaSocket outputSocket;
outputSocket.file(opt.output_file).streamType(StreamType::WebM);
Add Vorbis Audio Inputs¶
For each audio input, the sample creates an input socket for the source WebM file, adds it to the transcoder, and adds a Vorbis output pin to the WebM output socket.
// audio inputs
for (const auto& audioFile : opt.input_audio)
{
transcoder.addInput(
TMediaSocket()
.file(audioFile)
.streamType(StreamType::WebM)
);
outputSocket.addPin(TMediaPin()
.streamInfo(TAudioStreamInfo()
.streamType(StreamType::Vorbis)));
std::println("Muxing audio input: {}", audioFile);
}
Add VP8 Video Inputs¶
For each video input, the sample creates an input socket for the source WebM file, adds it to the transcoder, and adds a VP8 output pin to the WebM output socket.
// video inputs
for (const auto& videoFile : opt.input_video)
{
transcoder.addInput(
TMediaSocket()
.file(videoFile)
.streamType(StreamType::WebM)
);
outputSocket.addPin(TMediaPin()
.streamInfo(TVideoStreamInfo()
.streamType(StreamType::VP8)));
std::println("Muxing video input: {}", videoFile);
}
Run the Transcoder¶
After all input sockets and output pins are configured, the sample adds the output socket to the transcoder, opens it, runs the muxing operation, closes it, and prints the output file path.
transcoder.addOutput(outputSocket);
transcoder.open().run().close();
std::println("Output file: {}", opt.output_file);
return true;
Complete C++ Code¶
Here’s the complete working example from mux_webm_file.cpp:
#include <primo/avblocks/avb++.h>
#include <print>
#include <string>
#include "options.h"
#include "util.h"
using namespace primo::codecs;
using namespace primo::avblocks::modern;
bool mux(const Options& opt)
{
deleteFile(opt.output_file.c_str());
try {
TTranscoder transcoder;
transcoder.allowDemoMode(true);
TMediaSocket outputSocket;
outputSocket.file(opt.output_file).streamType(StreamType::WebM);
// audio inputs
for (const auto& audioFile : opt.input_audio)
{
transcoder.addInput(
TMediaSocket()
.file(audioFile)
.streamType(StreamType::WebM)
);
outputSocket.addPin(TMediaPin()
.streamInfo(TAudioStreamInfo()
.streamType(StreamType::Vorbis)));
std::println("Muxing audio input: {}", audioFile);
}
// video inputs
for (const auto& videoFile : opt.input_video)
{
transcoder.addInput(
TMediaSocket()
.file(videoFile)
.streamType(StreamType::WebM)
);
outputSocket.addPin(TMediaPin()
.streamInfo(TVideoStreamInfo()
.streamType(StreamType::VP8)));
std::println("Muxing video input: {}", videoFile);
}
transcoder.addOutput(outputSocket);
transcoder.open().run().close();
std::println("Output file: {}", opt.output_file);
return true;
} catch (const TAVBlocksException& ex) {
std::println(stderr, "AVBlocks error: {}", ex.what());
return false;
} catch (const std::exception& ex) {
std::println(stderr, "Error: {}", ex.what());
return false;
}
}
int main(int argc, char* argv[])
{
Options opt;
switch(prepareOptions(opt, argc, argv))
{
case Command: return 0;
case Error: return 1;
case Parsed: break;
}
TLibrary library;
return mux(opt) ? 0 : 1;
}
How to Run¶
See the build instructions for macOS and the mux_webm_file example for details.
Command Line¶
mux_webm_file --audio <Vorbis_file>.webm --video <VP8_file>.webm --output <output>.webm
Examples¶
List options:
./bin/x64/mux_webm_file --help
Usage: mux_webm_file --audio <input_Vorbis> --video <input_VP8> --output <output.webm>
-?, --help
-a, --audio input Vorbis files. Can be used multiple times
-v, --video input VP8 files. Can be used multiple times
-o, --output output file
Mux the WebM files big-buck-bunny_trailer_vp8_vorbis.aud.webm and big-buck-bunny_trailer_vp8_vorbis.vid.webm into the WebM file big-buck-bunny_trailer.webm:
mkdir -p ./output/mux_webm_file
./bin/x64/mux_webm_file \
--audio ./assets/aud/big-buck-bunny_trailer_vp8_vorbis.aud.webm \
--video ./assets/vid/big-buck-bunny_trailer_vp8_vorbis.vid.webm \
--output ./output/mux_webm_file/big-buck-bunny_trailer.webm