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