#!/usr/bin/perl # # Written by Travis Kent Beste # Mon Jul 23 09:30:12 CDT 2007 # # $Id: dvd2mp4.pl,v 1.2 2007/08/16 21:11:46 travis Exp $ # $Source: /cvs_repository/iPhone/dvd2mp4/dvd2mp4.pl,v $ use Data::Dumper; use Getopt::Std; # convert a dvd that you have on the filesystem (or mounted) # to mp4, suitable for iPhone # # requires lsdvd # http://untrepid.com/acidrip/lsdvd.html # # requires HandBrakeCLI # http://handbrake.m0k.org/ #handbrake \ #--format mp4 \ #--width \ #--height \ #--two-pass \ #--deinterlace \ #-i \ #--title \ #-o <output>.mp4 #----------------------------------------# # configuration #----------------------------------------# $|++; #non buffer I/O my %opts; getopt('l:i:o:vdh', \%opts); my $lsdvd = '/home/travis/iPod_video/lsdvd'; my $handbrake = '/home/travis/iPod_video/HandBrakeCLI'; my $input = $opts{'i'} || ''; my $output = $opts{'o'} || './output'; my $log = $opts{'l'} || './convert.log'; my $help = $opts{'h'} || 0; my $verbose = $opts{'v'} || 0; my $debug = $opts{'d'} || 0; my @directories = (); my $base_dir = ''; #----------------------------------------# # main #----------------------------------------# # display usage if they want to usage() if ($help); # exit if usage incorrect usage() if (! -e $input); # open log open(LOG, ">" . $log); if (! -e "$input/VIDEO_TS") { $base_dir = $input; opendir(DIR, $input); @directories = grep(!/^\.+/, readdir(DIR)); closedir(DIR); } else { $input =~ s/\/$//; #print "-->$input\n"; $input =~ /(.*)\/(\w+)$/; $base_dir = $1; $input = $2; push(@directories, $input); } foreach my $directory (@directories) { if (! -e "$directory.mp4") { $dir = $base_dir . '/' . $directory; my $hash = get_lsdvd_hash($dir); # scale accordingly if ( ($hash->{width} == 720) && ($hash->{height} == 480) ) { my $cmd = "$handbrake "; $cmd .= "--format mp4 "; $cmd .= "--width 480 "; $cmd .= "--height 320 "; $cmd .= "--two-pass "; $cmd .= "-i $dir "; $cmd .= "--title " . $hash->{longest_track} . " "; $cmd .= "-o " . $output .'/' . $directory . ".mp4 "; $cmd .= "2>&1 /dev/null"; print "$cmd\n" if ($verbose); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon++; my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec); print "[$timestamp] $cmd\n"; print LOG "[$timestamp] $cmd\n"; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon++; my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec); print "[$timestamp] converting .......... $directory\n"; print LOG "[$timestamp] converting .......... $directory\n"; system $cmd; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon++; my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec); print "[$timestamp] done ................ $directory\n\n"; print LOG "[$timestamp] done ................ $directory\n\n"; } else { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon++; my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec); printf "[$timestamp] video size abnormal . $directory (%dx%d)\n\n", $hash->{width}, $hash->{height}; print LOG "[$timestamp] video size abnormal . $directory\n\n"; } } else { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon++; my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year, $mon, $mday, $hour, $min, $sec); print "[$timestamp] already converted ... $directory\n\n"; print LOG "[$timestamp] already converted ... $directory\n\n"; } } close(LOG); exit(0); #----------------------------------------# # subroutines #----------------------------------------# sub usage { print "usage: $0\n"; print "\t-i : input to process, if directory, process entire directory\n"; print "\t-o : output directory (default: ./output)\n"; print "\t-l : log file\n"; print "\t-v : verbose output\n"; print "\t-d : debug output\n"; print "\t-h : this message\n"; exit (0); } sub get_lsdvd_hash { my $path = shift; my $sub_debug = shift || 0; #--------------------# # get perl output #--------------------# system("$lsdvd -q -p $path > .lsdvd.pl 2>&1 /dev/null"); open(IN, "<.lsdvd.pl"); open(OUT, ">.lsdvd.pl.tmp"); my $gather = 0; while(<IN>) { $gather = 1 if ($_ =~ /^our/); print OUT $_ if ($gather); } print OUT "1;\n"; close(IN); close(OUT); system("mv .lsdvd.pl.tmp .lsdvd.pl"); require '.lsdvd.pl'; #--------------------# # now get the video information #--------------------# open(CMD, "$lsdvd -v $path 2>&1 /dev/null |"); $gather = 0; my @lines = (); while(<CMD>) { $gather = 1 if ( ($gather == 0) && ($_ =~ /^Title/) ); push(@lines, $_) if ($gather); } close(CMD); my $string = sprintf("Title: %02d", $lsdvd{longest_track}); my $gather = 0; my $prev = ''; foreach my $line (@lines) { #print "$line\n"; if ($line =~ /^Title/) { $gather = 1; $prev = $line; } else { if ($gather) { if ($prev =~ /$string/) { print "$line\n" if ($sub_debug); $line =~ /Width: (\d+),/; $lsdvd{width} = $1; $line =~ /Height: (\d+),/; $lsdvd{height} = $1; $line =~ /Aspect ratio: (\d+)\/(\d+),/; $lsdvd{aspect_ratio} = "$1/$2"; $line =~ /FPS: ([\d\.]+),/; $lsdvd{fps} = $1; $line =~ /DF: (\w+)/; $lsdvd{df} = $1; } } $gather = 0; } #print "$gather: $line\n"; } unlink '.lsdvd.pl'; return \%lsdvd; }