Digital Video to DVD encoding under Linux

There are a few things where Linux is truly not ready to go. Converting video from a DV-capable digital camcorder to DVD is one of them.

I’ve been struggling with this for almost the past week. The biggest problem is that it generally takes too long to encode the video. This isn’t helped by the fact that you can’t just generate a 10-second test clip and see how it plays, since the encoding process may mess up later, so you need to test the whole file. However, I almost understand the process now, so I’m going to try to describe it in a step-by-step fashion. Note that I’m assuming NTSC formatting here (used in the U.S. and Japan, but not in Europe), and that since I’ve been having trouble, you may not want to mirror my steps too closely. ;-)

  1. If your computer doesn’t have a FireWire card, go get one. USB (even at 2.0) is just not suited for this kind of thing, and USB-capable DV camcorders generally require some crappy Windows program to work anyways.
  2. You will also need to make sure your kernel is Fire-Wire enabled (look for IEEE1394 in your kernel config). It may already have FireWire configured in. If so, you’ll probably have modules named ieee1394 and ohci1394 in your lsmod output.
  3. If you are not using DevFS (or udev, but I haven’t tested that), you need to make sure you create /dev/ieee1394. Note that it isn’t a device file, but a directory hierarchy, I’m not sure how exactly to create it if you don’t already have it after plugging in your digital camcorder.
  4. Also, you’re going to need a lot of hard drive space. And you’re almost assuredly going to require large file support in both your kernel and glibc, and basically any other software you might be using on the video files.
  5. Now you need to dump the video from your digital camcorder to your hard drive. There are apparently a few programs that can do this, including Kino, a GTK+-based video editor. I wasn’t able to use it since it wasn’t able to compile for some reason, but the command-line tool called dvgrab works just as well. It is by the same author, and available at the Kino site.
  6. dvgrab is more or less easy to use, although you will want to consult the man pages for it. You’ll probably want to export to the DV2 format (–format dv2) using OpenDML (–opendml). You can use the –duration command line option to capture only a given number of minutes of video, although you’ll need to fast foward or rewind to the start position manually first. dvgrab can also automatically split files if they grow too large, but this has annoyed me more than anything else, so I don’t use that. This process happens in real time, so if you’re capturing an hour of video, expect to have dvgrab running for an hour.
  7. If you’re like me, you’ll have a rather large .avi file after performing the capture. For example, a 47 minute video I have is 11277964172 bytes (11 gigabytes) large. Yikes! But whatever you do, as long as the capture process was successfu, don’t delete this file until you are positive your DVD is correct and playable.
  8. Now, you have some options. The general gist of what you’re going to do next is that you are going to be converting the video in the .avi file to MPEG 2, the DVD standard video format, with an extension of .m2v. You’ll be converting the audio in the .avi file to either MPEG Layer II (.mp2, not .mp3) or AC3, both of which are supported by DVD players. You’re going to have a pretty wide collection of encoders/decoders/transcoders at your disposal, none of which will work quite right if you have my luck.
Some programs you can look at are: 

  * [Transcode](http://www.transcoding.org/cgi-bin/transcode), which can convert the audio and video streams of a movie simultaneously to a different format. If this program works for you, I would recommend using it. I was never able to get it to work quite right however.
  * [mjpegtools](http://mjpeg.sourceforge.net/). You'll probably need these installed anyways, but this collection includes a bunch of command line utilities you can use, including the very descriptively named lav2yuv, lav2mpeg, and jpeg2yuv.
  * [ffmpeg](http://ffmpeg.sourceforge.net/). You'll probably also need this installed, as it provides libavcodec, and can be used to encode to AC3 if you'd like.
  * [tooLAME](http://users.tpg.com.au/adslblvi/). This is a MP2 encoder (there is also mp2enc, but it is essentially the MPEG reference encoder). MP2 apparently is the recommended audio format for DVD if you have no special requirements (like 5.1 audio) that would dictate AC3. It's also much easier to use tooLAME than ffmpeg natively.
  * [mplayer](http://www.mplayerhq.hu/). This Linux media player includes a mode to output video and audio to separate files, and the video can be output in a format which is ready to convert. You can use this to encode practically any movie that you can play with mplayer, and is what I've ended up sticking with. Also, mplayer includes the mencoder tool which can be used to fix some kinds of damage in AVI files that may lead to a bad encoding.
  * [xine](http://xine.sourceforge.net/). You're going to need this to test the DVD before you burn it.   9. Anyways… assuming that you have dumped your DV into a file called foo.avi, the first thing you should do is try playing it. I used mplayer, and you don't really have to watch the whole video, but you should skip through it at least, and **pay attention to the mplayer debugging output**. If you see things such as mplayer complaining about the interlacing, or that there's no index, you should use mencoder to fix the file.
`$ mv foo.avi foo-broken.avi<br /> $ mencoder -idx foo-broken.avi -ovc copy -oac copy -o foo.avi`   10. Now you should separate the audio and video streams of the DV avi. You can also use mplayer for this (and if you want, you can even take care of encoding the audio and video before it hits the disk, but let's keep it simple).
`$ mplayer -vo yuv4mpeg -ao pcm -aofile foo-audio.pcm foo.avi`
The audio will be in a file called <tt>foo-audio.pcm</tt>, and the video will be in a file called <tt>stream.yuv</tt>.   11. Then you need to convert the audio and video into their encoded variants.
`$ toolame -s 48 foo-audio.pcm foo-audio.mp2`
The audio is encoded at 48000 Hz, which seems to be the standard for DVD.</p> 
`$ cat stream.yuv | mpeg2enc -F 1 -f 8 -I 1 -a 2 -n n -o foo-video.m2v`
The video is encoded at NTSC frame rate and aspect ratio, and is ready to be converted later using dvdauthor. Note that if you get errors in the resulting DVD, you may need to play around with this command by tweaking the interlacing settings. Note also that this command will take **a long time** to complete.</li> 

  * Assuming that everything went successfully, you need to reintegrate the audio and video streams. This is done using the `mplex` command.
    `$ mplex -f 8 -o foo.mpg foo-video.m2v foo-audio.mp2` 
  * Of course, you're not done yet. The .mpg file has to be DVD-ified. The tool to do this is [dvdauthor](http://dvdauthor.sourceforge.net/). It uses an XML file for its configuration, so I'm just going to say see the website. The XML isn't that difficult if all you need is a single movie on the DVD with no menus. Assuming the XML is dvdauthor.xml, and that the XML specifies an output directory of foo-dvd:
    `$ dvdauthor -x dvdauthor.xml` 
  * You can now use xine to test the DVD, by running:
    `$ xine dvd:/exact/freakin/path/to/dvd/`
    Note that the path ends in &#8216;/' as well.
  * If everything is working good, use mkisofs to make a .iso:
    `$ mkisofs -dvd-video -o foo-dvd.iso foo-dvd` 
  * Once you have the .iso, you can burn it using `growisofs`:
    `$ growisofs -dvd-compat -Z /dev/dvd=/path/to/foo-dvd.iso`
    Of course, you may need to replace /dev/dvd with whatever the appropriate path is to your DVD drive.</ol> 

There are a few GUI tools being developed to try to make all this easier, including [Q DVD Author](http://qdvdauthor.sf.net/) and a Java-based tool, [Varsha](http://varsha.sourceforge.net/). However, this whole experience has made me realize why it is that Macintosh is popular in the multimedia industry, as all this would be _easy_ on Macintosh. :-(