HOWTO Create a DVD:Filesystem
From Gentoo Linux Wiki
|
Contents |
[edit] Simple DVD with no menus
When the encoding is done, you should create a suitable DVD filesystem. You need dvdauthor for this. Dvdauthor can be controlled from the command line, for simple solutions, but as the recent release has support for xml-files for "scripting", this is preferred. It is easier to change things around in an xml-file than on the command line.
First of all, install dvdauthor:
# emerge -av dvdauthor
The simple solution is to just tell dvdauthor where the file is, like this:
$ dvdauthor -o dvd/ -t movie.mpg
Note: you can repeat this command to add more movies as separate titles.
When you are finished run:
$ dvdauthor -o dvd/ -T
You're done! But this DVD won't have any menus of any sort.
[edit] DVD with a cherry on top
[edit] Create the menu images in GIMP
Create a menu background, can be a video or a still photo. It has to be sized 720x576, and if it's an image, a resolution of 75dpi in the x-axis and 80dpi in the y-axis. Add an alpha channel, and create three more transparent layers with GIMP. This guide concentrates on text-based buttons, so write the contents onto one layer and copy that layer two times. Change the color for the text for all the layers. Save all four layers separately and name them as:
- menu_background.png # can be any format (but a lossless format should always be preferred)
- menu_list.png
- menu_select.png
- menu_highlight.png
See the links for images on how it's done. It can be a bit confusing at first.
You may also extract frames from mpeg with convert[] or while you're at GIMP, using a screenshot.
[edit] mux the menu
Grab this into a file.
| File: menu.xml |
<subpictures>
<stream>
<spu
force="yes"
start="00:00:00.00"
image="menu_list.png"
select="menu_select.png"
highlight="menu_highlight.png"
autooutline="infer"
autoorder="rows"
outlinewidth="18">
</spu>
</stream>
</subpictures>
|
DVD takes an mpeg for a menu. You can change silence.mp2 to any kind of audio (e.g. ac3, pcm, or mp2/3).
| File: menu.sh |
#!/bin/bash # -a is for aspect, # 1 - 1 - 1:1 display # 2 - 2 - 4:3 display # 3 - 3 - 16:9 display # 4 - 4 - 2.21:1 display # -n is for frames convert menu_background.png ppm:- | \ ppmtoy4m -n50 -F25:1 -A59:54 -I p -r -S 420mpeg2 | \ mpeg2enc -n p -f8 -b5000 -a3 -o background.m2v dd if=/dev/zero bs=4 count=1920 | \ toolame -b 128 -s 48 /dev/stdin silence.mp2 mplex -f 8 -o background.mpeg background.m2v silence.mp2 spumux menu.xml < background.mpeg > menu.mpeg |
$ ./menu.sh
[edit] dvdauthor
Write a dvdauthor.xml file. You may take a template from the links. You should have a couple of small test .vobs around so you can go with trial and error method. When you're finished, issue:
$ dvdauthor -x dvdauthor.xml
| File: dvdauthor.xml |
<dvdauthor dest="DVD">
<vmgm />
<titleset>
<menus>
<video format="pal" aspect="16:9" widescreen="nopanscan" />
<pgc entry="root">
<button> jump title 1; </button>
<button> jump title 2; </button>
<vob file="menu.mpeg"/>
<post> jump cell 1; </post>
</pgc>
</menus>
<titles>
<video widescreen="nopanscan" />
<pgc>
<vob file="source-1.mpg" />
<post> jump title 2; </post>
</pgc>
<pgc>
<vob file="source-2.vob" chapters="0,0:30,1:00,1:30,2:30,3:00,3:30,4:00"/>
<post> call menu; </post>
</pgc>
</titles>
</titleset>
</dvdauthor>
|
| File: dvdauthor.xml |
<dvdauthor dest="DVD">
<vmgm />
<titleset>
<menus>
<video format="pal" aspect="16:9" widescreen="nopanscan" />
<pgc entry="root">
<button> jump title 1; </button>
<button> jump title 2; </button>
<button> {g3 = 0; jump titleset 2 menu;} </button>
<vob file="menu-1_in_aspect_1.77.mpeg"/>
<post> jump cell 1; </post>
</pgc>
</menus>
<titles>
<video widescreen="nopanscan" />
<pgc>
<vob file="source-1.mpg" chapters="0,0:30,1:00,1:30,2:30,3:00,3:30,4:00"/>
<post> jump title 2; </post>
</pgc>
<pgc>
<vob file="source-2.vob" chapters="0,0:30,1:00,1:30,2:30,3:00,3:30,4:00"/>
<post> call menu; </post>
</pgc>
</titles>
</titleset>
<titleset>
<menus>
<video widescreen="noletterbox" />
<pgc>
<pre> {if (g3 eq 1) {jump titleset 1 menu;} } </pre>
<vob file="menu-2_in_aspect_1.33.mpeg"/>
<post> jump title 1 ; </post>
</pgc>
</menus>
<titles>
<video widescreen="noletterbox" />
<pgc>
<vob file="source-3_in_aspect_1.33.mpeg" />
<post> {g3 = 1; call menu ;} </post>
</pgc>
</titles>
</titleset>
</dvdauthor>
|
| File: dvdauthor.xml |
<dvdauthor dest="./dvd" jumppad="1">
<vmgm>
<!-- *******************************************************************************************************************
Definition of the Title-Menu (vmgm)
//-->
<menus>
<video format="pal" aspect="4:3" />
<audio format="mp2" lang="de" />
<pgc pause="0">
<!--
Register g1 is used to store the origin of a call or jump operation. g1=0 means, we are coming from the vmgm
Register g2 is used to store the actually selected button
Buttons are numbered as <n>*1024 where <n> is the number according to spumux definition
So, if g2 is less than 1024, it's probably uninitialized and the first button should be highlighted as default
If it's 1024 or more, it should have been set correctly before and thus the according button should be highlighted
//-->
<pre> { g1=0;
if (g2 lt 1024) button=1024;
if (g2 ge 1024) button=g2;
}
</pre>
<!--
My vmgm vob is a small movie (approx. 40 secs), that should be played in a loop. This is accomplished with the
pause="0" attribute and the <post> command.
Does work great with xine, my stand-alone is a bit slower, so approx half a second of the audio is missing at the
beginning when the loop is performed.
//-->
<vob file="./Title-Menu/title_menu_spu.mpg" pause="0"/>
<button name="1"> { jump titleset 1 title 1; } </button> <!-- Just play the whole title from beginning //-->
<!-- Store button to highlight when returning
and jump to the audio selection menu //-->
<button name="2"> { g2=button;
jump titleset 1 menu entry audio;
}
</button>
<!-- Store button to highlight when returning,
always highlight the first button in chapter menus
and jump to the root menu of titleset 1 //-->
<button name="3"> { g2=button;
button=1024;
jump titleset 1 menu entry root;
}
</button>
<!-- Same as above, select chapter 1-9 //-->
<button name="4"> { g2=button;
button=1024;
jump titleset 1 menu 2;
}
</button>
<!-- Select chapter 10-18 //-->
<button name="5"> { g2=button;
button=1024;
jump titleset 1 menu 3;
}
</button>
<!-- Select chapter 19-27 //-->
<button name="6"> { g2=button;
button=1024;
jump titleset 1 menu 4;
}
</button>
<!-- Select chapter 28-36 //-->
<button name="7"> { g2=button;
button=1024;
jump titleset 1 menu 5;
}
</button>
<!-- Select chapter 37-45 //-->
<button name="8"> { g2=button;
button=1024;
jump titleset 1 menu 6;
}
</button>
<!-- Select chapter 46-50 //-->
<button name="9"> { g2=button;
button=1024;
jump titleset 1 menu 7;
}
</button>
<post> jump chapter 1; </post> <!-- Go back to beginning (loop the movie) //-->
</pgc>
</menus>
</vmgm>
<!--
End of VMGM-Definition
************************************************************************************************************************ //-->
<!--
Definition of the Titleset
The Titleset consists of
- 1 Title with 50 Chapters
- 1 "Dummy" Root-Menu
- 6 Submenus for Chapter-Selection
- 1 Audio-Menu to choose the audio-track (title has three audio tracks, 2 mp2 (de,en) and 1 ac3 (de))
//-->
<titleset>
<!-- _______________________________________________________________________________________________________________
Menu Definitions
//-->
<menus>
<video format="pal" aspect="4:3" />
<audio format="mp2" lang="de" />
<!--
The root-entry is only a "Dummy" menu with no buttons to select from
It contains a small animation (approx 1,5 secs) which should be played before the
real menu selection is available
Register s7 should contain the chapter that was playing when the menu was called (eg. by a button on the remote).
The goal is to highlight this chapter when the chapter selection menu is shown.
To achieve this, the right submenu must be shown and within this, the right button must be highlighted
Each submenu has up to 9 chapters to choose from, so the desired menu is easy to judge. The jump command makes the
if-statements behave like a case structure, the first matching clause wins.
Register g3 should contain the chapter relative to the submenu to highlight the right button there
xine does handle register s7 properly and this selection works great. My stand-alone seems to have problems with it
because I always end up on menu 2 with the last button (#11) highlighted.
//-->
<pgc entry="root" pause="0">
<vob file="./Chapter-Menu/chapter_menu_ani.mpg" pause="0"/>
<post> { if (s7 le 9) { g3=s7; jump menu 2; }
if (s7 le 18) { g3=s7-9; jump menu 3; }
if (s7 le 27) { g3=s7-18; jump menu 4; }
if (s7 le 36) { g3=s7-27; jump menu 5; }
if (s7 le 45) { g3=s7-36; jump menu 6; }
if (s7 gt 45) { g3=(s7-45); jump menu 7; }
}
</post>
</pgc>
<!--
The following submenus for the chapter selection are defined quite similar, so I only comment the first one
thoroughly
The vob is just a still frame (indeed the last frame of the movie in the root menu above. 9 buttons for the chapters
are placed onto it and additionally 1-3 buttons for intra-menu navigation (1 "Back"-button to resume the movie or jump
back to the vmgm and 2 "Previous"- and "Next"-buttons where applicable.
//-->
<pgc pause="0">
<!--
Register g3 is set to the actual chapter number in relation to the chapters available in this menu.
Multiplied by 1024 it gives the button number to highlight when initially displaying the menu.
//-->
<pre> button=g3*1024; </pre>
<vob file="./Chapter-Menu/vtsm1_1.mpg" pause="inf"/>
<button name="1"> jump title 1 chapter 1; </button> <!-- jump to the specified chapter //-->
<button name="2"> jump title 1 chapter 2; </button>
<button name="3"> jump title 1 chapter 3; </button>
<button name="4"> jump title 1 chapter 4; </button>
<button name="5"> jump title 1 chapter 5; </button>
<button name="6"> jump title 1 chapter 6; </button>
<button name="7"> jump title 1 chapter 7; </button>
<button name="8"> jump title 1 chapter 8; </button>
<button name="9"> jump title 1 chapter 9; </button>
<!-- Go back to where you came from, depemding on
register g1 //-->
<button name="10"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
<button name="11"> jump menu 3; </button> <!-- jump to the next submenu //-->
</pgc>
<pgc pause="0">
<pre> button=g3*1024; </pre>
<vob file="./Chapter-Menu/vtsm1_2.mpg" pause="inf"/>
<button name="1"> jump title 1 chapter 10; </button>
<button name="2"> jump title 1 chapter 11; </button>
<button name="3"> jump title 1 chapter 12; </button>
<button name="4"> jump title 1 chapter 13; </button>
<button name="5"> jump title 1 chapter 14; </button>
<button name="6"> jump title 1 chapter 15; </button>
<button name="7"> jump title 1 chapter 16; </button>
<button name="8"> jump title 1 chapter 17; </button>
<button name="9"> jump title 1 chapter 18; </button>
<button name="10"> jump menu 2; </button> <!-- jump to previous submenu //-->
<button name="11"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
<button name="12"> jump menu 4; </button>
</pgc>
<pgc pause="0">
<pre> button=g3*1024; </pre>
<vob file="./Chapter-Menu/vtsm1_3.mpg" pause="inf"/>
<button name="1"> jump title 1 chapter 19; </button>
<button name="2"> jump title 1 chapter 20; </button>
<button name="3"> jump title 1 chapter 21; </button>
<button name="4"> jump title 1 chapter 22; </button>
<button name="5"> jump title 1 chapter 23; </button>
<button name="6"> jump title 1 chapter 24; </button>
<button name="7"> jump title 1 chapter 25; </button>
<button name="8"> jump title 1 chapter 26; </button>
<button name="9"> jump title 1 chapter 27; </button>
<button name="10"> jump menu 3; </button>
<button name="11"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
<button name="12"> jump menu 5; </button>
</pgc>
<pgc pause="0">
<pre> button=g3*1024; </pre>
<vob file="./Chapter-Menu/vtsm1_4.mpg" pause="inf"/>
<button name="1"> jump title 1 chapter 28; </button>
<button name="2"> jump title 1 chapter 29; </button>
<button name="3"> jump title 1 chapter 30; </button>
<button name="4"> jump title 1 chapter 31; </button>
<button name="5"> jump title 1 chapter 32; </button>
<button name="6"> jump title 1 chapter 33; </button>
<button name="7"> jump title 1 chapter 34; </button>
<button name="8"> jump title 1 chapter 35; </button>
<button name="9"> jump title 1 chapter 36; </button>
<button name="10"> jump menu 4; </button>
<button name="11"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
<button name="12"> jump menu 6; </button>
</pgc>
<pgc pause="0">
<pre> button=g3*1024; </pre>
<vob file="./Chapter-Menu/vtsm1_5.mpg" pause="inf"/>
<button name="1"> jump title 1 chapter 37; </button>
<button name="2"> jump title 1 chapter 38; </button>
<button name="3"> jump title 1 chapter 39; </button>
<button name="4"> jump title 1 chapter 40; </button>
<button name="5"> jump title 1 chapter 41; </button>
<button name="6"> jump title 1 chapter 42; </button>
<button name="7"> jump title 1 chapter 43; </button>
<button name="8"> jump title 1 chapter 44; </button>
<button name="9"> jump title 1 chapter 45; </button>
<button name="10"> jump menu 5; </button>
<button name="11"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
<button name="12"> jump menu 7; </button>
</pgc>
<pgc pause="0">
<pre> button=g3*1024; </pre>
<vob file="./Chapter-Menu/vtsm1_6.mpg" pause="inf"/>
<button name="1"> jump title 1 chapter 46; </button>
<button name="2"> jump title 1 chapter 47; </button>
<button name="3"> jump title 1 chapter 48; </button>
<button name="4"> jump title 1 chapter 49; </button>
<button name="5"> jump title 1 chapter 50; </button>
<button name="6"> jump menu 6; </button>
<button name="7"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
</pgc>
<!--
This is the definition of the audio track selection menu
It can be called from vmgm or with the audio-menu button on the remote or xine
In fact, in xine the audio-menu button does bring up this menu, whereas my stand-alone does not.
Instead, the stand-alone directly toggles through the audio tracks available without showing the menu.
//-->
<pgc entry="audio" pause="0">
<!--
The <pre> command is used to highlight the button with the currently selected audio track
//-->
<pre> button=(audio+1)*1024; </pre>
<!--
The first of the vob-files again contains a little animation (approx. 2 secs) and has no buttons defined
The second vob contains a still frame (the last frame of the first vob) with the buttons spumuxed in
//-->
<vob file="./Audio-Menu/audio_menu_ani.mpg" pause="0"/>
<vob file="./Audio-Menu/audio_menu_spu.mpg" pause="inf"/>
<!--
A click on the highlighted button causes the audio track to be changed and takes you back to where the
menu was called from. Register g1 stores this information. The last button is an explicit resume without
changing the audio track
//-->
<button name="1"> { audio=0;
if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
} </button>
<button name="2"> { audio=1;
if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
} </button>
<button name="3"> { audio=2;
if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
} </button>
<button name="4"> { if (g1 eq 0) jump vmgm menu entry title;
if (g1 eq 1) resume;
}
</button>
</pgc>
<!--
End of Menu Definition
_______________________________________________________________________________________________________________//-->
</menus>
<!--_______________________________________________________________________________________________________________
Title Definition
//-->
<titles>
<!--
Declare the available audio tracks.
Only neccessary item is the lang element, as it can't be determined by dvdauthor
//-->
<audio format="mp2" lang="de" />
<audio format="mp2" lang="en" />
<audio format="ac3" lang="de" />
<pgc pause="0">
<!--
Set register g1 to store the information, that all subsequent calls to menus came from the title and not the vmgm
This way, all menus return via the resume command and the movie continues at the same point the menu was called
//-->
<pre> g1=1; </pre>
<!--
The vob is one huge mpg-file and is divided into 50 chapters
Obviously, the chapters must be defined on one line without any spaces in between. Would be great for visibility,
if the chapters could be wrapped across lines having dvdauthor ignoring any whitespaces between
//-->
<vob file="./episodeII.mpg"
chapters="0:00:00.000,0:00:20.560,0:01:46.480,0:04:09.640,0:06:42.040,0:10:01.240,0:13:56.600,0:20:40.240,0:23:45.520,0:25:29.440,0:30:13.840,0:32:23.560,0:33:24.520,0:34:34.720,0:36:49.840,0:37:46.840,0:39:14.200,0:40:27.040,0:42:11.920,0:43:56.080,0:45:50.680,0:48:15.520,0:50:49.480,0:54:23.320,0:56:31.480,0:58:14.680,1:01:03.520,1:03:39.160,1:08:21.760,1:10:57.400,1:12:16.360,1:14:35.800,1:18:17.680,1:19:42.400,1:26:23.040,1:27:07.480,1:29:47.680,1:31:31.240,1:38:30.640,1:40:03.920,1:45:31.120,1:46:20.040,1:51:38.920,1:53:35.920,1:59:40.200,2:02:26.080,2:05:58.720,2:07:26.200,2:09:15.880,2:10:19.240"
pause="2" />
<!--
When the movie is done, return to the vmgm after 2 seconds
//-->
<post> call vmgm menu entry title ; </post>
</pgc>
<!--
End of Title Definition
_______________________________________________________________________________________________________________//-->
</titles>
</titleset>
</dvdauthor>
|
[edit] test && make iso
$ xine dvd:"$(pwd)/DVD" $ xine dvd:"$(pwd)/DVD" -u 0 # if you have subtitles $ mkisofs -dvd-video -v -o DVD.iso DVD
[edit] Links
- dvdstyler
- An excellent dvdauthor.xml example
- http://forums.gentoo.org/viewtopic.php?t=117709
- DVD authoring in Linux
- Some thoughts on DVD authoring
- Trial and error ; Things that worked and things that did not
- Panteltje's Linux DVD software page
