Simple Video Converter

Building a video converter using C++ and the AVBlocks Plus TTranscoder.

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.

Overview

These snippets are fully functional video converters. They take Wildlife_h264_aac.mp4 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 <cstdio>
#include <print>

#include "../shim/shim23.h"

using namespace primo::codecs;
using namespace primo::avblocks::modern;

int main()
{
    TLibrary library;

    const char* inputFile  = "Wildlife_h264_aac.mp4";
    const char* outputFile = "Wildlife_h265_aac.mp4";

    // transcoder will fail if output exists (by design)
    std::remove(outputFile);

    try {
        // Probe the input file and create the input socket from the probe
        auto input = TMediaSocket(TMediaInfo().file(inputFile).open());

        // Demo mode is allowed when using the demo version of the library.
        TTranscoder()
            .allowDemoMode(true)
            .addInput(input)
            // The output starts as a copy of the input
            .addOutput(
                input.clone()
                    .file(outputFile)
                    .videoInfoRef(0, [](TVideoStreamInfo& video) {
                        // Change the output video stream to H.265/HEVC
                        // Input is H.264/AVC at 700 kbps
                        // With H.265/HEVC we can use lower bitrate, e.g. 500 kbps
                        video.streamType(StreamType::H265)
                             .streamSubType(StreamSubType::HEVC_Annex_B)
                             .bitrate(500'000);
                    })
            )
            .transcode();

        std::println("Output: {}", outputFile);
        return 0;

    } catch (const TAVBlocksException& ex) {
        std::println(stderr, "AVBlocks error: {}", ex.what());
        return 1;
    }
}

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 as Wildlife_h264_aac.mp4 and save it in the project directory:

curl \
  -L -o Wildlife_h264_aac.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 <cstdio>
#include <print>

#include "../shim/shim23.h"

using namespace primo::codecs;
using namespace primo::avblocks::modern;

int main()
{
    TLibrary library;

    const char* inputFile  = "Wildlife_h264_aac.mp4";
    const char* outputFile = "Wildlife_h265_aac.mp4";

    // transcoder will fail if output exists (by design)
    std::remove(outputFile);

    try {
        // Probe the input file and create the input socket from the probe
        auto input = TMediaSocket(TMediaInfo().file(inputFile).open());

        // Demo mode is allowed when using the demo version of the library.
        TTranscoder()
            .allowDemoMode(true)
            .addInput(input)
            // The output starts as a copy of the input
            .addOutput(
                input.clone()
                    .file(outputFile)
                    .videoInfoRef(0, [](TVideoStreamInfo& video) {
                        // Change the output video stream to H.265/HEVC
                        // Input is H.264/AVC at 700 kbps
                        // With H.265/HEVC we can use lower bitrate, e.g. 500 kbps
                        video.streamType(StreamType::H265)
                             .streamSubType(StreamSubType::HEVC_Annex_B)
                             .bitrate(500'000);
                    })
            )
            .transcode();

        std::println("Output: {}", outputFile);
        return 0;

    } catch (const TAVBlocksException& ex) {
        std::println(stderr, "AVBlocks error: {}", ex.what());
        return 1;
    }
}

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 as Wildlife_h264_aac.mp4 and save it in the project directory:

curl \
  -L -o Wildlife_h264_aac.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 <cstdio>
#include <iostream>

using namespace primo::codecs;
using namespace primo::avblocks::modern;

int wmain()
{
    TLibrary library;

    const wchar_t* inputFile  = L"Wildlife_h264_aac.mp4";
    const wchar_t* outputFile = L"Wildlife_h265_aac.mp4";

    // transcoder will fail if output exists (by design)
    _wremove(outputFile);

    try {
        // Probe the input file and create the input socket from the probe
        auto input = TMediaSocketW(TMediaInfoW().file(inputFile).open());

        // Demo mode is allowed when using the demo version of the library.
        TTranscoderW()
            .allowDemoMode(true)
            .addInput(input)
            // The output starts as a copy of the input
            .addOutput(
                input.clone()
                    .file(outputFile)
                    .videoInfoRef(0, [](TVideoStreamInfo& video) {
                        // Change the output video stream to H.265/HEVC
                        // Input is H.264/AVC at 700 kbps
                        // With H.265/HEVC we can use lower bitrate, e.g. 500 kbps
                        video.streamType(StreamType::H265)
                             .streamSubType(StreamSubType::HEVC_Annex_B)
                             .bitrate(500'000);
                    })
            )
            .transcode();

        std::wcout << L"Output: " << outputFile << std::endl;
        return 0;

    } catch (const TAVBlocksException& ex) {
        std::wcerr << L"AVBlocks error: " << ex.what() << std::endl;
        return 1;
    }
}

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.mp4 sample file and save it as Wildlife_h264_aac.mp4 in the project directory:

Invoke-WebRequest `
  -Uri https://archive.org/download/WildlifeSampleVideo/Wildlife.mp4 `
  -OutFile Wildlife_h264_aac.mp4

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.