DVD with a Title Menu

This topic describes how you can use DVDBuilder to create a DVD with two titles and a title menu.

Project Directory

You need a directory to store the source images and the DVDBuilder project. This can be anywhere on your machine. For example create C:\TitleMenuDVD directory. We will refer to that as the DVD Project Directory.

Assets

Video Clips

Download the files Elephant_512kb.mp4 and Hippo_512kb.mp4 from the Internet Archive to the DVD Project Directory.

Download the Menu_NTSC.jpg and the Menu_NTSC_Mask.bmp images below to the DVD Project Directory.

Menu_NTSC.jpg Menu_NTSC_Mask.bmp

See Create Thumbnail Menu Background and Mask in GIMP for the steps to create the background and mask images.

DVDBuilder Project

In the DVD Project Directory create a file project.xml with the following contents:


<?xml version='1.0' encoding='utf-8'?>
<dvd version='2.3' xmlns='http://www.primosoftware.com/dvdbuilder/2.3'>
    <videoManager firstPlayNavigate='Menu=1001;'>
        <menus>
            <menu id='1001' entry='title'>
                <button left='130' top='150' width='200' height='150' navigate='Title=1;' />
                <button left='370' top='150' width='200' height='150' navigate='Title=2;' />
                <background file='Menu_NTSC.mpg' />
                <mask
                    file='Menu_NTSC_Mask.bmp'
                    patternColor    ='#FF0000'
                    backgroundColor ='#000000'
                    emphasisColor1  ='#00FF00'
                    emphasisColor2  ='#0000FF' />
                <display
                    patternColor   ='#FFFFFF' patternContrast   ='3'
                    backgroundColor='#000000' backgroundContrast='0'
                    emphasis1Color ='#000000' emphasis1Contrast ='0'
                    emphasis2Color ='#000000' emphasis2Contrast ='0'/>
                <selection
                    patternColor   ='#000000' patternContrast   ='0'
                    backgroundColor='#000000' backgroundContrast='0'
                    emphasis1Color ='#FF00FF' emphasis1Contrast ='15'
                    emphasis2Color ='#000000' emphasis2Contrast ='0'/>
                <action
                    patternColor   ='#000000' patternContrast   ='0'
                    backgroundColor='#000000' backgroundContrast='0'
                    emphasis1Color ='#FF00FF' emphasis1Contrast ='15'
                    emphasis2Color ='#FFFF00' emphasis2Contrast ='10'/>
            </menu>
        </menus>
    </videoManager>
    <titleSet>
        <titles>
            <title id='1' chapters='00:00:00;'>
                <videoObject file='Elephant.mpg'/>
            </title>
            <title id='2' chapters='00:00:00;'>
                <videoObject file='Hippo.mpg'/>
            </title>
        </titles>
    </titleSet>
</dvd>

For detailed explanation of the DVDBuilder project XML elements and attributes, see the DVD Title Menu with Thumbnail Images topic in the DVD Projects | Menus section.

Prepare Assets

Convert Menu Background to MPEG-2

You can use AVBlocks to convert JPG to MPG (MPEG-2 Program Stream).


wstring background = fs::path(DVDProjectDirectory).append(L"Menu_NTSC.jpg");
wstring background_mpeg2 = fs::path(DVDProjectDirectory).append(L"Menu_NTSC.mpg");

convert_image_to_mpeg2(background, background_mpeg2);

namespace p = primo;
namespace avb = primo::avblocks;
namespace fs = experimental::filesystem;

void convert_image_to_mpeg2(wstring input_file, wstring output_file)
{
    using namespace avb;
    using namespace avb::Library;

    if (fs::exists(output_file))
        fs::remove(output_file);

    auto inputSocket = p::make_ref(
        createMediaSocket()
    );

    inputSocket->setFile(input_file.c_str());

    auto outputSocket = p::make_ref(
        createMediaSocket(Preset::Video::DVD::NTSC_4x3_PCM)
    );

    outputSocket->setFile(output_file.c_str());

    auto transcoder = p::make_ref(
        createTranscoder()
    );

    transcoder->setAllowDemoMode(true);

    transcoder->inputs()->add(inputSocket.get());
    transcoder->outputs()->add(outputSocket.get());

    if (transcoder->open()) {
        transcoder->run();
        transcoder->close();
    }
}

Convert Video Clips to MPEG-2

You can use AVBlocks to convert MP4 to MPG (MPEG-2 Program Stream).


wstring source_mp4 = fs::path(DVDProjectDirectory).append(L"Elephant_512kb.mp4");
wstring source_mpeg2 = fs::path(DVDProjectDirectory).append(L"Elephant.mpg");

convert_video_to_mpeg2(source_mp4, source_mpeg2);

source_mp4 = fs::path(DVDProjectDirectory).append(L"Hippo_512kb.mp4");
source_mpeg2 = fs::path(DVDProjectDirectory).append(L"Hippo.mpg");

convert_video_to_mpeg2(source_mp4, source_mpeg2);

namespace p = primo;
namespace avb = primo::avblocks;
namespace fs = experimental::filesystem;

void convert_video_to_mpeg2(wstring input_file, wstring output_file)
{
    using namespace avb;
    using namespace avb::Library;

    if (fs::exists(output_file))
        fs::remove(output_file);

    auto inputInfo = p::make_ref(
        createMediaInfo()
    );

    inputInfo->setInputFile(input_file.c_str());

    if (inputInfo->load()) {
        auto inputSocket = p::make_ref(
            createMediaSocket(inputInfo.get())
        );

        auto outputSocket = p::make_ref(
            createMediaSocket(Preset::Video::DVD::NTSC_16x9_PCM)
        );

        outputSocket->setFile(output_file.c_str());

        auto transcoder = p::make_ref(
            createTranscoder()
        );

        transcoder->setAllowDemoMode(true);

        transcoder->inputs()->add(inputSocket.get());
        transcoder->outputs()->add(outputSocket.get());

        if (transcoder->open()) {
            transcoder->run();
            transcoder->close();
        }
    }
}

Build DVD Structures

Simply create a DVDBuilder object, set the ProjectFile and OutputFolder properties, and call the Build method.


wstring project = fs::path(DVDProjectDirectory).append(L"project.xml");
wstring dvd_files = fs::path(DVDProjectDirectory).append(L"dvd");

build_dvd_structures(project, dvd_files);

namespace p = primo;
namespace dvdb = primo::dvdbuilder;
namespace fs = experimental::filesystem;

void build_dvd_structures(wstring project, wstring dvd_files)
{
    using namespace dvdb::Library;

    if (fs::exists(dvd_files))
        fs::remove_all(dvd_files);

    auto dvdBuilder = p::make_ref(
        createDVDBuilder()
    );

    dvdBuilder->setProjectFile(project.c_str());
    dvdBuilder->setOutputFolder(dvd_files.c_str());

    dvdBuilder->build();
}

Complete C++ Code


// CreateDVDTitleMenu.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

using namespace std;

// or you can use boost::filesystem, http://www.boost.org
namespace fs = experimental::filesystem;

namespace p = primo;
namespace avb = primo::avblocks;
namespace dvdb = primo::dvdbuilder;

const wstring DVDProjectDirectory = L"C:/TitleMenuDVD";

void convert_image_to_mpeg2(wstring input_file, wstring output_file);
void convert_video_to_mpeg2(wstring input_file, wstring output_file);
void build_dvd_structures(wstring project, wstring dvd_files);

int main()
{
    // Video encoding
    primo::avblocks::Library::initialize();
    primo::avblocks::Library::setLicense("license_xml_string");

    // DVD authoring
    primo::dvdbuilder::Library::setLicense("license_xml_string");

    // Step 1: Convert menu background
    wstring background = fs::path(DVDProjectDirectory).append(L"Menu_NTSC.jpg");
    wstring background_mpeg2 = fs::path(DVDProjectDirectory).append(L"Menu_NTSC.mpg");

    convert_image_to_mpeg2(background, background_mpeg2);

    // Step 2: Convert title videos
    wstring source_mp4 = fs::path(DVDProjectDirectory).append(L"Elephant_512kb.mp4");
    wstring source_mpeg2 = fs::path(DVDProjectDirectory).append(L"Elephant.mpg");

    convert_video_to_mpeg2(source_mp4, source_mpeg2);

    source_mp4 = fs::path(DVDProjectDirectory).append(L"Hippo_512kb.mp4");
    source_mpeg2 = fs::path(DVDProjectDirectory).append(L"Hippo.mpg");

    convert_video_to_mpeg2(source_mp4, source_mpeg2);

    // Step 3: Build DVD structures
    wstring project = fs::path(DVDProjectDirectory).append(L"project.xml");
    wstring dvd_files = fs::path(DVDProjectDirectory).append(L"dvd");

    build_dvd_structures(project, dvd_files);

    primo::avblocks::Library::shutdown();

    return 0;
}

void convert_image_to_mpeg2(wstring input_file, wstring output_file)
{
    using namespace avb;
    using namespace avb::Library;

    if (fs::exists(output_file))
        fs::remove(output_file);

    auto inputSocket = p::make_ref(
        createMediaSocket()
    );

    inputSocket->setFile(input_file.c_str());

    auto outputSocket = p::make_ref(
        createMediaSocket(Preset::Video::DVD::NTSC_4x3_PCM)
    );

    outputSocket->setFile(output_file.c_str());

    auto transcoder = p::make_ref(
        createTranscoder()
    );

    transcoder->setAllowDemoMode(true);

    transcoder->inputs()->add(inputSocket.get());
    transcoder->outputs()->add(outputSocket.get());

    if (transcoder->open()) {
        transcoder->run();
        transcoder->close();
    }
}

void convert_video_to_mpeg2(wstring input_file, wstring output_file)
{
    using namespace avb;
    using namespace avb::Library;

    if (fs::exists(output_file))
        fs::remove(output_file);

    auto inputInfo = p::make_ref(
        createMediaInfo()
    );

    inputInfo->setInputFile(input_file.c_str());

    if (inputInfo->load()) {
        auto inputSocket = p::make_ref(
            createMediaSocket(inputInfo.get())
        );

        auto outputSocket = p::make_ref(
            createMediaSocket(Preset::Video::DVD::NTSC_16x9_PCM)
        );

        outputSocket->setFile(output_file.c_str());

        auto transcoder = p::make_ref(
            createTranscoder()
        );

        transcoder->setAllowDemoMode(true);

        transcoder->inputs()->add(inputSocket.get());
        transcoder->outputs()->add(outputSocket.get());

        if (transcoder->open()) {
            transcoder->run();
            transcoder->close();
        }
    }
}

// Build DVD structures
void build_dvd_structures(wstring project, wstring dvd_files)
{
    using namespace dvdb::Library;

    if (fs::exists(dvd_files))
        fs::remove_all(dvd_files);

    auto dvdBuilder = p::make_ref(
        createDVDBuilder()
    );

    dvdBuilder->setProjectFile(project.c_str());
    dvdBuilder->setOutputFolder(dvd_files.c_str());

    dvdBuilder->build();
}


Last updated on March 1st, 2016 12:00:00 AM