Hack 60. Streaming Internet Audio Broadcasts to TiVo

   

Hack 60 Streaming Internet Audio Broadcasts to TiVo

figs/moderate.gif figs/hack60.gif

Stream SHOUTcast Internet audio alongside your own MP3s to your HMO-enabled TiVo .

TiVo's Home Media Option (HMO) [Hack #63] allows you to stream MP3 music from your home PC through your TiVo to your television and home audio system speakers . But what of those online music broadcasts, streamed talk shows, and specials? The HMO can handle those too, thanks to Tobias Hoellrich's m3ugen.pl (http://www.kahunaburger.com/blog/archives/000054.html).

m3ugen.pl is a simple Perl (http://www.perl.com) script that generates .m3u files from SHOUTcast playlists. These .m3u files are what TiVo uses to stream music from PCs and Macs in your house to TiVo.

The Code

Save the following code to a file named m3ugen.pl somewhere on your PC or Mac's hard drive:

 #!c:\perl\bin\perl.exe use strict; use HTML::LinkExtor; use LWP::Simple; use URI::URL; use constant PROVIDER => qq{http://www.shoutcast.com/}; use constant DIRECTORY => PROVIDER.qq{directory/}; my $genre=$ARGV[0]; my $results=$ARGV[1]; my $outfile=$ARGV[2]; unless (defined($genre) &&     defined($results) && $results && $results <= 25 &&     defined($outfile)) {   die qq{Usage:\t 
 #!c:\perl\bin\perl.exe use strict; use HTML::LinkExtor; use LWP::Simple; use URI::URL; use constant PROVIDER => qq{http://www.shoutcast.com/}; use constant DIRECTORY => PROVIDER.qq{directory/}; my $genre=$ARGV[0]; my $results=$ARGV[1]; my $outfile=$ARGV[2]; unless (defined($genre) && defined($results) && $results && $results <= 25 && defined($outfile)) { die qq{Usage:\t$0 [genre] [numresults] [outfile]\n}. qq{\tgenre=TopTen,House,Blues,Punk,...\n}. qq{\tnumresults=1..25\n}. qq{\toutfile=m3u output file\n}; } my @playlists=getPlaylists(DIRECTORY. qq{?sgenre=$ genre &numresult=$results},PROVIDER); unless (scalar(@playlists)) { die "No results found - unable to create playlist\n"; exit(0); } @playlists=mapForTiVo(@playlists); open (OUT,">".$outfile) or die "Unable to create output file - $!"; print OUT qq{#EXTM3U }; foreach my $entry (@playlists) { my($url,$title)=%$entry; print OUT qq{#EXTINF:,$title $url }; } close(OUT); sub getPlaylists { my($url,$base)=@_; my(@results); my $content=get($url); unless (defined($content) && length($content)) { warn qq{Unable to fetch "$url" }; return @results; } my $parser=HTML::LinkExtor->new(sub { my($t,%a)=@_; return if $t ne 'a'; push(@results,$a{href}) if($a{href}=~/filename\.pls$/i); }); $parser->parse($content); @results = map {$_=url(/books/1/554/1/html/2/$_,$base)->abs;} @results; return @results; } sub mapForTiVo { my(@list)=@_; my(@results); foreach my $url (@list) { my $content=get($url); next unless(defined($content) && length($content)); my($file); foreach my $line (split(/[\n\r]/,$content)) { if ($line =~ /^File\d+=(.*)$/i) { my $u=URI::URL->new($1); $u->path(""),$file=$u->abs if($u->path eq '/'  $u-> path eq ''); } elsif ($line =~ /^Title\d+\s*=(.*)$/i && defined($file)) { push(@results,{$file => $1}); last; } } } return @results; } 
[genre] [numresults] [outfile]\n}. qq{\tgenre=TopTen,House,Blues,Punk,...\n}. qq{\tnumresults=1..25\n}. qq{\toutfile=m3u output file\n}; } my @playlists=getPlaylists(DIRECTORY. qq{?sgenre=$genre&numresult=$results},PROVIDER); unless (scalar(@playlists)) { die "No results found - unable to create playlist\n"; exit(0); } @playlists=mapForTiVo(@playlists); open(OUT,">".$outfile) or die "Unable to create output file - $!"; print OUT qq{#EXTM3U\n}; foreach my $entry (@playlists) { my($url,$title)=%$entry; print OUT qq{#EXTINF:,$title\n$url\n}; } close(OUT); sub getPlaylists { my($url,$base)=@_; my(@results); my $content=get($url); unless (defined($content) && length($content)) { warn qq{Unable to fetch "$url"\n}; return @results; } my $parser=HTML::LinkExtor->new(sub { my($t,%a)=@_; return if $t ne 'a'; push(@results,$a{href}) if($a{href}=~/filename\.pls$/i); }); $parser->parse($content); @results = map {$_=url($_,$base)->abs;} @results; return @results; } sub mapForTiVo { my(@list)=@_; my(@results); foreach my $url (@list) { my $content=get($url); next unless(defined($content) && length($content)); my($file); foreach my $line (split(/[\n\r]/,$content)) { if ($line =~ /^File\d+=(.*)$/i) { my $u=URI::URL->new(); $u->path(""),$file=$u->abs if($u->path eq '/' $u->path eq ''); } elsif ($line =~ /^Title\d+\s*=(.*)$/i && defined($file)) { push(@results,{$file => }); last; } } } return @results; }

Mac OS X should alter the first line to point to the proper location of Perl:

 #!/usr/bin/perl 

Running the Hack

Let's say I share the path c:\tivo\mp3\ on my Windows PC with my TiVo's HMO Music option. Let's also say that I want the top 15 Punk stations from SHOUTcast (http://www.shoutcast.com), so I can listen to the music broadcasts of these stations through my TiVo. I'd invoke the m3ugen.pl at my PC's DOS prompt (Start Run... command ), like so:

 C:\>  perl m3ugen.pl Punk 15 c:\tivo\mp3\Punk.m3u  

If you don't have a copy of the Perl programming language on your system, download and install a copy of ActivePerl from ActiveState (http://www. activestate .com/Products/ActivePerl/).

On a Mac, sharing the path ~/tivo/mp3/Punk.m3u , I'd run m3ugen.pl from the Terminal (Applications Utilities Terminal), as follows :

 %  perl m3ugen.pl Punk 15 ~/tivo/mp3/Punk.m3u  

The script will visit www.shoutcast.com, look up the Punk category, extract the playlists of the 15 most popular Punk stations, download each individual playlist, find TiVo-compatible server entries, and generate a Punk.m3u file.

The HMO only likes streams with URLs of the format:

 http://   hostname:port   

It doesn't work with more "involved " URLs like:

 http://hostname:port/dir/dir 

When asked to play a stream at such a URL, the HMO will simply fail to do so.

You'll then magically find a Punk.m3u section under Music and Photos Music section of your HMO-enabled TiVo. Select it and listen to some of the finest punk music streamed over the Net. See Figure 4-25.

Figure 4-25. The top 15 Punk SHOUTcast stations brought to your TiVo
figs/tivo_0425.gif

The HMO doesn't buffer streamed Internet-audio. If the stream pauses due to traffic congestion or any other problem, the HMO will just punt it and move on.

If Punk's not quite your cup of tea, visit http://www.shoutcast.com and choose a more appropriate genre from the "Choose a genre " pull-down list on the right side of the page. The page will refresh, and you'll end up on a page whose URL begins with http://www.shoutcast.com/directory/?sgenre=. The word after the = (equals sign) is what you should feed m3ugen.pl on the command line to find the most popular streams of that genre.

Tobias Hoellrich


   
Top


Tivo Hacks. 100 Industrial-strength Tips Tools 2003
Tivo Hacks. 100 Industrial-strength Tips Tools 2003
ISBN: 1597490318
EAN: N/A
Year: 2004
Pages: 164

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net