ra2mp3.pl
#!/usr/bin/perl
#
# Get a RealAudio stream and transcode it to MP3 for offline listening.
# (c) Andrew Flegg 2005. Released under the Artistic Licence.
# http://www.bleb.org/software/
#
# Syntax: ra2mp3 [<options>] <URL> [<outfile>]
# -m, --mono Produce a mono MP3
# -b, --bitrate=BITRATE Set the bitrate of the MP3 (default: 192)
# -o, --offset=SECOND Skip the first SECOND seconds
# -q, --quiet Be vewwy vewwy quiet
# -t, --title=TITLE Override the resulting title ID3 tag
# -a, --author=AUTHOR Override the resulting author ID3 tag
# -c, --comment=COMMENT Override the resulting comment ID3 tag
#
# If output filename is prefixed with 'scp:', the result is copied to the
# remote machine using scp.
#
# Examples:
# ra2mp3 -m -b 48 -o 7230 http://www.bbc.co.uk/radio/aod/shows/rpms/radio4/today.ram scp:website.somehost.com:public_html/misc/Today.mp3
# ra2mp3 http://www.bbc.co.uk/radio4/hitchhikers/media/discovery.ram
use warnings;
use strict;
use Getopt::Long;
use LWP::Simple;
use File::Temp qw(tempfile);
use File::Basename qw(basename);
use vars qw($CACHE $FREQ $LAME $QUIET);
$CACHE = 128;
$FREQ = 44.1;
$QUIET = 0;
my %options = ();
GetOptions(\%options, "help|?",
"mono|m",
"quiet|q",
"bitrate|b:i",
"title|t:s",
"author|a:s",
"comment|c:s",
"offset|o:i");
die <<EOM if $options{"help"} or not @ARGV;
ra2mp3 [options] <URL> [<outfile>] (c) Andrew Flegg 2005.
~~~~~~ Released under the Artistic Licence
Options:
-h, --help This message
-b, --bitrate=BITRATE Set the bitrate of the MP3 (default: 192)
-o, --offset=SECOND Skip the first SECOND seconds
-t, --title=TITLE Override the resulting title ID3 tag
-a, --author=AUTHOR Override the resulting author ID3 tag
-c, --comment=COMMENT Override the resulting comment ID3 tag
-q, --quiet Be vewwy vewwy quiet
If outfile is prefixed with 'scp:' the path will be passed to SCP.
Please report bugs to <andrew\@bleb.org>. Thanks.
EOM
$options{"offset"} ||= 0;
$options{"bitrate"} ||= 192;
$QUIET = defined($options{'quiet'});
# -- Get the rtsp:// URL if this is a playlist ----------------
#
my $url = $ARGV[0];
if ($url =~ /^\w+tp:.*\.ram$/i) {
$url = get($url);
} elsif (-f $url and $url =~ /\.ram$/i) {
die "Unable to handle local playlists (yet).";
}
# -- Add the offset -------------------------------------------
#
if ($options{"offset"}) {
$url =~ s/[\?\&]start=[^&=]+//i;
$url .= ($url =~ /\?/ ? '&' : '?');
$url .= 'start='.$options{'offset'};
}
# -- Fetch the file using mplayer -----------------------------
#
my ($out, $outFile) = tempfile( "ra2mp3-XXXX", SUFFIX => '.pipe.wav', DIR => '/tmp');
$out->close();
unlink $outFile;
system('/bin/mknod', $outFile, 'p');
open(IN, "mplayer -ao pcm -aofile $outFile -vo null -quiet -noconsolecontrols -cache $CACHE \Q$url\E 2>&1|") or die "Unable to open mplayer: $!\n";
my $inInfo = 0;
my %data = ( name => $options{'title'},
author => $options{'author'},
comment => $options{'comment'} );
while(<IN>) {
next if /Cache fill/i;
print unless $QUIET;
last if /Starting playback/i;
$inInfo ||= /Clip info:/;
next unless $inInfo;
last if /=====+/;
next unless /^\s*(\w+):\s*(.*?)\s*$/;
$data{$1} ||= $2;
#print "+++ Set '$1' to '$2'\n";
}
# -- Determine MP3 file name ----------------------------------
#
my $mp3File = $ARGV[1];
unless ($mp3File) {
if ($data{'name'}) {
$mp3File = $data{'name'}.'.mp3';
} else {
$mp3File = basename($ARGV[0]);
$mp3File =~ s/\.\w+$//;
$data{'name'} = $mp3File;
$mp3File .= '.mp3';
}
}
my $remote = '';
if ($mp3File =~ s/^scp://) {
$remote = $mp3File;
my $mp3;
($mp3, $mp3File) = tempfile("ra2mp3-XXXX", SUFFIX => '.mp3', DIR => '/tmp');
$mp3->close();
}
my $mode = ($options{'mono'} ? 'm' : 'j');
my $child = fork();
if ($child == 0) {
exec('lame','-b',$options{'bitrate'},'-m',$mode,'--resample',$FREQ,
($QUIET ? '--quiet' : ''),
$data{'name'} ? ('--tt', $data{'name'}) : (),
$data{'author'} ? ('--ta', $data{'author'}) : (),
$data{'copyright'} ? ('--tc', $data{'copyright'}) : (),
$outFile, $mp3File) == 0 or die "LAME failed: $!\n";
}
wait;
unlink $outFile;
# -- Copy elsewhere if required...
#
if ($remote) {
system("scp $mp3File $remote ".($QUIET ? '1>/dev/null' : ''));
unlink $mp3File;
}
print "$data{name} transcoding complete.\n";
exit;
Generated by GNU Enscript 1.6.5.90.