Automating DVD Creation with dvdauthor and Shell Scripts

Beginner’s Guide to dvdauthor: Create DVDs from Your Video Filesdvdauthor is a command-line toolkit for creating DVD-Video compliant structures from raw video files, primarily used on Linux and other Unix-like systems. It doesn’t encode video itself; instead, it takes MPEG-2 streams (or already-encoded video in an acceptable format) and builds the VIDEO_TS and AUDIO_TS directories with the correct files and navigation data so the result can be authored to disc and played in standard DVD players. This guide walks you through the concepts, prerequisites, installation, common workflows, and examples to help you create playable DVDs from your video files.


How dvdauthor fits into a DVD creation workflow

A typical DVD authoring workflow using open-source tools looks like this:

  1. Convert your source video to a DVD-compatible MPEG-2 stream (and audio to AC-3 or PCM) — use tools like ffmpeg or mencoder.
  2. Create an XML-based project describing titles, menus, and navigation — dvdauthor uses simple XML for this.
  3. Run dvdauthor to generate VIDEO_TS and AUDIO_TS directories.
  4. Optionally create ISO using genisoimage or mkisofs.
  5. Burn the ISO or VIDEO_TS folder to DVD with growisofs, wodim, or a graphical burner.

dvdauthor’s role is step 3: taking prepared streams and a project file and producing a fully structured DVD-Video filesystem.


Prerequisites and supported formats

  • Video: DVD-Video requires MPEG-2 video at standard DVD resolutions (720×480 NTSC or 720×576 PAL) and appropriate frame rates (23.976/24/29.⁄30 for NTSC variants, 25 for PAL).
  • Audio: AC-3 (Dolby Digital) is the most widely supported; PCM (uncompressed) is also allowed.
  • Tools: You’ll typically use ffmpeg or mencoder to encode/convert into compliant streams. genisoimage/mkisofs to create ISOs; growisofs/wodim for burning.
  • Platform: dvdauthor runs on Linux and other Unix-like systems. Windows users can run it via Cygwin/MSYS or use GUI tools that bundle similar functionality.

Installation

On Debian/Ubuntu:

sudo apt update sudo apt install dvdauthor 

On Fedora:

sudo dnf install dvdauthor 

On Arch:

sudo pacman -S dvdauthor 

From source (if needed):

wget http://downloads.sourceforge.net/project/dvdauthor/dvdauthor/0.7.11/dvdauthor-0.7.11.tar.gz tar xzf dvdauthor-0.7.11.tar.gz cd dvdauthor-0.7.11 ./configure make sudo make install 

Basic concepts and XML structure

dvdauthor uses an XML project file describing titlesets, titles (VOBs), menus, buttons, and navigation. A minimal dvdauthor XML contains a root with nested (menu manager) and sections.

Key elements:

  • : Defines a set of titles (each title typically maps to a VOB file).
  • : Contains <vob> elements with the path to MPEG-2 files.</li> <li><menus> and <pgc>: Used to build DVD menus and navigation commands.</li> <li><button>: Defines clickable regions on a menu with coordinates and actions.</li> </ul> <p>Minimal example — single title, no menus:</p> <pre><code ><dvdauthor> <vmgm/> <titleset> <title> <vob file="movie.mpg" /> </title> </titleset> </dvdauthor> </code></pre> <hr> <h2 id="converting-source-video-to-dvd-compliant-streams">Converting source video to DVD-compliant streams</h2> <p>If your video is not already MPEG-2 with proper resolution and audio, use ffmpeg to convert:</p> <p>Example: Convert an MP4 to DVD-compliant MPEG-2 video and AC-3 audio (NTSC):</p> <pre><code>ffmpeg -i input.mp4 -target ntsc-dvd -aspect 16:9 -ac 2 -ar 48000 -y output.mpg </code></pre> <p>Notes:</p> <ul> <li>The -target ntsc-dvd preset sets many correct parameters (bitrate, GOP, pixel format).</li> <li>For PAL, use -target pal-dvd.</li> <li>If you need AC-3 specifically, ensure ffmpeg is compiled with libfdk_aac or ac3 encoders; alternatively, output WAV and convert audio separately.</li> </ul> <p>If you need precise control:</p> <pre><code>ffmpeg -i input.mp4 -vf scale=720:480,fps=29.97 -c:v mpeg2video -b:v 6000k -minrate 6000k -maxrate 6000k -bufsize 1835k -c:a ac3 -b:a 192k -ar 48000 output.mpg </code></pre> <hr> <h2 id="creating-a-simple-dvd-with-dvdauthor">Creating a simple DVD with dvdauthor</h2> <ol> <li>Prepare one or more MPEG-2 files (e.g., movie1.mpg, movie2.mpg).</li> <li>Write a project XML (example below).</li> <li>Run dvdauthor to produce VIDEO_TS.</li> </ol> <p>Example project (two titles):</p> <pre><code ><dvdauthor> <vmgm/> <titleset> <title> <vob file="movie1.mpg" /> </title> <title> <vob file="movie2.mpg" /> </title> </titleset> </dvdauthor> </code></pre> <p>Command:</p> <pre><code>dvdauthor -x project.xml -o dvd_out </code></pre> <p>Result: dvd_out/VIDEO_TS contains .ifo, .vob, .bup files ready for burning.</p> <hr> <h2 id="adding-a-menu">Adding a menu</h2> <p>A simple menu can be built using dvdauthor’s XML or by using pre-rendered background images and button coordinates.</p> <p>Example menu XML with background image (menu.png), two buttons:</p> <pre><code ><dvdauthor> <vmgm> <menus> <menu name="main"> <background file="menu.png" /> <button highlight="rect(50,200,300,260)" action="jump title 1" /> <button highlight="rect(50,260,300,320)" action="jump title 2" /> </menu> </menus> </vmgm> <titleset> <title> <vob file="movie1.mpg" /> </title> <title> <vob file="movie2.mpg" /> </title> </titleset> </dvdauthor> </code></pre> <p>Notes:</p> <ul> <li>Coordinates are in pixels relative to 720×480 (NTSC) or 720×576 (PAL) menu size. Buttons should map to visible menu areas.</li> <li>For more advanced menus, use dvdauthor’s PGC (Program Chain) features or an external GUI tool.</li> </ul> <p>To add audio background for menus, include <audiofile file="menu-ac3.ac3" /> inside the </p> <menu> element.</p> <hr> <h2 id="creating-subtitles-sub-idx-or-vobsub">Creating subtitles (sub/idx or VobSub)</h2> <p>dvdauthor supports subtitles in VobSub format (.sub/.idx). Create subtitles with tools like Subrip (to get .srt), then convert to VobSub using tools such as subtitle2vobsub or vobsub toolchains.</p> <p>Once you have .sub/.idx:</p> <ul> <li>Use spumux (or other muxers) to multiplex subtitles into the VOBs, or let dvdauthor reference external subtitle files via <subpicture> elements.</li> </ul> <p>Basic spumux usage:</p> <pre><code>spumux -o movie_with_subs.mpg -s subtitle.idx movie.mpg </code></pre> <hr> <h2 id="making-an-iso-and-burning">Making an ISO and burning</h2> <p>Create an ISO image from the authored DVD structure:</p> <pre><code>genisoimage -dvd-video -o dvd_image.iso dvd_out </code></pre> <pre><code>mkisofs -dvd-video -o dvd_image.iso dvd_out </code></pre> <p>Burn to disc (DVD-R/DVD+R) with growisofs:</p> <pre><code>growisofs -dvd-compat -Z /dev/dvd=dvd_image.iso </code></pre> <p>Replace /dev/dvd with your burner device node or use a GUI burner.</p> <hr> <h2 id="common-pitfalls-and-troubleshooting">Common pitfalls and troubleshooting</h2> <ul> <li>Wrong resolution/frame rate: Player rejects disc or video plays improperly. Ensure conversion uses correct DVD resolutions and NTSC/PAL frame rates.</li> <li>Audio format unsupported: Convert audio to AC-3 or PCM.</li> <li>Large titles: DVDs have size limits (~4.7GB single-layer); use bitrate control or split titles across discs.</li> <li>Menu coordinates wrong: Buttons don’t align on screen — check menu background size (720×480 or 720×576) and coordinates.</li> <li>dvdauthor errors like “VOB not compliant”: Re-encode the video with DVD-compliant settings.</li> </ul> <p>Useful commands for debugging:</p> <ul> <li>Use mediainfo or ffprobe to inspect streams.</li> <li>dvdauthor -o out -x project.xml prints verbose errors—add -v for more verbosity.</li> </ul> <hr> <h2 id="examples-full-end-to-end-commands">Examples: full end-to-end commands</h2> <p>Single-file DVD (NTSC) quick flow:</p> <pre><code>ffmpeg -i input.mp4 -target ntsc-dvd -aspect 16:9 -ac 2 -ar 48000 -y output.mpg cat > project.xml <<EOF <dvdauthor> <vmgm/> <titleset> <title> <vob file="output.mpg" /> </title> </titleset> </dvdauthor> EOF dvdauthor -x project.xml -o dvd_out genisoimage -dvd-video -o dvd_image.iso dvd_out growisofs -dvd-compat -Z /dev/dvd=dvd_image.iso </code></pre> <p>Multiple titles with menu (assumes menu.png present):</p> <pre><code>ffmpeg -i part1.mp4 -target ntsc-dvd -y part1.mpg ffmpeg -i part2.mp4 -target ntsc-dvd -y part2.mpg # create project.xml including menu (as shown earlier) dvdauthor -x project.xml -o dvd_out genisoimage -dvd-video -o dvd_image.iso dvd_out </code></pre> <hr> <h2 id="alternatives-and-gui-front-ends">Alternatives and GUI front-ends</h2> <p>If the command-line XML feels complex, consider GUI tools that wrap dvdauthor:</p> <ul> <li>DeVeDe (simple GUI for creating DVDs, uses dvdauthor)</li> <li>QDVDAuthor (older GUI)</li> <li>DVDStyler (creates menus and authors DVDs; may use similar backend tools)</li> </ul> <p>Each GUI simplifies menu creation, button placement, and encoding presets.</p> <hr> <h2 id="summary-key-steps">Summary: key steps</h2> <ul> <li>Convert videos to DVD-compliant MPEG-2 and AC-3/PCM audio.</li> <li>Create a dvdauthor XML project describing titles and menus.</li> <li>Run dvdauthor to generate VIDEO_TS structure.</li> <li>Make an ISO and burn to disc.</li> </ul> <hr> <p>If you want, I can:</p> <ul> <li>Build a ready-to-run project.xml for your files (tell me filenames, NTSC/PAL, aspect).</li> <li>Convert a sample command for a particular source file and target region.</li> </ul> </div> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"> </div> <div class="wp-block-group alignwide is-layout-flow wp-block-group-is-layout-flow" style="margin-top:var(--wp--preset--spacing--60);margin-bottom:var(--wp--preset--spacing--60);"> <nav class="wp-block-group alignwide is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-9b36172e wp-block-group-is-layout-flex" aria-label="Post navigation" style="border-top-color:var(--wp--preset--color--accent-6);border-top-width:1px;padding-top:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40)"> <div class="post-navigation-link-previous wp-block-post-navigation-link"><span class="wp-block-post-navigation-link__arrow-previous is-arrow-arrow" aria-hidden="true">←</span><a href="http://cloud9342111.sbs/5-best-alt-tag-generator-tools-to-improve-seo/" rel="prev">5 Best ALT Tag Generator Tools to Improve SEO</a></div> <div class="post-navigation-link-next wp-block-post-navigation-link"><a href="http://cloud9342111.sbs/efficient-versioning-and-management-of-javascript-web-resources-in-crm-2011/" rel="next">Efficient Versioning and Management of JavaScript Web Resources in CRM 2011</a><span class="wp-block-post-navigation-link__arrow-next is-arrow-arrow" aria-hidden="true">→</span></div> </nav> </div> <div class="wp-block-comments wp-block-comments-query-loop" style="margin-top:var(--wp--preset--spacing--70);margin-bottom:var(--wp--preset--spacing--70)"> <h2 class="wp-block-heading has-x-large-font-size">Comments</h2> <div id="respond" class="comment-respond wp-block-post-comments-form"> <h3 id="reply-title" class="comment-reply-title">Leave a Reply <small><a rel="nofollow" id="cancel-comment-reply-link" href="/automating-dvd-creation-with-dvdauthor-and-shell-scripts/#respond" style="display:none;">Cancel reply</a></small></h3><form action="http://cloud9342111.sbs/wp-comments-post.php" method="post" id="commentform" class="comment-form"><p class="comment-notes"><span id="email-notes">Your email address will not be published.</span> <span class="required-field-message">Required fields are marked <span class="required">*</span></span></p><p class="comment-form-comment"><label for="comment">Comment <span class="required">*</span></label> <textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525" required></textarea></p><p class="comment-form-author"><label for="author">Name <span class="required">*</span></label> <input id="author" name="author" type="text" value="" size="30" maxlength="245" autocomplete="name" required /></p> <p class="comment-form-email"><label for="email">Email <span class="required">*</span></label> <input id="email" name="email" type="email" value="" size="30" maxlength="100" aria-describedby="email-notes" autocomplete="email" required /></p> <p class="comment-form-url"><label for="url">Website</label> <input id="url" name="url" type="url" value="" size="30" maxlength="200" autocomplete="url" /></p> <p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes" /> <label for="wp-comment-cookies-consent">Save my name, email, and website in this browser for the next time I comment.</label></p> <p class="form-submit wp-block-button"><input name="submit" type="submit" id="submit" class="wp-block-button__link wp-element-button" value="Post Comment" /> <input type='hidden' name='comment_post_ID' value='463' id='comment_post_ID' /> <input type='hidden' name='comment_parent' id='comment_parent' value='0' /> </p></form> </div><!-- #respond --> </div> </div> <div class="wp-block-group alignwide has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"> <h2 class="wp-block-heading alignwide has-small-font-size" style="font-style:normal;font-weight:700;letter-spacing:1.4px;text-transform:uppercase">More posts</h2> <div class="wp-block-query alignwide is-layout-flow wp-block-query-is-layout-flow"> <ul class="alignfull wp-block-post-template is-layout-flow wp-container-core-post-template-is-layout-3ee800f6 wp-block-post-template-is-layout-flow"><li class="wp-block-post post-998 post type-post status-publish format-standard hentry category-uncategorised"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-154222c2 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="http://cloud9342111.sbs/why-you-need-hide-it-4-me-a-comprehensive-review-of-its-features/" target="_self" >Why You Need Hide It 4 Me: A Comprehensive Review of Its Features</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-10T23:16:58+01:00"><a href="http://cloud9342111.sbs/why-you-need-hide-it-4-me-a-comprehensive-review-of-its-features/">10 September 2025</a></time></div> </div> </li><li class="wp-block-post post-997 post type-post status-publish format-standard hentry category-uncategorised"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-154222c2 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="http://cloud9342111.sbs/transform-your-windows-8-experience-with-relaxing-rain-sounds/" target="_self" >Transform Your Windows 8 Experience with Relaxing Rain Sounds</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-10T22:56:51+01:00"><a href="http://cloud9342111.sbs/transform-your-windows-8-experience-with-relaxing-rain-sounds/">10 September 2025</a></time></div> </div> </li><li class="wp-block-post post-996 post type-post status-publish format-standard hentry category-uncategorised"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-154222c2 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="http://cloud9342111.sbs/advanced-registry-tracer-the-ultimate-tool-for-windows-registry-management/" target="_self" >Advanced Registry Tracer: The Ultimate Tool for Windows Registry Management</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-10T22:30:07+01:00"><a href="http://cloud9342111.sbs/advanced-registry-tracer-the-ultimate-tool-for-windows-registry-management/">10 September 2025</a></time></div> </div> </li><li class="wp-block-post post-995 post type-post status-publish format-standard hentry category-uncategorised"> <div class="wp-block-group alignfull is-content-justification-space-between is-nowrap is-layout-flex wp-container-core-group-is-layout-154222c2 wp-block-group-is-layout-flex" style="border-bottom-color:var(--wp--preset--color--accent-6);border-bottom-width:1px;padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)"> <h3 class="wp-block-post-title has-large-font-size"><a href="http://cloud9342111.sbs/fatfree-photo-resizer/" target="_self" >FatFree Photo Resizer</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-10T21:44:47+01:00"><a href="http://cloud9342111.sbs/fatfree-photo-resizer/">10 September 2025</a></time></div> </div> </li></ul> </div> </div> </main> <footer class="wp-block-template-part"> <div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--50)"> <div class="wp-block-group alignwide is-layout-flow wp-block-group-is-layout-flow"> <div class="wp-block-group alignfull is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-e5edad21 wp-block-group-is-layout-flex"> <div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex"> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%"><h2 class="wp-block-site-title"><a href="http://cloud9342111.sbs" target="_self" rel="home">cloud9342111.sbs</a></h2> </div> <div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> <div style="height:var(--wp--preset--spacing--40);width:0px" aria-hidden="true" class="wp-block-spacer"></div> </div> </div> <div class="wp-block-group is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-570722b2 wp-block-group-is-layout-flex"> <nav class="is-vertical wp-block-navigation is-layout-flex wp-container-core-navigation-is-layout-fe9cc265 wp-block-navigation-is-layout-flex"><ul class="wp-block-navigation__container is-vertical wp-block-navigation"><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Blog</span></a></li><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">About</span></a></li><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">FAQs</span></a></li><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Authors</span></a></li></ul></nav> <nav class="is-vertical wp-block-navigation is-layout-flex wp-container-core-navigation-is-layout-fe9cc265 wp-block-navigation-is-layout-flex"><ul class="wp-block-navigation__container is-vertical wp-block-navigation"><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Events</span></a></li><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Shop</span></a></li><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Patterns</span></a></li><li class=" wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="#"><span class="wp-block-navigation-item__label">Themes</span></a></li></ul></nav> </div> </div> <div style="height:var(--wp--preset--spacing--70)" aria-hidden="true" class="wp-block-spacer"></div> <div class="wp-block-group alignfull is-content-justification-space-between is-layout-flex wp-container-core-group-is-layout-91e87306 wp-block-group-is-layout-flex"> <p class="has-small-font-size">Twenty Twenty-Five</p> <p class="has-small-font-size"> Designed with <a href="https://en-gb.wordpress.org" rel="nofollow">WordPress</a> </p> </div> </div> </div> </footer> </div> <script type="speculationrules"> {"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/twentytwentyfive\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} </script> <script src="http://cloud9342111.sbs/wp-includes/js/comment-reply.min.js?ver=6.8.2" id="comment-reply-js" async data-wp-strategy="async"></script> <script id="wp-block-template-skip-link-js-after"> ( function() { var skipLinkTarget = document.querySelector( 'main' ), sibling, skipLinkTargetID, skipLink; // Early exit if a skip-link target can't be located. if ( ! skipLinkTarget ) { return; } /* * Get the site wrapper. * The skip-link will be injected in the beginning of it. */ sibling = document.querySelector( '.wp-site-blocks' ); // Early exit if the root element was not found. if ( ! sibling ) { return; } // Get the skip-link target's ID, and generate one if it doesn't exist. skipLinkTargetID = skipLinkTarget.id; if ( ! skipLinkTargetID ) { skipLinkTargetID = 'wp--skip-link--target'; skipLinkTarget.id = skipLinkTargetID; } // Create the skip link. skipLink = document.createElement( 'a' ); skipLink.classList.add( 'skip-link', 'screen-reader-text' ); skipLink.id = 'wp-skip-link'; skipLink.href = '#' + skipLinkTargetID; skipLink.innerText = 'Skip to content'; // Inject the skip link. sibling.parentElement.insertBefore( skipLink, sibling ); }() ); </script> </body> </html>