Convert any Movie to DVD Video

From ArchWiki
Revision as of 11:31, 6 July 2009 by Ezzetabi (Talk | contribs) (Found the solution about VobSub subtitles.)

Jump to: navigation, search

Tango-document-new.pngThis article is a stub.Tango-document-new.png

Notes: please use the first argument of the template to provide more detailed indications. (Discuss in Talk:Convert any Movie to DVD Video#)
Why another article about this argument? There is a plethora of articles, man pages, blog entries on the Internet about how to convert any
movie to a standard DVD Video viewable to any hardware DVD player. But most of those pages actually focus on one problem. The point of this
article is to summarize most the knowledge necessary in only one place.

The parts of a DVD

For our purposes every movie in the DVD has one video track, at least one audio track, possibly subtitles. We will begin making a simple DVD that just start the movie we put in the DVD player, without any menu. If there is more than one movie you can select them using the chapter function of the DVD player.

The Video

Standard compliant DVD videos have well defined an precise video requirement. The aspect ratio can be '16/9' or '4/3', the available resolutions change if you are making a Pal or a Ntsc DVD. The two standards also have different frame ratios. The codec is the Mpeg-2.

DVDs do not use square pixels, the pixels are rectangular: while the movie has a certain resolution the player have to show it as it were another deforming the pixels. The table show the real resolution and how the player shows it.

NTSC DVD, framerate: 30000/1001 (29.97) or 24000/1001 (23.97)
 Resolution    Displayed as
 720x480       720x540 (4/3) or 854/480 (16/9)
 704x480       720x528 (4/3) 
 352x480       640x480 (4/3) 
 352x240       352x264 (4/3) 

PAL DVD, framerate: 25
 Resolution    Displayed as
 720x576       768x576 (4/3) or 1024/576 (16/9)
 704x576       768x576 (4/3)
 352x576       768x576 (4/3)
 352x288       384x288 (4/3)

As you can read the 4/3 aspect ratio have 4 resolutions, the 16/9 only one. The Ntsc standard gives you two kind of frame rate while Pal only one.

Depending of the country you live on, you have to decide between Ntsc or Pal. In order to decide ratio and resolution you have to see your input movie.

Play you input movie with mplayer (of mplayer package), ensure that mplayer plays exactly what you want to put in the DVD. You might consider options like -ss. --endpos or -chapter.

mplayer show lines like:

Movie-Aspect is 1.39:1 - prescaling to correct movie aspect.
VO: [xv] 512x368 => 512x368 Planar YV12 

Where gives you the aspect ratio and the resolution. In this very example the ratio is 1.39:1 that is quite similar to 4/3 (as is 1.333:1), while the resolution is 512x368 we can put it in a 704x576 Pal DVD or 704x480 Ntsc DVD.

This is fine and good if the input does not have black borders or if the input file have exactly the aspect ratio of 4/3 or 16/9. Otherwise there is some intermediate step to do.

Removing the black borders

If the input file has black borders and its aspect ratio is not 4/3 or 16/9 you have to remove the black border and consider the 'real' resolution and the 'real' aspect ratio. mplayer has a feature to detect the black borders in order to remove them with easy: the cropdetect video filter. Play the movie with -vf cropdetect, seek in the movie a bright scene where the black borders are easily visible. mplayer will give you an output with the correct crop values. Example:

Movie-Aspect is 1.50:1 - prescaling to correct movie aspect.
VO: [xv] 720x480 => 720x480 Planar YV12 
[CROP] Crop area: X: 0..719  Y: 38..440  (-vf crop=720:400:0:40).% 0 0 
[CROP] Crop area: X: 0..719  Y: 38..440  (-vf crop=720:400:0:40).% 0 0 
[CROP] Crop area: X: 0..719  Y: 38..440  (-vf crop=720:400:0:40).% 0 0 

This movie have 40 pixels of black border and its aspect ratio is 1.50. So we sought a bright scene and mplayer said us the correct values for the crop video filter: in this case 720:400:0:40.

Playing again the movie with -vf crop=720:400:0:40 we see the real resolution, unfortunately mplayer will show the old aspect ratio so we have to calculate the real one by hand:

Movie-Aspect is 1.50:1 - prescaling to correct movie aspect.
VO: [xv] 720x400 => 720x400 Planar YV12 

The aspect ratio is actually 720/400 = 1.8; a ratio of 1.8 means we have to use 16/9 (as it is 1.777)

Obtaining the correct aspect ratio

We have movie without black borders with the wrong aspect ratio as DVDs accept only 16/9 or 4/3. Luckily mplayer has another video filter that puts the correct black borders to obtain the correct aspect ratio. The filter is expand. Lets continue the previous example:

mplayer -vf crop=720:400:0:40,expand=:::::16/9:16

mplayer will display the movie with a small black border (we passed from to 1.8 to 1.777 after all). All the heading colons are necessary because the filter would accept many other parameters we leave to default, the trailing :16 instead is necessary because, for encoding reasons, the black borders must have thickness that is a multiple of 16.

Reaching a valid resolution

Now we have to decide the resolution we will use. Of course if we selected the 16/9 aspect ratio we will have only one choice (720x576 for Pal or 720x480 for Ntsc), but if we selected the 4/3 aspect ratio we have to decide. Usually the best selection is the smallest resolution that contains the original movie after removing the black borders or the max resolution if the input file is bigger. For example a 4/3 movie of 640x480 should be put in 704x480 Ntsc or 704x576 Pal. To continue the previous example we will use 720x576 Pal.

The video filter chain becomes: -vf crop=720:400:0:40,expand=:::::4/3:16,scale=720:576,dsize=1024:576 where we scaled to the correct resolution in scale and set the display resolution in dsize following the table.

If mplayer shows something like VO: [xv] 720x576 => 1024x576 Planar YV12 where the first pair is the resolution, the second pair is the displayed resolution and the movie is displayed correctly (no oval heads for example) we are done.

Encoding the video

We finally convinced mplayer to display correctly our video with a aspect ratio of 4/3 or 16/9 in one of the DVD compliant resolutions.

It is finally time of encode the video in a file good for DVD video. We will use mencoder (of mplayer package), mplayer and mencoder share the video filers, so the -vf line we calculated until now will be used to have a fine mpeg2 file.

There is one last thing to decide, the average bitrate of movie. A compliant mpeg-2 video for DVD can have a maximum bitrate of 9800 bits per second. But actually the video usually needs only 4000-5000 kbits per seconds in average. mencoder takes the meaning of average very seriously, so much you can assume that:

(average bitrate) * (movie length in seconds) = (total of bits)

And knowing how many bits you have in the DVD you can calculate your bitrate with great precision.

Kind of DVD   # of bits
DVD-R SL      37658558464
DVD+R SL      37602983936
DVD-R DL      68349329408
DVD+R DL      68383932416

For example if you have a 2 hours movie (7200 seconds), a single 448 kbits per seconds audio track (usual value for 6 channels audio) and a DVD-R SL you might calculate:

37658558464 / 7200 - 448000 = 4782355

There is probably some space wastage in the DVD structure, but we can use 4500 kbits and be fairly safe.

The encoding is made in two passages, the first is about getting information about the movie structure in order to know where the encoder should use more bits (high action scenes) and where it should use less bits (calm or slow paced scenes) in order to use exactly the bits you asked for with the best quality.

Here the commands, as you can understand from the || exit, it is meant to be written in a file:

 rm divx2pass.log

 nice -19 mencoder -nosound -ovc lavc -of rawvideo -vf \
 crop=720:400:0:40,expand=:::::16/9:16,scale=720:576,dsize=1024:576,harddup \
 -ofps 25 -lavcopts vcodec=mpeg2video:turbo:vpass=1:vrc_buf_size=1835\
:vrc_maxrate=9800:vbitrate=4500:keyint=15:vstrict=0:aspect=16/9 \
 -o /dev/null || exit

 nice -19 mencoder -nosound -ovc lavc -of rawvideo -vf \
 crop=720:400:0:40,expand=:::::16/9:16,scale=720:576,dsize=1024:576,harddup \
 -ofps 25 -lavcopts vcodec=mpeg2video:vpass=2:vrc_buf_size=1835\
:cmp=2:dia=2:predia=2:cbp:mv0:lmin=1:dc=10:vstrict=0:aspect=16/9 \ -o movie_video_track.m2v  || exit

Things to notice:

  • there is the video filters chain we calculated until now with the adding of harddup. A necessary filter to obtain standard compliant DVD videos;
  • the bitrate we decided (4500) is the value that appears in vbitrate value;
  • the aspect ratio appears in the aspect value;
  • the -ofps 25 option is there because we wanted a Pal DVD, if you wanted a Ntsc DVD you had to put -ofps 30000/1001;
  • the first passage throws away the video output; the passage is there only to make the information file divx2pass.log;
  • the input file can be replaced with everything mplayer can read, it is of course only a place-holder;
  • there is no sound at the moment;
  • the output is a raw video stream;
  • if you copy and paste ensure there are not leading spaces in the lines starting with a colon.

All the other values are more or less fixed for an high quality DVD compliant conversion, you can (and should) read about in the mencoder man page.

Note: the filter chain shown here is complete in the sense we had to make every passage. If you had an input file already of 16/9 ratio for example you would have only -vf scale=720:576,dsize=1024:576,harddup; if you had a input file of the wrong ratio but without black borders you would have only -vf expand=:::::4/3:16,scale=720:576,dsize=1024:576,harddup; the bare minimum is -vf harddup if you had a movie of a correct resolution and ratio.

Save this commands in a text file and in the shell execute sh filename, the execution of those two commands might take long. But once finished you will have a video stream good for DVD video.

If you have more than one video file (like first part of the movie in a file and the second part in another file) you have to encode both following this instructions, we will put both in the DVD when we will author the DVD.

The Audio

The audio tracks are encoded using the Dolby Surround AC-3 Digital codec, a DVD video can have up to 1536 kbps of audio information, but for each audio track the limit is 448 kbps. You can have mono, stereo or 5.1 audio tracks.

While the heavy constraints of the video makes almost impossible to find a video track without need of encoding, it is fairly common to find files with an ac3 track.

In order to know your input file audio codec you can use mplayer, an example of a file with a fine audio track:

$ mplayer
AUDIO: 48000 Hz, 6 ch, s16le, 448.0 kbit/9.72% (ratio: 56000->576000)
Selected audio codec: [a52] afm: liba52 (AC3-liba52)

If your input file already have ac3 encoded audio track (with an acceptable bitrate) you should not encode it again.

You need only to extract it:

mencoder -alang en -ovc frameno -of rawaudio -oac copy \
-o english_audio.ac3

If the audio track it is not an ac3 file then you have to encode it. Usually ac3 uses 64 or 96 kbps per audio channel.

For 6 channels the encoding command is:

mencoder -alang en -ovc frameno -of rawaudio -channels 6 \
-oac lavc -lavcopts acodec=ac3:abitrate=384 -o english_audio.ac3

or for stereo audio:

mencoder -alang it -ovc frameno -of rawaudio -channels 2 \
-oac lavc -lavcopts acodec=ac3:abitrate=128 -o italian_audio.ac3

Using both commands we will have two files, one per audio track.

Putting Audio and Video together

In order to have only one file with both audio and video we will use mplex (of mjpegtools package), the command line is really easy:

mplex -f 8 -o movie.mpg movie_video_track.m2v english_audio.ac3 italian_audio.ac3

The output file (movie.mpg) will contains both audio tracks and the related video track. mplex is necessary if there is more than one audio tracks, but if you have only one you can actually do everything in one passage. You have to replace the second command of video encoding. For example, making movie.mpg with only the English track in one passage:

 nice -19 mencoder -oac lavc -ovc lavc -of mpeg -mpegopts format=dvd:tsaf -vf \
 crop=720:400:0:40,expand=:::::16/9:16,scale=720:576,dsize=1024:576,harddup \
 -ofps 25 -lavcopts vcodec=mpeg2video:vpass=2:vrc_buf_size=1835\
:aspect=16/9 -channels 6 -o movie.mpg  || exit

Things to notice:

  • the -of option now states mpeg, not raw video;
  • there is a new option: -mpegopts with the settings that mplex hides behind -f 8;
  • there are both the options for video and audio in the -lavcopts.

The Subtitles

The subtitles are merged in the mpeg file and depending of the setting displayed if the user asks (normal subtitles) or always (forced subtitles). Forced subtitles are usually used to translate to the main language the parts of the movie in foreign languages, for example the Elfs speak in The Lord of the Ring.

In DVD video you have 3360 kbps of spaces for subtitles, subtitles are actually pictures of at most 4 colors (one being the transparency): this is the reason why the subtitles often look crude.

In mpeg file there is no relation between the subtitles and languages, only a sid number. While you add subtitles write down the language the subtitle is for every sid. (example: sid 0: english; sid 1: italian; sid 2: french,...)

Textual subtitles

A textual subtitle is easily recognizable, it is a file that opened with a text editor shows the lines of the movie with relative timings. We will use spumux (of the dvdauthor package) to render the text in the movie as subtitle.

The first problem is the font, it is needed a font that is well readable also when rendered in the movie with the heavy constraint of resolution and colors. I found the Xerox Sans Serif Wide Bold that is freely available quite adapt.

spumux seeks for the .ttf file of the font in the directory ~/.spumux, so make that directory and copy the font inside it. For the example we will assume the font file name is then ~/.spumux/xerox.ttf.

The file contains the subtitles for the example is called

spumux uses a .xml file with the settings, here is how our would like:

      <textsub filename=""
         fontsize="22.0" font="xerox.ttf" horizontal-alignment="center"
         vertical-alignment="bottom" left-margin="60" right-margin="60"
         top-margin="20" bottom-margin="30" subtitle-fps="25"
         movie-fps="25" movie-width="720" movie-height="576"

Once made the sub_ita.xml file we have to mix it with the mpeg file, spumux does it:

spumux -s0 sub_ita.xml <movie.mpg >movie_ita_sub.mpg

You should experiment with the position values to obtain a result you like, you should put force="yes" if you wanted forced subtitles. The -s sets the subtitle stream id, if you put more subtitles the value have to be increased.

For example you might add other subtitles after modifying the subtitles file name in the .xml file using:

spumux -s1 sub_fre.xml <movie_ita_sub.mpg >movie_ita_sub__fre_sub.mpg

Subtitles from another DVD video

If you want to extract the subtitles from another DVD you have to use tccat and tcextract (of dvdauthor package) to have the subtitle raw stream. After we convert the raw stream with subtitle2pgm (of transcode package) to pictures and a control file. The control file is understood by spumux.

Assuming the dvd device is /dev/sr0 and the video track is the first we detect the subtitles available with mplayer:

$ mplayer -dvd-device /dev/sr0 dvd://1 -frames 0 2>&1 | grep sid
subtitle ( sid ): 0 language: en
subtitle ( sid ): 1 language: pt

We extract the raw subtitle stream:

tccat -i /dev/sr0 -T 1,-1 | tcextract -x ps1 -t vob -a  $((0x20 + 0)) > subs-en

The value of -a is the sid number of the subtitle + 0x20. In this case we extracted the first subtitle stream, eventually change the second zero to the wanted sid number.

Extracting the pictures from the subtitles makes lots of files, so we make a directory and work on it. subtitle2pgm extracts in black and white and the grey levels must be decided the user. So to begin try:

$ mkdir subs-en-wd
$ cd subs-en-wd
$ subtitle2pgm -i ../subs-en -c 0,85,170,255 -g 4 -t 1

The directory will be filled with the subtitles. Using an image viewer see the colors: you will have white (the 255), light grey (the 170), dark grey (the 85) and black (the 0). Select an unique color for the background and select colors for the other parts: usually letters white and border around letters dark gray. Once you find suitable color scheme delete the folder and execute again subtitle2pgm with the new color scheme.

$ cd ..
$ rm -rf subs-en-wd && mkdir subs-en-wd
$ cd subs-en-wd
$ subtitle2pgm -i ../subs-en -c 224,224,32,0 -g 4 -t 1

subtitle2pgm created the pictures, but also an .xml file usable by spumux. So if the pictures are fine, just use spumux to mix them with the mpeg file.

spumux -s0 movie_subtitle.dvdxml <../movie.mpg >../movie_subs.mpg

Fix picture subtitles

The pictures might be of a wrong resolution (for example, if extracted from a Ntsc DVD and put in a Pal one) and so appear misplaced. To fix the problem there are two approaches: one is converting every picture to the correct resolution; the other is just move the picture.

Lets start with the former. For example you have subtitles as pictures of resolution 720x480 extracted from a Ntsc DVD 16/9. You are making a Pal DVD, so the resolution is 720x576: just putting the subtitles without alterations makes them appear in the centre of the movie.

We do not care that subtitles will appear a little deformed (as the 720 pixels are shown as 1024 in Pal, while in the Ntsc they are shown as 854) and just tell spumux to put the pictures in the bottom.

spumux accepts some options about how to render the subtitle pictures, reading the man page we see we need to use the yoffset option. To alter every line of the .xml file we use sed. The pictures where fine for 480 pixels, since we now have 576 so we have to move down the pictures of 96 pixels, so:

sed -i movie_subtitle.dvdxml -e 's.<spu .<spu yoffset="96" .'

Using sed to alter the .xml file is easy and quick. If you need to add some other options (for example you want forced subtitles) just use the sed expression s.<spu .<spu X where X is the new option you want.

If just moving the subtitle picture is not enough you might want to convert the pictures to the correct resolution. To do that we will use convert (of imagemagick package) and a little bash script.

For example to convert the pictures from the Ntsc resolution to the Pal one, we might write a text file with:

for d in *.png ;do
  convert "$d" -resize '720x575!' +dither -map "$d" tmp.png || break
  mv tmp.png "$d"
  echo "$d"

That does convert every picture without altering the palette (thanks to -map) and making a clean resize (thanks to +dither). The resulting pictures replaced the old ones, so now you can just use the .xml file.

VobSub files

VobSub subtitles are a pair of files an .idx and a .sub sometime compressed as a single .rar file. If you got the compressed version you have to use unrar to decompress and obtain the two files.

The .sub file is an mpeg sequence with only the subtitles. You have to extract is with tcextract

tcextract -i s.sub -x ps1 -a $((0x20 + 0)) > subs-en

It is the same idea of extracting from a DVD, the second 0 is the sid number of the subtitle track you want to extract.

You now have a raw subtitle stream, you can follow the same instruction of the above section.

Authoring the DVD

Still a stub...