#!/usr/bin/perl package main; use Term::ANSIColor; # DVD2mp3: Rip a DVD and make an mp3. $cpr= '#################################################################### # This Perl script is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public # License (as published by the Free Software Foundation) or the # Artistic License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public # License along with this program; if not, write to the Free # Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ####################################################################'; # Version $VERSION = 0.4; ## GET READY. print colored ['cyan'], "$0: == GETTING READY ==\n"; # Catch signals. sub catch_zap { my $signame = shift; print colored ['cyan'], "$0: == CLEANING UP ==\n"; unlink $fifo if ($fifo); die "Somebody sent me a SIG$signame"; } $SIG{INT} = \&catch_zap; $SIG{TERM}= \&catch_zap; # Check for prereqs. use Config; my(@path) = split /$Config{'path_sep'}/, $ENV{'PATH'}; foreach (@path) { if (-f "$_/mplayer") { $mplayer = 1; } if (-f "$_/lame") { $lame = 1; } } if (! $mplayer) { die "$0: Can't find MPlayer\n Error"; } if (! $lame) { die "$0: Can't file LAME\n Error"; } # Get command-line options. $help = < -t=: Set title to rip from. --stream= -s=<T>: Set audio stream to rip from. --help -h: Print this message. --version : Print the version. END foreach (@ARGV) { if ((/^\-v$/) || (/^\-\-verbose$/)) { print colored ['green'], "$0: Got arg: verbose\n"; $verbose = 1; } elsif ((/^\-\-fifo$/) || (/^\-f$/)) { $fifo = "$1"; } elsif ((/^\-\-help$/) || (/^\-h$/)) { print $help; exit; } elsif (/^\-\-version$/) { print "dvd2mp3 $VERSION\n"; print "$cpr\n"; exit; } elsif ((/^\-\-stream=(.+)$/) || (/^\-s=(.+)$/)) { print colored ['green'], "$0: Ripping stream: $1\n" if ($verbose); $stream="$1"; } elsif ((/^\-\-title=(.+)$/) || (/^\-t=(.+)$/)) { print colored ['green'], "$0: Ripping title: $1\n" if ($verbose); $title="$1"; } else { print colored ['green'], "$0: Writing to file: $_\n" if ($verbose); $file = "$_"; } } # Sanity check 1: Check arguments. if (! $file) { die "$0: Please specify file\n Error"; } # Sanity check 2: Default FIFO. if (! $fifo) { $fifo = "soundpipe"; } # Check for audio stream. unless ($stream) { print colored ['blue'], "$0: Checking audio streams...\n" if ($verbose); open(AUDIO,"mplayer -v dvd:// 2>&1 |") || die "$0: Can't search for audio streams...\n Error"; while (<AUDIO>) { if (/==> Found audio stream: 128/) { print colored ['green'], "$0: Found English audio track (128)\n" if ($verbose); $stream = "128"; close(AUDIO); } } } if (!$stream) { die "$0: Couldn't find English audio stream (128). $0: Please specify it manually on the command line\n Error"; } # Check for FIFO. if ((! -p "$fifo") && (-f "$fifo")) { print "$0: \"$fifo\" is not a FIFO\n$0: Remaking it." if ($verbose); unlink "$fifo"; } if (! -p "$fifo") { use POSIX qw(mkfifo); $main::mkfifo=1; mkfifo("$fifo", 0700) || die "$0: Can't create FIFO: $!\n Error"; } ## START RIPPIMG print colored ['cyan'], "$0: == RIPPING ==\n"; print colored ['blue'], "$0: Starting LAME: lame -b 64 $fifo \"$file\"...\n" if ($verbose); open(LAME, "lame -b 64 $fifo \"$file\" |"); print colored ['blue'], "$0: Starting MPlayer: mplayer -quiet -ao pcm:file=$fifo -vo null -vc dummy -aid 128 dvd://$title...\n" if ($verbose); open(MPLAYER,"mplayer -quiet -ao pcm:file=$fifo -vo null -vc dummy -aid 128 dvd://$title 2>&1 |"); while (<MPLAYER>) { print "mplayer: $_" if ($verbose); } while (<LAME>) { print "lame: $_"; } ## CLEAN UP print colored ['cyan'], "$0: == CLEANING UP ==\n"; unlink "$fifo"; =pod =head1 NAME dvd2mp3 - Convert a DVD to an MP3 =head1 SYNOPSIS dvd2mp3 [options] [file] =head1 DESCRIPTION B<dvd2mp3> rips a DVD to an MP3 (SURPRISE!!!) using L<MPlayer|mplayer(1)> and pipe-ing the audio through L<LAME|lame(1)>. Don't worry, it doesn't rip in real-time. It accepts various options to specify how it rips, but you usually don't have to use them. =head1 OPTIONS =over 1 =item B<--verbose|-v> Print extra info. =item B<--title=<TITLE>|-t=<T>> Set title to rip from. =item B<--stream=<TITLE>|-s=<T>> Set audio stream to rip from. =item B<--help|-h> Print this message. =back =head1 EXAMPLES # Rip the first track to F<movie.mp3> (should work for most DVDs) dvd2mp3 movie.mp3 # Rip the first track to F<movie.mp3> verbosely. dvd2mp3 -v movie.mp3 # Rip the third track to F<movie.mp3> dvd2mp3 -t=3 movie.mp3 # Rip audio stream 300 on the first track to F<movie.mp3> dvd2mp3 -s=300 movie.mp3 =head1 SCRIPT CATEGORIES Audio : MP3 =head1 AUTHOR Michael Howell <m_howell123@yahoo.com> =head1 COPYRIGHT Copyright (c) 2007 Michael Howell. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO L<mplayer(1)> L<lame(1)> =cut