Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Book On CD

by abitkin (Monk)
on Sep 08, 2002 at 05:12 UTC ( [id://195982]=sourcecode: print w/replies, xml ) Need Help??
Category: Audio
Author/Contact Info jasmoft146@hotmail.com
Description: Okay, so I listen to books on CD, but having 20 cds around with me, for 1 book kind of sucks to haul around. So I got a MP3 cd player, but then playing the story in order took some special formatting in file names and directories. So I made this script to help me out, as I use more than 1 cdrom at a time, there's configuration for which drive you want, along everthing else. As it is set up, I'm able to get about 22 discs onto 1 mp3 cd.
#!/usr/local/bin/perl -w
#########################################
# File -        BookOnCD.pl
# Date -        Saturday, September 07, 2002
# Description - A script for ripping Books on
#                 CD to mp3s while keeping a
#                 format that a mp3 cd player
#                 can read.
#########################################
use strict;

#########################################
# Function -    prompt
# Date -        Saturday, September 07, 2002
# Input -        String to print to the user
# ReturnVal -    If the user hit Y for yes
# Description -    Verifies that the user has
#                 said yes.
#########################################
sub prompt {
    my $msg = shift;
    print $msg;
    my $rsp = <STDIN>;
    $rsp =~/^y/i;
}

#########################################
# Function -    prompt2
# Date -        Saturday, September 07, 2002
# Input -        String to print to the user
# ReturnVal -    A number that the user 
#                 enters
# Description -    Gets  a number from the user
#########################################
sub prompt2 {
    my $msg = shift;
    print $msg;
    my $rsp = <STDIN>;
    $rsp =~ /^(\d+)/;
    return int(($rsp));
}
#########################################
# Function -    getCount
# Date -        Saturday, September 07, 2002
# Input -        A scalar representing a 
#                 cdrom on your system
# ReturnVal -    An integer
# Description -    The number of tracks on the
#                 audio cd in the device
#                 specified
#########################################
sub getCount {
    my $device = shift;
    my $direct = shift;
    open(PH, "cdparanoia -Q -d $device 2>&1 1>/dev/null |");
    my $max=0;
    while(<PH>){
        /^\s(\d+)\./;
        $max = int($1) if defined($1);
    }
    close PH;
    return $max;
}

#########################################
# Function -    ripIt
# Date -        Saturday, September 07, 2002
# Input -        Various information for this
#                 cd.
# ReturnVal -    None
# Description -    This is the "Magic" function
#                 that rips the mp3s from the
#                 cd and puts them in order
#########################################
sub ripIt {
    my $directory = shift;
    my $Device    = shift;
    my $Title     = shift;
    my $Disc      = shift;
    my $Start     = shift;
    my $tracks    = getCount($Device, $directory);
    my $LineP = "cdparanoia -d $Device -p";
    $LineP .= "-S 52" if $Device eq "/mnt/cdrom2";
    $LineP .= "-S 6" if $Device eq "/mnt/cdrom1";
    $LineP .= "-S 12" if $Device eq "/mnt/cdrom";
    my $LameP = "lame -r -a -v -V 6 -b 32 -B 192 -p --ta \"Disc $Disc\
+" --tl \"$Title Disc $Disc\"";
    my $file = "";
    my $line;
    my $lame;
    my $clean;
    my $p1 = $tracks - $Start+1;
    my $p2;
    my $p3;
    my $p4;
    print "Starting Rip on $Title, Disc $Disc.\n";
    print "$tracks tracks to be ripped.\n";
    print "0 Tracks Done. (0%)";
    select((select( STDOUT ), $| = 1)[0]);
    foreach my $i ($Start .. $tracks){
        $file = $directory . "/" . $main::alpha[$i] . ".mp3";
        $line = $LineP . " \"$i\" $directory/track_$i.raw 2>/dev/null 
+1>/dev/null;\n";
        $lame = $LameP . " --tt \"Track $i\" --tn \"$i\" $directory/tr
+ack_$i.raw $file 2>/dev/null 1>/dev/null;";
        $clean = "yes | rm $directory/track_$i.raw 2>/dev/tty4 1>/dev/
+tty4";
        system `$line`;
        system ($lame.$clean);
        $p2 = $i - $Start+1;
        $p3 = $p2/$p1;
        $p3 *= 100;
        $p4 = sprintf("%.2f", $p3);
        print("\r$p2 Track".(int($p2)==1?"":"s")." Done. ($p4%)");
        select((select( STDOUT ), $| = 1)[0]);
    }
    print "\n";
}

#########################################
# Function -    ripping
# Date -        Saturday, September 07, 2002
# Input -        Scalar with a device
# ReturnVal -    none
# Description -    First this function asks
#                 which disk you are working
#                 on, then if the directory
#                 for that disk already exists
#                 confirm we want to run, or
#                 make the directory if it
#                 doesn't exist.  Finally
#                 we start ripping the cd
#########################################
sub ripping {
    my $Title  = shift;
    my $Device = shift;
    my $Disc   = prompt2("Disc Number?: ");
    @main::alpha = ('AA' .. 'BZ');
    unshift @main::alpha, "00";
    
    my $directory = $main::alpha[$Disc];
    if(-d $directory){
        exit unless prompt("Directory Exists, Replace? (Y|N): ");
    }else{
        system("mkdir $directory");
    }
    ripIt($directory,$Device,$Title,$Disc,1);
    system("eject $Device");
}


#########################################
# Function -    prompt4
# Date -        Saturday, September 07, 2002
# Input -        String to print to the user
# ReturnVal -    If the user hit q for quit
# Description -    Checks to see if we are ready
#                 to quit.
#########################################
sub prompt4 {
    my $msg = shift;
    print $msg;
    my $rsp = <STDIN>;
    $rsp =~/^q/i;
}

#########################################
# Function -    prompt3
# Date -        Saturday, September 07, 2002
# Input -        String to print to the user
# ReturnVal -    Scalar w/ the user's response
# Description -    Used in picking the device
#########################################
sub prompt3 {
    my $msg = shift;
    print $msg;
    my $rsp = <STDIN>;
    return $rsp;
}

my @dev = ("/dev/cdrom","/dev/cdrom1","/dev/cdrom2");
my $title  = prompt3("Title of this Book: ");
chomp $title;
my $device = "/dev/cdrom" . prompt2("Device: /dev/cdrom");
chomp $device;

# The loop for ripping
do {
    system("eject -t $device");
    ripping($title, $device);
}while(! prompt4("Hit Enter to continue, or q to quit. "));

Edited
Fixed an error with stderr and cdparanoia.
Replies are listed 'Best First'.
(jeffa) Re: Book On CD
by jeffa (Bishop) on Sep 08, 2002 at 15:08 UTC
    Looks good, but it would look a whole lot better with some POD in there. Get rid of those ugly comments that explain what each subroutine does and replace them with some sexy POD. Personally, i prefer to put all POD at the end of the script, but you can place each description of the subroutines with the subroutines if that eases your burden of documentation. (Me, i just use gvim and split the window :D). Here is an example to get you started (hint,hint):
    # The loop for ripping do { system("eject -t $device"); ripping($title, $device); }while(! prompt4("Hit Enter to continue, or q to quit. ")); __END__ =head1 NAME BookOnCD.pl - BooksOnCD to MP3 =head1 DATE Most recently modified on ... (CVS could do this for you, BTW) =head1 DESCRIPTION This script will rip BooksOnCD to an MP3 format that is readable by today's popular MP3 CD players. =head1 SUBROUTINES =over 4 =item B<prompt> $boolean = prompt($scalar); Verifies that the user typed some form of 'yes' =item B<ripIt> ripIt($directory,$device,$title,$disc,$tracks,$tracks); This is the "Magic" function that rips the MP3's from the CD and orders them. =back =head1 AUTHOR atbitkin =cut
    Now, all you need do is type perldoc BookOnCD.pl and receive instant usage and API documentation. You can also beef up your script easily with POD::Usage and one of the Getopt modules if necessary. By using the power of POD, you can use comments for what they are really best for - comment what an otherwise unintuitive piece of code is suppose to do - not turn your program into a maintenance nightmare. Have fun! :)

    Oh yeah ... you can find out more about POD via perlpod.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: Book On CD
by abitkin (Monk) on Sep 08, 2002 at 18:18 UTC
    As jeffa pointed out, I still have some work on this. I was on fairly heavy painkillers, so of course it has it's own problems. I thought I'd outline my goals for the next version: (I may or may not get to them, but here they are in no peticular order.)
    • POD documentation (thanks jeffa)
    • More Generalized (eg. Get rid of the speeds for my cdroms, and have a config file)
    • Multi-Thread the app, to have it work on more than 1 cdrom at a time
    • Make a GUI through TK
    • Improved headers
    • Progress Bar
    • Estimated Time Done
    • Paths to apps (like cdparanoia and lame)
    • Generalized options for apps
    • Better Logs
    • Checking for Ctrl-C to quit
    • Check for incomplete files
    • Options for directory Structure
    • Applet in gnome w/ progress on each cd


    I know it's a long list, but like I said, their goals. Any other suggestions are appreciated; and let me know if you find this script useful.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://195982]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-03-29 12:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found