Friday, April 6, 2012

DVD Backup

Here's how I currently backup my kids' DVDs to single CD-sized AVI files (mostly tested with PAL animation DVDs):
  1. find the main title (usually the longest):
    $ lsdvd
    ...
    Title: 21, Length: 01:31:58.200 Chapters: 42, Cells: 43, Audio streams: 05, Subpictures: 15
    ...
    
    (lsdvd is also kind enough to report the number of the longest title)
    Alternatively, you can use mplayer to do this too:
    mplayer -msglevel identify=6 -frames 0 dvd://
    (it also lists the language audio tracks on the disc)
  2. extract the MPEG2 stream with mplayer
    mplayer -dumpstream -dumpfile temp/title.mpg dvd://21
  3. calculate encoded video bit-rate with the script that's listed below:
    $ calc_video_bitrate.py 1:31:58 128 700
    bitrate: 929.650763
    
    (the command line arguments are, in order: duration of video, audio target bitrate in kbit/sec and encoded file size in MB)
  4. rip the MPEG2 stream into an AVI file, in two passes, using ffmpeg - note that I use the -map command line option to keep only a single audio track (my kids don't speak English, yet):
    ffmpeg -i temp/title.mpg -pass 1 -ac 2 -ab 128k -ar 44100 -acodec libmp3lame -b 929.65k -s 640x360 -map 0:0 -map 0:3  temp/title.pass1.avi
    ffmpeg -i temp/title.mpg -pass 2 -ac 2 -ab 128k -ar 44100 -acodec libmp3lame -b 929.65k -s 640x360 -map 0:0 -map 0:3  temp/title.avi
    
The code for calculating video bit-rate is based on JavaScript code found at http://quadpoint.org/projects/simplerip.


#! /usr/bin/env python

import sys

def bitrate2bytes(bitrate, length):
    # bitrate in kbit/s
    # length in seconds
    # returns number of bytes
    return (bitrate * length * 1000) / 8.0

def bytes2bitrate(size, length):
    # size in bytes
    # length in seconds
    # returns bitrate in kbit/s
    return size * 8.0 / length / 1000

def calcbr(targetsize, audiosize, length, coverhead):
    # targetsize in bytes
    # audiosize in bytes
    # length in seconds
    # coverhead in percent (container overhead)
    # returns bitrate in kbit/s
    overhead = 1.0 + (coverhead / 100.0)
    size = (targetsize - audiosize) / overhead
    return bytes2bitrate(size, length)

def main():
    if len(sys.argv) != 4:
        print >>sys.stderr, 'Usage: %s hh:mm[:ss] <audio-bitrate-kb-per-sec> <target-size-mb>\n' % sys.argv[0]
        return -1
    
    tokens = sys.argv[1].split(':')
    length = (float(tokens[0]) * 3600 + 
              float(tokens[1]) * 60 +
              (float(tokens[2]) if len(tokens) > 2 else 0))
    audiobr = float(sys.argv[2])
    audiosize = bitrate2bytes(audiobr, length)
    targetsize = float(sys.argv[3])
    tsize = targetsize * 1024 * 1024
    overhead = 0.7
    bitrate = calcbr(tsize, audiosize, length, overhead)
    print 'bitrate: %f\n' % bitrate
    return 0

if __name__ == '__main__':
    sys.exit(main())

No comments:

Post a Comment