#!/usr/bin/perl # # Author: Espen Skoglund # Date: before 1999-02-08 # # Rip music from CD and convert to MP3 # # Hacked by Petter Reinholdtsen , 1999-02-08 sub usage { print "USAGE: $0 [-h][-t] [ []]\n"; } use File::Path; $rip_times_only = 0; while ( $_ = shift ) { if ( /^-t$/ ) { $rip_times_only = 1; } elsif ( /^-?-h(elp)?$/ ) { $0 =~ s!.*/([^/]+)$!\1!; usage(); exit; } else { push( @args, $_ ); } } ($topdir, $trbegin, $trend) = @args; if ( ! $topdir ) { usage(); exit; } $dagrab = find_prog_in_path("dagrab"); $cdparanoia = find_prog_in_path("cdparanoia"); $cdda2wav = find_prog_in_path("cdda2wav"); $gcdplay = find_prog_in_path("gcdplay"); $l3enc = find_prog_in_path("l3enc"); $bladeenc = find_prog_in_path("bladeenc"); $mp3_8hz = find_prog_in_path("8hz-mp3"); # Choose encoder if ( $l3enc ) { $mp3encoder = "$l3enc _infile_ _outfile_"; } elsif ( $bladeenc ) { $mp3encoder = "$bladeenc _infile_ _outfile_ -br 192000"; } elsif ( $mp3_8hz ) { $mp3encoder = "$mp3_8hz -b 128 _infile_ _outfile_"; } $tmp = $ENV{TMPDIR} || '/tmp'; $[ = 1; ## Get artist and tracknages from CDDB if ( $gcdplay ) { # extract online from CDDB open (GCDPLAY, "$gcdplay -q -i|") || die "open($gcdplay -q -i |): $!\n"; while () { chomp; if (m/^CD TITLE:/) { ($artist) = m%^CD TITLE: (.+\S)\s*/[^/]+$%; ($title) = m%/\s*([^/]+)$%; } if (m/\d+: /) { my ($track, $name) = m/^(\d+): (.+)$/; $names[$track] = $name; } } close(GCDPLAY); } else { print "Unable to find gcdplay. It is required to fetch title and track\n"; print "names from CDDB. Fetch gcdplay from\n"; print ".\n"; exit; } if ($artist) { $artist =~ s%/%&%g; print "Artist: $artist\n"; print "Title: $title\n"; $destdir = "$topdir/$artist/$title"; mkpath($destdir, 0, 0775); } else { print "Error: CD is unknown to CDDB. Unable to extract info, and\n"; print "thereby unable to rip. Add it to CDDB.\n"; exit; } $numnames = scalar(@names); ## Get tracktimes if ( $cdparanoia ) { open( TOC, "$cdparanoia -Q 2>&1|" ) || die "open(cdparanoia -Q |): $!\n"; while( ) { push( @times, $1 ) if /^\s*\d+\.\s*\d+\s*\[(\d+:\d*)/; } close TOC; } elsif ( $dagrab ) { open( TOC, "$dagrab -i 2>&1|" ) || die "open(dagrab -i |): $!\n"; while( ) { push( @times, $1 ) if /\d\d:(\d\d:\d\d)/; } close TOC; } elsif ( $gcdplay ) { open( TOC, "$gcdplay -di 2>&1|" ) || die "open(gcdplay -di |): $!\n"; my (@starttimes, $endtime); while( ) { chomp; $endtime = $1 * 60 + $2 if /^\d+ Tracks, (\d+) minutes and (\d+) seconds/; push(@starttimes, $1 * 60 + $2) if /minute: \[(\d+)\] second: \[(\d+)\]/; } close TOC; my $lasttime; for $time (@starttimes, $endtime) { if ($lasttime) { my $sec = $time - $lasttime; my $time = sprintf("%02d:%02d", int($sec / 60), ($sec%60)); push(@times, $time); } $lasttime = $time; } } $numtracks = scalar(@times); ## Warn if the number of tracknames does not match number of tracks if ( $numtracks && !$rip_times_only && $numnames != $numtracks ) { warn ("Warn: The number of names is not equal to the Number of ". "tracks on CD.\n (Number of tracks = $numtracks, ". "number of names = $numnames)\n"); } $trbegin = 1 unless $trbegin; $trend = $numtracks if $numtracks && !$trend; ## Store tracktimes. $timesfile = "$destdir/.times"; open( TIMES, ">$timesfile" ) || die "open(>$timesfile): $!\n"; foreach $time ( @times ) { print TIMES "$time\n"; } close TIMES; exit if $rip_times_only; ## Start processing the tracks my $pid = 0; foreach $track ( $trbegin .. $trend ) { # Get the track from the CD. if ( $cdda2wav ) { system "$cdda2wav -D /dev/cdrom -x -t $track+$track ". "$tmp/track-$track.wav 2>&-"; } elsif ( $dagrab ) { system "$dagrab -f $tmp/track-$track.wav $track 2>/dev/null 1>/dev/null"; } elsif ( $cdparanoia ) { system "$cdparanoia $track $tmp/track-$track.wav 2>&-"; } else { die "I don't know of any cdrippers.\n"; } # Wait for the previous encoding to get finished. waitpid( $pid, 0 ) if $pid != 0; # Fork off a new process that does the encoding. We may then start # reading another track from the CD. unless ( $pid = fork ) { chdir($destdir); my $time = $times[$track]; my $name = $names[$track] || "Track $track"; my $mp3enc = $mp3encoder; my $destfile = sprintf( "%02d - %s.mp3", $track, $name ); $destfile =~ s/\"/\\\"/g; $destfile =~ s/\\/\\\\/g; $mp3enc =~ s!_infile_!$tmp/track-$track.wav!; $mp3enc =~ s!_outfile_!\"$destfile\"!; print sprintf("Encoding: %02d - $name\n", $track); # MP3 encode the track system "$mp3enc >/dev/null 2>&1"; # Remove temporary wav file. unlink "$tmp/track-$track.wav"; exit; } } # Wait for last encoding to be finished waitpid( $pid, 0 ) if $pid; sub find_prog_in_path { my $prog = shift; for $dir (split(/:/, $ENV{PATH})) { my $fullpath = "$dir/$prog"; return $fullpath if ( -x $fullpath ); } return; # Not found }