#!/usr/bin/perl -w
use strict;
##############################################################################
# Quickly rip DVD to iPod format #
# #
# Author: Michael A. Smith #
# Credits: blackace, infi on #
# freenode #
# Modified: April 30, 2006 #
# Description: Rips DVD to MP4 for iPod. #
##############################################################################
# Globals :-/
my $dev = getDvdDevice();
my $numTitles = getNumTitles();
# We'll be starting at main();
main();
sub main {
rip();
encode();
}
# rip the dvd to avi
sub rip {
foreach(1..$numTitles) {
my $avi = "Title $_.avi";
my $mencode = "mencoder dvd://$_ $dev -ovc copy -oac copy -alang en -o '$avi'";
my $death = "\n\nUnable to rip track $_!\nFailed to execute $mencode\n\n\n";
!system "$mencode" or die "$death";
}
}
# convert the avi to mp4
sub encode {
my @res = getResolutions();
ejectDvd();
my $log = "ffmpeg2pass-0.log";
if (-e "$log") {unlink "$log";}
foreach my $avi (glob "*.avi") {
my $mp4 = $avi;
$mp4 =~ s/\.avi$/.mp4/;
my $res = shift(@res);
foreach(1..2) {
my $ffmpeg = "ffmpeg -y -pass $_ -vcodec xvid -b 750 -acodec aac -ab 96 -i '$avi' -s $res '$mp4'";
my $death = "\n\nUnable to encode $avi!\nFailed to execute $ffmpeg\n\n\n";
!system "$ffmpeg" or die "$death";
}
if (-e "$log") {unlink "$log";}
if (-e "$avi") {unlink "$avi";}
}
}
# get title resolutions
sub getResolutions {
my @resList;
foreach(1..$numTitles) {
my $command = "mplayer dvd://$_ $dev -vo null -ao null -frames 0";
foreach(split(/\n/, `$command`)) {
# Line looks like: "Movie-Aspect is 1.78:1 - prescaling to correct movie aspect."
if ($_ =~ /^Movie-Aspect is ([0-9.]*):([0-9.]*) -.*$/) {
my $width = 480;
my $height = sprintf("%.0f", $width * $2 / $1);
if ($height % 2) {$height--;}
push(@resList, "${width}x${height}");
}
}
}
return @resList;
}
# get the number of titles from dvd
sub getNumTitles {
my $command = "mplayer dvd:// $dev -identify -vo null -ao null -frames 0 -novideo";
my $result = `$command`;
foreach(split(/\n/, $result)) {
if ($_ =~ /^ID_DVD_TITLES=([0-9]+).*$/) { return $1; }
}
}
# get dvd device from args, if specified
sub getDvdDevice {
if (@ARGV) {
if (($ARGV[0] eq "-D") or ($ARGV[0] eq "--dvd-device")) {
return "-dvd-device $ARGV[1]";
}
}
return ""; # no argument, no foul :-)
}
sub ejectDvd {
if (@ARGV) {
if (($ARGV[0] eq "-D") or ($ARGV[0] eq "--dvd-device")) {
system "eject $ARGV[1]";
return;
}
}
system "eject";
}