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
.
Menu Background and Mask
Download the Menu_NTSC.jpg
and the Menu_NTSC_Mask.bmp
images below to the DVD Project Directory
.
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