Back to main page

The Quick-n-Dirty Guide to DVD Backup

I find it quite repulsive that the behaviour of the major music and movie corporations forces me to include this disclaimer, but here it is:

This guide is provided for informational purposes only. I in no way advocate copyright infringement. The reader is hereby warned to use this guide in a manner consistent with all applicable copyright laws.

This guide demonstrates how to back up single- and dual-layer DVD media onto single-layer recordable DVD media (DVD+R and DVD-R) on Unix-like operating systems (e.g. Linux). If you run Windows, there are many point-and-click tools that should get the job done.

Note that MPEG video is a fairly complex beast, and thus there are many ways of skinning it. This guide shows you a way that works for the author. Other methods exist, using other tools. If you find a way that works better for you, great.

Tools of the Trade

You will need to download and install the following tools. For help on this, see The Quick-N-Dirty Guide to Finding and Installing Software or your distribution's documentation.

In order to back up single-layer DVDs, you will need the following tools:

Backing up dual-layer DVDs onto single-layer media is a little bit harder. In addition to mkisofs, MPlayer (not optional for dual-layer DVD backup), and cdrecord-ProDVD from the single-layer tools list, you will need:

Filesystem Layout

Locate a filesystem with enough free space. You will need at least twice the size of the largest disc you plan to backup: around 10 gigabytes for single-layer DVDs and 18 gigabytes for dual-layer ones (you can probably get by with less for dual-layer discs, but don't blame me if you run into problems due to running out of space). Create a directory called scratch, and create the following subdirectories: burndvd, masterdvd, mirrordvd, ripdvd, shrinkdvd, subdvd, and xmldvd. For the sake of convenience, if you have root access, symlink your scratch directory to /scratch:

ln -s scratch /scratch
If you do not have root access, you will just have to substitute the path to your scratch directory for /scratch for the remainder of this guide.

Single- or Dual-Layer?

If you do not know whether your source DVD is single- or dual-layer, stick it in your DVD drive, mount it as a UDF filesystem, and run:

df -h /mnt/dvd
(assuming that /mnt/dvd is where you mounted the DVD). If df reports that the disc is 4.3 gigabytes (because single-layer DVDs hold 4.7 billion bytes, not 4.7 gigabytes--4.7 times 2^10 (kilobytes) times 2^10 (megabytes) times 2^10 (gigabytes)) or less, you have yourself a single-layer disc. Otherwise, it is dual-layer.

Single-Layer DVDs

If the DVD you are backing up is a single-layer disc, then you can make a perfect copy (minus the pesky region lock if DeCSS is legal where you live), with menus and everything. Here is how:

  1. Insert the DVD and mount it as a UDF filesystem
  2. Set a volume name for the disc (you can get the actual volume name using lsdvd, or you can just make one up; in either case, it should be all uppercase and contain no spaces--use underscores instead):
    export vol="SOME_VOLUME_NAME"
    
  3. Mirror the disc with vobcopy:
    vobcopy -m -t ${vol} -v -o /scratch/mirrordvd/
    
    If DeCSS is legal where you live, vobcopy may well have been built with DeCSS support, in which case the resulting mirror is region-free. See the vobcopy documentation for details.
  4. [Optional] Preview the mirror with MPlayer:
    mplayer -dvd-device /scratch/mirrordvd/${vol} dvd://1
    
    On some DVDs, the feature is not title 1. If this is the case, or you want to see what is on the other titles, look at the output that MPlayer spewed to your terminal. It should list the number of titles on the disc. A better way to view get this information is lsdvd, which also lists the duration of each title.
  5. If the preview was OK, unmount the DVD. You can take it out of the drive, as you will not be needing it again for the remainder or the backup process. If the preview showed some problems, you can try again with the vobcopy method, or use the more complex method that we will demonstrate for backing up dual-layer DVDs.
  6. Use mkisofs to generate a DVD filesystem image:
     mkisofs -dvd-video -udf -V ${vol} -o /scratch/burndvd/${vol}.iso /scratch/mirrordvd/${vol}
    
  7. [Optional] Mount the image as a loopback device (as root!):
    test -d /mnt/iso || mkdir /mnt/iso
    mount -t UDF -o loop /scratch/burndvd/${vol}.iso /mnt/iso
    
    and preview with MPlayer:
    mplayer -dvd-device /mnt/iso dvd://1
    
    (Remember, title 1 may not be what you want in all cases; see above.) Do not forget to unmount the image when you are done (as root!):
    umount /mnt/iso
    
  8. Insert a blank DVD (use DVD+R or DVD-R, whichever is appropriate for your DVD recorder--note that DVD-RW media will probably not work) and use cdrecord-ProDVD to burn the image to a disc:
    cdrecord-ProDVD -v dev=ATAPI:0,0,0 speed=4 -dao -eject /scratch/burndvd/${vol}.iso
    
    If cdrecord-ProDVD bombs out with an error like:
    ***
    
    you probably have an expired key. Search for CDR_SECURITY in the cdrecord-ProDVD README file and follow the steps outlined there.
    This guide assumes that your DVD drive is capable of being used as an ATAPI device, and that it is the first ATAPI device on the bus. If this is not the case, you will have to refer to either the cdrecord man page or some other documentation, such as this entry in the LinuxQuestions.org Linux Wiki. You can also use a GUI recording suite, such as a DVD-enabled version of K3b or X-CD-Roast.

Dual-Layer DVDs

If the DVD you are backing up is a dual-layer disc, and your drive only supports single-layer media (or you do not want to pony up the cash for the more expensive dual-layer media), you will have to use a more intricate method. (If you are backing up a dual-layer DVD onto dual-layer media, you should be able to use the single-layer backup method without problems.)

  1. Insert the source DVD into your DVD drive. No need to mount it.
  2. Use lsdvd to determine which title or titles you want to backup:
    lsdvd
    
    lsdvd will print out some statistics on the disc:
    Disc Title: FOO_BAR_AND_FOOBAR
    Title: 01, Length: 01:39:57 Chapters: 19, Cells: 20, Audio streams: 03, Subpictures: 02
    Title: 02, Length: 00:11:26 Chapters: 02, Cells: 02, Audio streams: 01, Subpictures: 03
    Title: 03, Length: 00:29:05 Chapters: 04, Cells: 04, Audio streams: 01, Subpictures: 03
    
    In this case, it should be quite obvious that title 1 is the one that we want. If you are backing up a television show, expect to see three to five titles of the same approximate size, one per episode:
    Disc Title: WINNIE_THE_FOO
    Title: 01, Length: 00:58:37 Chapters: 08, Cells: 09, Audio streams: 03, Subpictures: 02
    Title: 02, Length: 00:56:12 Chapters: 08, Cells: 09, Audio streams: 03, Subpictures: 02
    Title: 03, Length: 00:57:40 Chapters: 08, Cells: 09, Audio streams: 03, Subpictures: 02
    Title: 04, Length: 00:55:16 Chapters: 08, Cells: 09, Audio streams: 03, Subpictures: 02
    Title: 05, Length: 00:11:26 Chapters: 02, Cells: 02, Audio streams: 01, Subpictures: 03
    Title: 06, Length: 00:29:05 Chapters: 04, Cells: 04, Audio streams: 01, Subpictures: 03
    
    Make a note of the titles that you want to backup.
  3. As in the single-layer method, set a volume name for the disc (you can either use the one reported by lsdvd in the previous step, or you can just make one up; in either case, it should be all uppercase and contain no spaces--use underscores instead):
    export vol="SOME_VOLUME_NAME"
    
  4. Use streamanalyze to inspect the title(s) you want:
    for i in `seq 1 4`; do streamanalyze -i /dev/dvd -t ${i}; done
    
    For the seq command, the first number is the first title that you want, and the second is the last title that you want. If want only a single title, use it for both the first and second number, e.g. seq 1 1 for title 1. If you want titles 1, 3, 5, 7, and 11, discard seq from the command and use for i in 1 3 5 7 11 instead. streamanalyze will list the streams present for the selected titles:
    Title 1 - 29 Chapters (3530691 Blocks /  7230855168 Bytes) - Runtime 8898 sec.
    
    Track List:
    X   0xe0  MPEG Video  6194615223 Bytes
    X   0x80   AC3 Audio   510246912 Bytes
    X   0x81   AC3 Audio   218677248 Bytes
    X   0x82   AC3 Audio   218677248 Bytes
    X   0x21  Subpicture     4986797 Bytes
    X   0x23  Subpicture     4986797 Bytes
    X   0x25  Subpicture     4986797 Bytes
    X   0x27  Subpicture     4986797 Bytes
    X   0x20  Subpicture     4986797 Bytes
    X   0x24  Subpicture     4986797 Bytes
    
    Size of selected streams:  7230855168 Bytes
    Max. target size        :  4700000000 Bytes
    Factor                  :  1.691
    
    Based on this information, you will need to decide which streams you want to backup. In the interest of maintaining the highest quality video possible, I recommend that you backup the MPEG Video stream (there will be only one), a single AC3 Audio stream (the first one is most likely the film's native language track, unless you bought it in the US, in which case it is probably English), and as many Subpicture (AKA subtitle) streams as you want (they are so tiny in relation to the video and audio streams). This guide will proceed under the assumption that you chose the MPEG Video stream, AC3 Audio stream 0x80 (this will translate to audio stream 0 for most tools), and Subpicture stream 0x20 (ditto, most tools consider this subtitle stream 0). If you make other arrangements, the onus is on you to make the appropriate changes to subsequent commands.
    As promising as that "Factor" line may look, ignore it unless you are planning to backup all the streams from this title (remember you are sacrificing video quality if you do this!), and this is the only title you are backing up (in which case, note the factor and skip the next step).
  5. Use a Perl one-liner to calculate the video re-quantisation factor. It is probably best to open a new terminal so that you can view the output of the streamanalyze command(s) from the previous step more easily. What we are doing is asking Perl to handle some arithmetic for us:
    1. add up the sizes of all video streams
    2. add up the sizes of all audio streams
    3. add up the sizes of all subtitle streams
    4. subtract the total audio and subtitle sizes from 4600000000 (single-layer DVDs hold 4700000000 bytes, remember--we drop 700 million bytes in our formula to give us some breathing room, as a lot of CPU work must be redone if we are a single byte over the limit)
    5. divide the total video size by the result of the previous step to determine the factor by which we must shrink each video stream
    6. multiply said factor by 1.04 to err on the side of caution even more (this number is the result of trial and error--mess with it at your own peril)
    Or in Perl terms:
    perl -e 'print( (( 1694615223 + 1573869032 + 1752895200 + 1546317236) / (4600000000 - ( 111875698 + 104728283 + 132458647 + 109528594) - ( 2986797 + 2986797 + 2986797 + 2986797)) * 1.04), "\n" )'
    
    The number that is printed--1.65406661613724, is the factor. I recommend rounding it up to the hundredth's place and dropping the rest, giving us 1.66 in our example case. The golden rule for backing up dual-layer DVDs is: when in doubt, make the video smaller.
    If you ever get a factor less than one, you will not need to re-quantise the video at all! Congratulations--just remember to omit the tcrequant step later in this guide.
  6. Rip and process each title. What we will be doing in this step is:
    1. Extracting the chapter information from all titles with lsdvd
    2. Ripping the complete stream for each title with MPlayer
    3. Extracting the video stream for each title with tcextract, and re-quantising it with tcrequant
    4. Extracting the audio stream for each title with tcextract
    5. Extracting the subtitle palette for each title with ifo_dump (ifo_dump_ogle on some systems)
    6. Extracting the subtitle stream for each title with spuunmux
    7. Re-multiplexing the video and audio streams with mplex
    8. Re-multiplexing the subtitle stream with the newly re-multiplexed video and audio with spumux
    This can all be accomplished in one (albeit hairy) command-line:
    vol="WINNIE_THE_FOO"; \
    factor=1.66; \
    for i in `seq 1 4`; do \
      lsdvd -x -t $i >/scratch/xmldvd/${vol}-$i.info && \
      mplayer dvd://$i -dumpstream -dumpfile /scratch/ripdvd/${vol}-$i.vob && \
      tcextract -i /scratch/ripdvd/${vol}-${i}.vob -d 2 -x mpeg2 \
       | tcrequant -d 2 -f ${factor} -o /scratch/shrinkdvd/${vol}-${i}.m2v && \
      tcextract -i /scratch/ripdvd/${vol}-${i}.vob -d 2 -x ac3 -a 0 \
       >/scratch/ripdvd/${vol}-${i}.ac3 && \
      ifo_dump_ogle /dev/dvd ${i} | grep Color | sed 's/Color ..: 00//' \
       >/scratch/subdvd/${vol}-${i}.palette.yuv && \
      spuunmux -v 2 -s 0 -p /scratch/subdvd/${vol}-${i}.palette.yuv \
       -o /scratch/subdvd/${vol}-${i} /scratch/ripdvd/${vol}-${i}.vob && \
      rm /scratch/ripdvd/${vol}-${i}.vob && \
      mplex -f 8 -v 1 -S 0 -o /scratch/shrinkdvd/${vol}-${i}.mpg \
       /scratch/shrinkdvd/${vol}-${i}.m2v /scratch/ripdvd/${vol}-${i}.ac3 && \
      rm /scratch/shrinkdvd/${vol}-${i}.m2v /scratch/ripdvd/${vol}-${i}.ac3 && \
      spumux -m dvd -s 0 -P /scratch/subdvd/${vol}-${i}.xml \
       </scratch/shrinkdvd/${vol}-${i}.mpg \
       >/scratch/shrinkdvd/${vol}-${i}.SUB.mpg && \
      rm /scratch/shrinkdvd/${vol}-${i}.mpg /scratch/subdvd/${vol}-${i}*; \
    done
    
  7. In the terminal that you used for the streamanalyze step, use Perl to print out the chapter marks for each title:
    for i in `seq 1 4`; do \
      cat /scratch/xmldvd/${vol}-${i}.info | grep 'Chapter:' | \
       perl -e 'use DateTime; my $dt = DateTime->new( year => 2005, month => 02, day => 23, hour => 0, minute => 0, second => 0 ); my @ts = ( $dt->hms.".00" ); while (<>){ /^\s+Chapter:.+Length:\s(\d{2}):(\d{2}):(\d{2}),/; $dt->add( hours => $1, minutes => $2, seconds => $3 ); push @ts, $dt->hms.".00"; } print join( ",", @ts ), "\n";'; \
    done
    
  8. Back in your other terminal, create an XML description file of the DVD (this will be fed to dvdauthor in a couple of steps):
    vim /scratch/xmldvd/${vol}.xml
    
    The file should look like this:
    <dvdauthor dest="/scratch/masterdvd">
      <vmgm />
      <titleset>
        <titles>
          <audio lang="EN" />
          <subpicture lang="EN" />
          <pgc>
            <vob file="/scratch/shrinkdvd/VOLUME_NAME-1.SUB.mpg" chapters="00:00:00.00,00:03:28.00,00:06:07.00,00:09:41.00,00:12:39.00,00:15:48.00,00:20:19.00,00:25:33.00,00:30:14.00,00:33:11.00,00:36:29.00,00:40:58.00,00:43:48.00,00:43:48.00" />
            <vob file="/scratch/shrinkdvd/VOLUME_NAME-2.SUB.mpg" chapters="00:00:00.00,00:02:15.00,00:05:27.00,00:09:01.00,00:10:45.00,00:14:06.00,00:19:23.00,00:25:34.00,00:28:47.00,00:32:03.00,00:35:17.00,00:39:52.00,00:43:32.00,00:43:32.00" />
            <vob file="/scratch/shrinkdvd/VOLUME_NAME-3.SUB.mpg" chapters="00:00:00.00,00:01:55.00,00:05:21.00,00:09:02.00,00:14:14.00,00:16:07.00,00:21:45.00,00:23:59.00,00:26:01.00,00:28:11.00,00:32:29.00,00:37:21.00,00:42:17.00,00:42:17.00" />
            <vob file="/scratch/shrinkdvd/VOLUME_NAME-4.SUB.mpg" chapters="00:00:00.00,00:01:50.00,00:07:24.00,00:10:51.00,00:12:33.00,00:16:53.00,00:21:18.00,00:23:26.00,00:26:12.00,00:29:02.00,00:34:27.00,00:38:25.00,00:43:26.00,00:43:26.00" />
          </pgc>
        </titles>
      </titleset>
    </dvdauthor>
    
    Remember to replace VOLUME_NAME in each line above with the actual volume name that you exported near the beginning of this convoluted process (i.e. ${vol})! The numbers inside the chapters attributes are of course the list of numbers reported for each title in the previous step. (See why I recommended using two terminals?)
  9. Use dvdauthor to build a DVD-compliant directory structure:
    dvdauthor -x /scratch/xmldvd/${vol}.xml && \
     dvdauthor -T -o /scratch/masterdvd/ && \
     rm /scratch/shrinkdvd/*
    
    The second invocation of dvdauthor is necessary to write the table-of-contents, without which standard DVD players will not play the disc.
  10. At this point, we have created a DVD directory structure of the sort that vobcopy produced for us in the single-layer backup method. We can now use mkisofs to generate a DVD filesystem image:
     mkisofs -dvd-video -udf -V ${vol} -o /scratch/burndvd/${vol}.iso /scratch/mirrordvd/${vol}
    
  11. [Optional] Mount the image as a loopback device (as root!):
    test -d /mnt/iso || mkdir /mnt/iso
    mount -t UDF -o loop /scratch/burndvd/${vol}.iso /mnt/iso
    
    and preview with MPlayer:
    mplayer -dvd-device /mnt/iso dvd://1
    
    See this step in the single-layer backup method for more details.
  12. Insert a blank DVD (use DVD+R or DVD-R, whichever is appropriate for your DVD recorder--note that DVD-RW media will probably not work) and use cdrecord-ProDVD to burn the image to a disc:
    cdrecord-ProDVD -v dev=ATAPI:0,0,0 speed=4 -dao -eject /scratch/burndvd/${vol}.iso
    
    See this step in the single-layer backup method for more details.

Following all of the steps in either one of these methods should result in a single-layer DVD that can play in any standard DVD player (provided that said DVD player can handle DVD+R or DVD-R media--depending on which you used--but that is a whole other can of worms).

Back to main page

Creative Commons License This work is licensed under a Creative Commons License