Simple DVD
This topic describes the steps needed to create a DVD from an MP4 video.
Project Directory
You need a directory to store the source video and the DVDBuilder project. This can be anywhere on your machine. For example create C:\ElephantDVD
directory. We will refer to that as the DVD Project Directory
.
Source Video
Download the clip Elephant_512kb.mp4
from the Internet Archive to the DVD Project Directory
.
Convert Source Video To MPEG-2
DVDBuilder accepts only MPEG-2 Program Stream as input, but you can use AVBlocks to convert the source video from MP4 to MPG (MPEG-2 Program Stream). AVBlocks is already included with DVDBuilder.
string sourceMp4 = Path.Combine(DVDProjectDirectory, "Elephant_512kb.mp4");
string sourceMpeg2 = Path.Combine(DVDProjectDirectory, "Elephant.mpg");
ConvertSourceToMpeg2(sourceMp4, sourceMpeg2);
using avb = PrimoSoftware.AVBlocks;
private static void ConvertSourceToMpeg2(string inputFile, string outputFile)
{
if (File.Exists(outputFile))
File.Delete(outputFile);
var inputInfo = new avb.MediaInfo() {
InputFile = inputFile
};
if (inputInfo.Load())
{
var inputSocket = avb.MediaSocket.FromMediaInfo(inputInfo);
var outputSocket = avb.MediaSocket.FromPreset(avb.Preset.Video.DVD.NTSC_16x9_PCM);
outputSocket.File = outputFile;
using (var transcoder = new avb.Transcoder())
{
transcoder.AllowDemoMode = true;
transcoder.Inputs.Add(inputSocket);
transcoder.Outputs.Add(outputSocket);
if (transcoder.Open())
{
transcoder.Run();
transcoder.Close();
}
}
}
}
Create DVDBuilder Project
DVDBuilder project is an XML file that describes a video DVD.
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='Title=1'/>
<titleSet>
<titles>
<title id='1' chapters='00:00:00;'>
<videoObject file='Elephant.mpg'/>
</title>
</titles>
</titleSet>
</dvd>
Build DVD Structures
Simply create a DVDBuilder object, set the ProjectFile
and OutputFolder
properties, and call the Build
method.
string project = Path.Combine(DVDProjectDirectory, "project.xml");
string dvdFiles = Path.Combine(DVDProjectDirectory, "dvd");
BuildDVDStructures(project, dvdFiles);
using dvdb = PrimoSoftware.DVDBuilder;
private static void BuildDVDStructures(string project, string dvdFiles)
{
if (Directory.Exists(dvdFiles))
Directory.Delete(dvdFiles, true);
using (var dvdBuilder = new dvdb.DVDBuilder())
{
dvdBuilder.ProjectFile = project;
dvdBuilder.OutputFolder = dvdFiles;
dvdBuilder.Build();
}
}
Burn DVD
You can use PrimoBurner for DVD burning. A limited version of PrimoBurner, that supports DVD burning only, is included with DVDBuilder.
Create Engine
using pb = PrimoSoftware.Burner;
private static void BurnToDVD(string output, char driveLetter)
{
using (var engine = new pb.Engine())
{
engine.Initialize();
BurnToDVD(engine, driveLetter, output);
engine.Shutdown();
}
}
Create Device
using pb = PrimoSoftware.Burner;
private static void BurnToDVD(pb.Engine engine, char driveLetter, string dvdFiles)
{
int deviceIndex = PrimoSoftware.Burner.Library.GetCDROMIndexFromLetter(driveLetter);
using (var enumerator = engine.CreateDeviceEnumerator())
{
var device = enumerator.CreateDevice(deviceIndex, true);
if (null != device)
{
BurnToDVD(device, dvdFiles);
device.Dispose();
}
}
}
Use VideoDVD To Prepare DVD Layout
using pb = PrimoSoftware.Burner;
private static void BurnToDVD(pb.Device device, string dvdFiles)
{
// Use VideoDVD to prepare the DVD image layout
using (var videoDVD = new pb.VideoDVD())
{
// set the dvd files as layout
videoDVD.SetImageLayoutFromFolder(dvdFiles);
videoDVD.Validation = pb.VideoDVDValidation.Minimal;
// get the actual DVD layout
var preparedImageLayout = videoDVD.ImageLayout;
// Burn
BurnToDVD(device, preparedImageLayout);
}
}
Burn DVD Layout
using pb = PrimoSoftware.Burner;
private static void BurnToDVD(pb.Device device, pb.DataFile imageLayout)
{
if (!CheckDeviceAndMedia(device))
{
Console.WriteLine("Please insert a blank DVD-R or DVD+R in burner and try again.");
// media is not a DVD+R or DVD-R, or not blank
device.Eject(true, true);
return;
}
// Use DataDisc to burn the DVD image layout
using (var dataDisc = new pb.DataDisc())
{
// set device, and write method
dataDisc.Device = device;
dataDisc.WriteMethod = pb.WriteMethod.DvdDao;
// close the disc for true playback compatibility
// this will result in slower disc burning
dataDisc.CloseDisc = true;
// DataDisc needs this to create the correct disc image
dataDisc.DvdVideo = true;
// set volume label and creation date
dataDisc.IsoVolumeProps.VolumeLabel = "DVDVIDEO";
dataDisc.IsoVolumeProps.CreationTime = DateTime.Now;
dataDisc.UdfVolumeProps.VolumeLabel = dataDisc.IsoVolumeProps.VolumeLabel;
dataDisc.UdfVolumeProps.CreationTime = dataDisc.IsoVolumeProps.CreationTime;
// set the image layout as prepared by VideoDVD
dataDisc.SetImageLayout(imageLayout);
// this may take some time
dataDisc.WriteToDisc(true);
}
}
Complete C# Code
Here is the complete code.
using System;
using System.IO;
using avb = PrimoSoftware.AVBlocks;
using dvdb = PrimoSoftware.DVDBuilder;
using pb = PrimoSoftware.Burner;
namespace SimplestDVD
{
class Program
{
const string DVDProjectDirectory = "C:/ElephantDVD";
const char DVDBurnerDriveLetter = 'I';
static void Main(string[] args)
{
// Video encoding
PrimoSoftware.AVBlocks.Library.Initialize();
PrimoSoftware.AVBlocks.Library.SetLicense("license_xml_string");
// DVD authoring
PrimoSoftware.DVDBuilder.Library.Initialize();
PrimoSoftware.DVDBuilder.Library.SetLicense("license_xml_string");
// DVD burning
PrimoSoftware.Burner.Library.Initialize();
PrimoSoftware.Burner.Library.SetLicense("license_xml_string");
// Step 1: Convert sources
string sourceMp4 = Path.Combine(DVDProjectDirectory, "Elephant_512kb.mp4");
string sourceMpeg2 = Path.Combine(DVDProjectDirectory, "Elephant.mpg");
ConvertSourceToMpeg2(sourceMp4, sourceMpeg2);
// Step 2: Build DVD structures
string project = Path.Combine(DVDProjectDirectory, "project.xml");
string dvdFiles = Path.Combine(DVDProjectDirectory, "dvd");
BuildDVDStructures(project, dvdFiles);
// Step 3: Burn to DVD
BurnToDVD(dvdFiles, DVDBurnerDriveLetter);
PrimoSoftware.Burner.Library.Shutdown();
PrimoSoftware.DVDBuilder.Library.Shutdown();
PrimoSoftware.AVBlocks.Library.Shutdown();
}
private static void ConvertSourceToMpeg2(string inputFile, string outputFile)
{
if (File.Exists(outputFile))
File.Delete(outputFile);
var inputInfo = new avb.MediaInfo() {
InputFile = inputFile
};
if (inputInfo.Load())
{
var inputSocket = avb.MediaSocket.FromMediaInfo(inputInfo);
var outputSocket =
avb.MediaSocket.FromPreset(avb.Preset.Video.DVD.NTSC_16x9_PCM);
outputSocket.File = outputFile;
using (var transcoder = new avb.Transcoder())
{
transcoder.AllowDemoMode = true;
transcoder.Inputs.Add(inputSocket);
transcoder.Outputs.Add(outputSocket);
if (transcoder.Open())
{
transcoder.Run();
transcoder.Close();
}
}
}
}
private static void BuildDVDStructures(string project, string dvdFiles)
{
if (Directory.Exists(dvdFiles))
Directory.Delete(dvdFiles, true);
using (var dvdBuilder = new dvdb.DVDBuilder())
{
dvdBuilder.ProjectFile = project;
dvdBuilder.OutputFolder = dvdFiles;
dvdBuilder.Build();
}
}
private static void BurnToDVD(string output, char driveLetter)
{
using (var engine = new pb.Engine())
{
engine.Initialize();
BurnToDVD(engine, driveLetter, output);
engine.Shutdown();
}
}
private static void BurnToDVD(pb.Engine engine, char driveLetter, string dvdFiles)
{
int deviceIndex = PrimoSoftware.Burner.Library.GetCDROMIndexFromLetter(driveLetter);
using (var enumerator = engine.CreateDeviceEnumerator())
{
var device = enumerator.CreateDevice(deviceIndex, true);
if (null != device)
{
BurnToDVD(device, dvdFiles);
device.Dispose();
}
}
}
private static void BurnToDVD(pb.Device device, string dvdFiles)
{
// Use VideoDVD to prepare the DVD image layout
using (var videoDVD = new pb.VideoDVD())
{
// set the dvd files as layout
videoDVD.SetImageLayoutFromFolder(dvdFiles);
videoDVD.Validation = pb.VideoDVDValidation.Minimal;
// get the actual DVD layout
var preparedImageLayout = videoDVD.ImageLayout;
// Burn
BurnToDVD(device, preparedImageLayout);
}
}
private static void BurnToDVD(pb.Device device, pb.DataFile imageLayout)
{
if (!CheckDeviceAndMedia(device))
{
Console.WriteLine("Please insert a DVD-R or DVD+R in burner and try again.");
// media is not DVD+R or DVD-R, or not blank
device.Eject(true, true);
return;
}
// Use DataDisc to burn the DVD image layout
using (var dataDisc = new pb.DataDisc())
{
// set device, and write method
dataDisc.Device = device;
dataDisc.WriteMethod = pb.WriteMethod.DvdDao;
// close the disc for true playback compatibility
// this will result in slower disc burning
dataDisc.CloseDisc = true;
// DataDisc needs this to create the correct disc image
dataDisc.DvdVideo = true;
// set volume label and creation date
dataDisc.IsoVolumeProps.VolumeLabel = "DVDVIDEO";
dataDisc.IsoVolumeProps.CreationTime = DateTime.Now;
dataDisc.UdfVolumeProps.VolumeLabel = dataDisc.IsoVolumeProps.VolumeLabel;
dataDisc.UdfVolumeProps.CreationTime = dataDisc.IsoVolumeProps.CreationTime;
// set the image layout as prepared by VideoDVD
dataDisc.SetImageLayout(imageLayout);
// this may take some time
dataDisc.WriteToDisc(true);
}
}
private static bool CheckDeviceAndMedia(pb.Device device)
{
// close the device tray and refresh disc information
if (device.Eject(false))
{
// wait for the device to become ready
WaitForUnitReady(device);
// refresh disc information. Need to call this method when media changes
device.Refresh();
}
// check if disc is present
if (pb.MediaReady.Present != device.MediaState)
return false;
// check if disc is blank
if (!device.MediaIsBlank)
return false;
// for simplicity only accept DVD-R and DVD+R
pb.MediaProfile mp = device.MediaProfile;
if (pb.MediaProfile.DvdPlusR != mp && pb.MediaProfile.DvdMinusRSeq != mp)
return false;
return true;
}
private static void WaitForUnitReady(pb.Device device)
{
int error = device.UnitReady;
while (true)
{
if ((int)pb.DeviceError.Success == error)
break;
if ((int)pb.DeviceError.MediumNotPresent == error)
break;
if ((int)pb.DeviceError.MediumNotPresentTrayClosed == error)
break;
if ((int)pb.DeviceError.MediumNotPresentTrayOpen == error)
break;
System.Threading.Thread.Sleep(1000);
error = device.UnitReady;
}
}
}
}
Last updated on May 9th, 2015 12:00:00 AM