[MPlayer-users] dvd->iso->mpg4

Andres Meyer andres.meyer at computer.org
Sat Apr 12 13:33:15 CEST 2003


As more and more people are asking privately, I post it here. A method to do 
dvd backups:

a) make an iso using the rip.c program (I am sure there are better methods, 
this was just the easiest one for me): 

test# rip /dev/dvd > test.iso

b) if you want to keep all the DVD-menus etc, leave it. If not, use the enc.py 
script to encode it to mpg4.

Andres


rip.c:

/* -*- Mode: C; compile-command: "gcc rip.c -o rip -ldvdcss"; -*- 
 * Rip an entire dvd to stdout.
 * Get libdvdcss
 *
 */

#include <stdlib.h>
#include <dvdcss/dvdcss.h>

int main( int argc, char *argv[] )
{
    dvdcss_handle dvdcss;
    const unsigned int BLOCKS = 32;
    unsigned char buf[ DVDCSS_BLOCK_SIZE * BLOCKS];
    unsigned int  numberOfBlocks = 0;;

    /* Check for 2 arguments */
    if( argc != 2 )
    {
        printf( "rips dvd to stdout. usage: %s <device>\n", argv[0] );
        return -1;
    }

    /* Initialize libdvdcss */
    dvdcss = dvdcss_open( argv[1] );
    if( dvdcss == NULL )
    {
        printf( "argh ! couldn't open DVD (%s)\n", argv[1] );
        return -1;
    }

    dvdcss_title( dvdcss, 0 );

    while(1) {
      /* Read one sector */
      numberOfBlocks = dvdcss_read( dvdcss, buf, BLOCKS, DVDCSS_READ_DECRYPT 
);
      if( numberOfBlocks < 1 )
        break;

      /* Print the sector */
      write( 1, buf, numberOfBlocks * DVDCSS_BLOCK_SIZE);

    }
 
    /* Close the device */
    dvdcss_close( dvdcss );

    return 0;
}

enc.py:

#!/usr/bin/python
#
# mencoder dvd backup script

import os
import re
import sys
import getopt
import string

usage = """
usage:
   ./enc.py -i, --iso movie.iso [OPTIONS]
or ./enc.py -d, --dvd /dev/dvd [OPTIONS]

options:

-o, --output movie.avi    resulting movie
-l, --language en,fr,de   two-letter language codes
-p, --pretend             only print mencoder commands to screen
-t, --track 2             try this track first
-x, --deinterlace         deinterlace movie
"""

try:
        opts, tmp = getopt.getopt(
                sys.argv[1:], "i:o:l:d:pt:x",
                ["iso=", "output=", "language=",
                 "dvd=", "pretend", "track=", "deinterlace"])
except getopt.GetoptError:
        print usage
        sys.exit(2)


source = None
target = None
languages = "en,de,fr"
pretend = None
telecine = 0
deinterlace = ""
aid = None
trackNum = 1

for o, a in opts:
        if o in ("-i", "--iso"):
                if target == None:
                        path, ext = os.path.splitext( a)
                        target = "%s.avi" % path

                source = a
        if o in ("-d", "--dvd"):
                source = a
        if o in ("-o", "--output"):
                target = a
        if o in ("-l", "--lang"):
                languages = a
        if o in ("-p", "--pretend"):
                pretend = 1
        if o in ("-t", "--track"):
                trackNum = int(a)
        if o in ("-x", "--deinterlace"):
                deinterlace = "pp=0x20000,"

if source == None:
        print usage
        sys.exit(2)

print "source: %s, target: %s, languages: %s\n" % (source, target, languages)


cx = 10000
cy = 10000
cw = 0
ch = 0

cropNum = None
dvdInfo = ""
while cropNum == None:
        for minute in range( 20, 30):
                cmd = ("mplayer -v -vo null -dvd %s -dvd-device \"%s\" "
                       "-vop cropdetect -ss 00:%s:00 -frames 12") % (
                        trackNum, source, minute)
                print "cmd :%s" % cmd
                dvdInfo = os.popen( cmd).read()
                cropNum = re.compile(
                        r".*\(-vop crop=(.*):(.*):(.*):(.*)\).*").search( 
dvdInfo)

                print dvdInfo

                if cropNum == None:
                        trackNum = trackNum + 1
                        telecine = None
                        if trackNum > 9:
                                sys.exit("movie not found\n")
                        break

                x = int( cropNum.group(3))
                y = int( cropNum.group(4))
                w = int( cropNum.group(1))
                h = int( cropNum.group(2))

                cx = min( cx, x)
                cy = min( cy, y)
                cw = max( cw, w)
                ch = max( ch, h)

                if re.compile( r".*3:2 TELECINE.*").search( dvdInfo) != None:
                        telecine += 1

print "\nCrop=(%s:%s:%s:%s)" % (cw, ch, cx, cy)

resMatch = re.compile( r".*Movie-Aspect is (.*):1.*").search( dvdInfo)
aspect = float( resMatch.group(1))
print "Aspect=%s" % aspect

resMatch = re.compile(
        r".*VIDEO:  MPEG2  (.*)x(.*)  \(aspect.*\) (.*) fps .*").search( 
dvdInfo)
resX = int( resMatch.group(1))
resY = int( resMatch.group(2))
fps = float( resMatch.group(3))

print "fps from dvd = %s" % fps

if telecine > 1:
        print "fps override = 23.976"
        ofps = "-ofps 23.976"
else:
        ofps = " "

res = re.compile(
        r"audio stream: (.*) audio format: (.*) \((.*)\) language: (.*) aid: 
(.*)\n")

llist = string.split( languages, ",")
llist.reverse()

for lang in llist:
        for match in res.finditer( dvdInfo):
                if match.group(4) == lang:
                        aid = match.group(5)
                        if match.group(3) == "5.1" or match.group(2) == "dts":
                                break
if aid == None:
        cmdlang = "-alang %s" % languages
else:
        cmdlang = "-aid %s" % aid

print "language set to: %s\n" % cmdlang

newAspect = (float(cw) / float(resX))/(float(ch) / float(resY)) * aspect

cmd = ("nice -18 mencoder -dvd %s -dvd-device \"%s\" %s -ovc lavc "
       "-vop %scrop=%s:%s:%s:%s %s -oac copy -lavcopts "
       "vcodec=mpeg4:aspect=%s:vhq:v4mv:vbitrate=2000") % (
        trackNum, source, ofps, deinterlace, cw, ch, cx, cy, cmdlang, 
newAspect)

cmd1 = "%s:vpass=1 -o /dev/null" % cmd
cmd2 = "%s:vpass=2 -o \"%s\"" % (cmd, target)


print
print
print "%s; %s" % (cmd1, cmd2)

if pretend == None:
        os.popen( cmd1).read()
        os.popen( cmd2).read()



More information about the MPlayer-users mailing list