dvda-author vs Alternatives: Choosing the Right DVD Tool

How to Use dvda-author to Create Professional DVDsCreating professional-looking DVDs doesn’t require expensive commercial software — with dvda-author, a powerful open-source toolset, you can build polished DVDs complete with menus, chapters, subtitles, and multiple audio tracks. This guide walks through everything from installation to advanced menu customization, showing practical examples and tips so your DVDs look and behave like those produced by commercial tools.


What is dvda-author?

dvda-author is an open-source command-line tool that assembles MPEG-2 video, audio, subtitle streams, and menu XML into a DVD-compliant VIDEO_TS structure. It’s commonly used on Linux and other Unix-like systems and is often paired with tools like ffmpeg (for encoding), spumux (for subtitle multiplexing), and mkisofs/genisoimage (for creating ISO images).

Key components:

  • dvdauthor: the main authoring tool that reads an XML project file and creates VIDEO_TS.
  • ffmpeg or mencoder: used to encode source video into DVD-compliant MPEG-2.
  • spumux: creates VOB-compatible subtitle streams (SPU).
  • growisofs or wodim: used to burn the final ISO to a disc.
  • mkisofs/genisoimage/xorriso: create ISO images.

Installing required tools

On Debian/Ubuntu:

sudo apt update sudo apt install dvdauthor ffmpeg spumux mkisofs growisofs 

On Fedora:

sudo dnf install dvdauthor ffmpeg spumux genisoimage growisofs 

If a package is unavailable in your distro, build from source or use alternative names (e.g., xorriso instead of mkisofs).


Workflow overview

  1. Encode source videos to DVD-compliant MPEG-2 VOBs (using ffmpeg or mencoder).
  2. Create subtitle SPU streams using spumux (if needed).
  3. Write a dvdauthor XML project describing menus, titles, chapters, and audio/subtitle tracks.
  4. Run dvdauthor to build the VIDEO_TS structure.
  5. Optionally create an ISO with mkisofs/genisoimage/xorriso.
  6. Burn the ISO to disc with growisofs/wodim.

Preparing and encoding video

DVD requires MPEG-2 video with specific bitrate/resolution standards (NTSC: 720×480, 29.97 fps; PAL: 720×576, 25 fps). Use ffmpeg to transcode:

Example for PAL:

ffmpeg -i input.mp4 -target pal-dvd -aspect 16:9 -b:v 5000k -b:a 192k output.mpg 

Example for NTSC:

ffmpeg -i input.mp4 -target ntsc-dvd -aspect 16:9 -b:v 6000k -b:a 192k output.mpg 

Split long videos into chapters while encoding (optional) — you can later define chapters in the dvdauthor XML or create separate title sets.


Creating subtitles (SPU)

If you have subtitle files (e.g., .srt), convert them to SPU streams:

  1. Convert SRT to OSDL XML (tools like subtitler or manual conversion).
  2. Use spumux to multiplex subtitles into an .spu file:
spumux -o subtitles.spu -s 25 subtitle.xml 

The -s 25 specifies PAL timing; use 29.97 for NTSC if needed.


Writing the dvdauthor XML

dvdauthor uses an XML file to define menus, titles, chapters, and audio/subtitle tracks. Here’s a basic example that creates a menu and a single title:

<?xml version="1.0" encoding="utf-8"?> <dvdauthor>   <vmgm>     <menus>       <pgc>         <pre>jump title 1;</pre>       </pgc>     </menus>   </vmgm>   <titleset>     <titles>       <title>         <vob file="output.mpg" />       </title>     </titles>   </titleset> </dvdauthor> 

This simple XML creates a menu that immediately jumps to the first title. More complex menus will reference background images, button positions, and button commands.


Creating graphical menus

Menus are built from a background video or image and button definitions. You can use a static PNG as the background and define buttons with coordinates.

Example:

<vmgm>   <menus>     <pgc>       <vob file="menu_background.mpg" />       <button highlight="0,0,100,40" select="goto title 1;" />       <button highlight="0,50,100,90" select="goto title 2;" />     </pgc>   </menus> </vmgm> 

To use a PNG background convert it to MPEG:

ffmpeg -loop 1 -i menu.png -t 10 -r 25 -s 720x576 -b:v 2000k menu_background.mpg 

Buttons require exact pixel coordinates (left, top, right, bottom). Test and tweak positions using a previewing tool like lsdvd or by burning a test DVD.


Chapters and multi-title DVDs

Define chapters inside a element:</p> <pre><code><title> <vob file="episode1.mpg"> <chapter> <vob filepos="00:10:00" /> </chapter> <chapter> <vob filepos="00:20:00" /> </chapter> </vob> </title> </code></pre> <p>Alternatively use multiple <title> elements for separate movies/episodes.</p> <hr> <h3 id="multiple-audio-tracks-and-subtitles">Multiple audio tracks and subtitles</h3> <p>Specify audio tracks in the title, pointing to separate audio files or streams. Example:</p> <pre><code><title> <vob file="movie.mpg" /> <audio lang="en" file="audio_eng.ac3" /> <audio lang="es" file="audio_spa.ac3" /> <subpicture lang="en" file="subtitles.spu" /> <subpicture lang="es" file="subtitles_es.spu" /> </title> </code></pre> <p>Make sure audio is in AC3 or MP2 format supported by DVD players.</p> <hr> <h3 id="building-the-dvd">Building the DVD</h3> <p>Run dvdauthor with your project file:</p> <pre><code>dvdauthor -o DVD -x project.xml </code></pre> <p>This creates a DVD/VIDEO_TS directory in ./DVD. Validate with totem, vlc, or a standalone DVD player.</p> <p>Create an ISO:</p> <pre><code>mkisofs -dvd-video -o dvd_image.iso DVD/ </code></pre> <p>Or with xorriso:</p> <pre><code>xorriso -as mkisofs -o dvd_image.iso -dvd-video DVD/ </code></pre> <p>Burn to disc:</p> <pre><code>growisofs -Z /dev/dvd -audio -dvd-compat -J -R -V "MyDVD" dvd_image.iso </code></pre> <hr> <h3 id="common-problems-troubleshooting">Common problems & troubleshooting</h3> <ul> <li>Video not playing: confirm NTSC/PAL settings and MPEG-2 compliance.</li> <li>Menu buttons not responding: check button coordinates and button commands.</li> <li>Subtitles out of sync: ensure framerate and timing used for spumux match encoded video.</li> <li>File too large: lower video bitrate or split into multiple titles.</li> </ul> <hr> <h3 id="advanced-tips">Advanced tips</h3> <ul> <li>Use templates for menus: design in GIMP/Photoshop, export PNG, convert to MPEG.</li> <li>Scripting: automate repetitive tasks with shell scripts that call ffmpeg, spumux, and dvdauthor.</li> <li>Preview iteratively: convert menu PNG to short MPEG loops to test highlighting and timing.</li> <li>Optimize bitrate: use two-pass ffmpeg encoding for better quality at constrained bitrates:</li> </ul> <pre><code>ffmpeg -y -i input.mp4 -target pal-dvd -pass 1 -b:v 5000k -an -f rawvideo /dev/null ffmpeg -i input.mp4 -target pal-dvd -pass 2 -b:v 5000k -b:a 192k output.mpg </code></pre> <hr> <h3 id="example-complete-minimal-project">Example: Complete minimal project</h3> <p>Files: movie.mp4, menu.png, subs.srt</p> <p>Steps (summarized):</p> <ol> <li>Encode movie: ffmpeg -i movie.mp4 -target pal-dvd output.mpg</li> <li>Convert menu PNG: ffmpeg -loop 1 -i menu.png -t 10 -r 25 -s 720×576 menu_background.mpg</li> <li>Convert subs and mux: (convert SRT to XML) spumux -o subs.spu -s 25 subs.xml</li> <li>Create project.xml (example shown above, adapted)</li> <li>dvdauthor -o DVD -x project.xml</li> <li>mkisofs -dvd-video -o dvd.iso DVD/</li> <li>growisofs -Z /dev/dvd -dvd-compat dvd.iso</li> </ol> <hr> <p>Creating professional DVDs with dvdauthor takes some learning, but it gives you complete control over menus, chapters, and tracks without relying on proprietary software. With practice and careful encoding, your results can match commercial DVDs in look and functionality.</p> </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://cloud93421.baby/latitude-longitude-calculator-with-distance-bearing-area-tools/" rel="prev">Latitude Longitude Calculator with Distance, Bearing & Area Tools</a></div> <div class="post-navigation-link-next wp-block-post-navigation-link"><a href="http://cloud93421.baby/how-the-talking-moose-vista-changed-mac-humor-forever/" rel="next">How The Talking Moose Vista Changed Mac Humor Forever</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="/dvda-author-vs-alternatives-choosing-the-right-dvd-tool/#respond" style="display:none;">Cancel reply</a></small></h3><form action="http://cloud93421.baby/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='572' 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-1074 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://cloud93421.baby/maximize-your-earnings-the-ultimate-pay-calculator-guide/" target="_self" >Maximize Your Earnings: The Ultimate Pay Calculator Guide</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-12T11:39:09+01:00"><a href="http://cloud93421.baby/maximize-your-earnings-the-ultimate-pay-calculator-guide/">12 September 2025</a></time></div> </div> </li><li class="wp-block-post post-1073 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://cloud93421.baby/opensc/" target="_self" >OpenSC</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-12T09:59:54+01:00"><a href="http://cloud93421.baby/opensc/">12 September 2025</a></time></div> </div> </li><li class="wp-block-post post-1072 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://cloud93421.baby/windows-hardware-collector/" target="_self" >Windows Hardware Collector</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-12T08:03:14+01:00"><a href="http://cloud93421.baby/windows-hardware-collector/">12 September 2025</a></time></div> </div> </li><li class="wp-block-post post-1071 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://cloud93421.baby/khmer-language-spelling-dictionary-enhance-your-vocabulary-and-writing-skills/" target="_self" >Khmer Language Spelling Dictionary: Enhance Your Vocabulary and Writing Skills</a></h3> <div class="has-text-align-right wp-block-post-date"><time datetime="2025-09-12T06:19:38+01:00"><a href="http://cloud93421.baby/khmer-language-spelling-dictionary-enhance-your-vocabulary-and-writing-skills/">12 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://cloud93421.baby" target="_self" rel="home">cloud93421.baby</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://cloud93421.baby/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>