Simple Video Converter¶
Building a video converter using C++ and the AVBlocks Transcoder.
Source Video¶
For a video source we use the Wildlife.mp4 movie from the Internet Archive. The original format is an MP4 container with H.264/AVC video and AAC audio. On Windows we use the Wildlife.wmv version of the same movie.
Overview¶
These snippets are fully functional video converters. They take Wildlife.mp4 (Wildlife.wmv on Windows) as input and convert it to H.265/HEVC video and AAC audio in an MP4 container, saved as Wildlife_h265_aac.mp4.
macOS¶
Code¶
#include <primo/avblocks/avb.h>
#include <primo/platform/reference++.h>
#include <primo/platform/ustring.h>
using namespace primo;
using namespace primo::codecs;
using namespace primo::avblocks;
int main(int argc, const char *argv[]) {
Library::initialize();
auto inputFile = primo::ustring(L"Wildlife.mp4");
auto outputFile = primo::ustring(L"Wildlife_h265_aac.mp4");
auto inputInfo = primo::make_ref(Library::createMediaInfo());
inputInfo->inputs()->at(0)->setFile(inputFile);
if (inputInfo->open()) {
auto inputSocket = primo::make_ref(
Library::createMediaSocket(inputInfo.get())
);
// Start with same output as the input, which is MP4 / H.264 + AAC
auto outputSocket = primo::make_ref(inputSocket->clone());
// Change the video stream type to H.265 (HEVC)
// and the stream subtype to HEVC Annex B
auto outVideoStream = (VideoStreamInfo*)outputSocket
->pins()->at(0)
->streamInfo();
outVideoStream->setStreamType(StreamType::H265);
outVideoStream->setStreamSubType(StreamSubType::HEVC_Annex_B);
// Input is H.264/AVC at 700 kbps
// With H.265/HEVC we can use lower bitrate, e.g. 500 kbps
outVideoStream->setBitrate(500'000);
// Change the output file name to Wildlife_h265_aac.mp4
outputSocket->setFile(outputFile);
// Create Transcoder and configure it with
// the input and output sockets
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
// Allow demo mode for the transcoder when
// using the demo version of the library
transcoder->setAllowDemoMode(true);
// Run the transcoder
if (transcoder->open()) {
transcoder->run();
transcoder->close();
} else {
std::cerr << "transcoder->open() failed: "
<< primo::ustring(transcoder->error()->message())
<< std::endl;
}
}
Library::shutdown();
return 0;
}
How to run¶
Follow the steps in Create a Command Line Tool using CMake on macOS, but use the code from this article.
Download the Wildlife.mp4 sample file and save it in the project directory:
curl \
-L -o Wildlife.mp4 \
https://archive.org/download/WildlifeSampleVideo/Wildlife.mp4
Run the application. Wait for the Transcoder to finish - it will take a few minutes. The converted file Wildlife_h265_aac.mp4 will be in the project directory.
Linux¶
Code¶
#include <primo/avblocks/avb.h>
#include <primo/platform/reference++.h>
#include <primo/platform/ustring.h>
using namespace primo;
using namespace primo::codecs;
using namespace primo::avblocks;
int main(int argc, const char *argv[]) {
Library::initialize();
auto inputFile = primo::ustring(L"Wildlife.mp4");
auto outputFile = primo::ustring(L"Wildlife_h265_aac.mp4");
auto inputInfo = primo::make_ref(Library::createMediaInfo());
inputInfo->inputs()->at(0)->setFile(inputFile);
if (inputInfo->open()) {
auto inputSocket = primo::make_ref(
Library::createMediaSocket(inputInfo.get())
);
// Start with same output as the input, which is MP4 / H.264 + AAC
auto outputSocket = primo::make_ref(inputSocket->clone());
// Change the video stream type to H.265 (HEVC)
// and the stream subtype to HEVC Annex B
auto outVideoStream = (VideoStreamInfo*)outputSocket
->pins()->at(0)
->streamInfo();
outVideoStream->setStreamType(StreamType::H265);
outVideoStream->setStreamSubType(StreamSubType::HEVC_Annex_B);
// Input is H.264/AVC at 700 kbps
// With H.265/HEVC we can use lower bitrate, e.g. 500 kbps
outVideoStream->setBitrate(500'000);
// Change the output file name to Wildlife_h265_aac.mp4
outputSocket->setFile(outputFile);
// Create Transcoder and configure it with
// the input and output sockets
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
// Allow demo mode for the transcoder when
// using the demo version of the library
transcoder->setAllowDemoMode(true);
// Run the transcoder
if (transcoder->open()) {
transcoder->run();
transcoder->close();
} else {
std::cerr << "transcoder->open() failed: "
<< primo::ustring(transcoder->error()->message())
<< std::endl;
}
}
Library::shutdown();
return 0;
}
How to run¶
Follow the steps in Create a Command Line Tool using CMake on Ubuntu, but use the code from this article.
Download the Wildlife.mp4 sample file and save it in the project directory:
curl \
-L -o Wildlife.mp4 \
https://archive.org/download/WildlifeSampleVideo/Wildlife.mp4
Run the application. Wait for the Transcoder to finish - it will take a few minutes. The converted file Wildlife_h265_aac.mp4 will be in the project directory.
Windows¶
Code¶
#include <primo/avblocks/avb.h>
#include <primo/platform/reference++.h>
#include <primo/platform/ustring.h>
#include <windows.h>
using namespace primo;
using namespace primo::codecs;
using namespace primo::avblocks;
int wmain(int argc, wchar_t* argv[])
{
// needed for WMV
CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
Library::initialize();
auto inputFile = primo::ustring(L"Wildlife.wmv");
auto outputFile = primo::ustring(L"Wildlife_h265_aac.mp4");
auto inputInfo = primo::make_ref(Library::createMediaInfo());
inputInfo->inputs()->at(0)->setFile(inputFile);
if (inputInfo->open()) {
auto inputSocket = primo::make_ref(
Library::createMediaSocket(inputInfo.get())
);
// Start with MP4 / H.264 + AAC preset, then change video to H.265
auto outputSocket = primo::make_ref(
Library::createMediaSocket(Preset::Video::Generic::MP4::Base_H264_AAC)
);
// Get the output video stream info and modify it for H.265/HEVC
auto outVideoStream = (VideoStreamInfo*)outputSocket->pins()->at(0)->streamInfo();
outVideoStream->setStreamType(StreamType::H265);
outVideoStream->setStreamSubType(StreamSubType::HEVC_Annex_B);
// With H.265/HEVC we can use lower bitrate, e.g. 500 kbps
outVideoStream->setBitrate(500'000);
// Change the output file name to Wildlife_h265_aac.mp4
outputSocket->setFile(outputFile);
// Create Transcoder and configure it with
// the input and output sockets
auto transcoder = primo::make_ref(Library::createTranscoder());
transcoder->inputs()->add(inputSocket.get());
transcoder->outputs()->add(outputSocket.get());
// Allow demo mode for the transcoder when
// using the demo version of the library
transcoder->setAllowDemoMode(true);
// Run the transcoder
if (transcoder->open()) {
transcoder->run();
transcoder->close();
} else {
std::wcerr << L"transcoder->open() failed: "
<< primo::ustring(transcoder->error()->message())
<< std::endl;
}
}
Library::shutdown();
CoUninitialize();
return 0;
}
How to run¶
Follow the steps in Create a Command Line Tool using CMake on Windows, but use the code from this article.
Download the Wildlife.wmv sample file and save it in the project directory:
Invoke-WebRequest `
-Uri https://archive.org/download/WildlifeSampleVideo/Wildlife.wmv `
-OutFile Wildlife.wmv
Run the application. Wait for the Transcoder to finish - it will take a few seconds. The converted file Wildlife_h265_aac.mp4 will be in the project directory.