After setting up a shoutcast server I tried to find a way to stream my music through it. When I was a windows user winamp with the shoutcast DSP plugin was a nice solution. But now I wanted to stream music that resides on my linux home server. The Shoutcast Transcoder that can be used for this purpose requires a paid license for mp3 streaming. So libshout from Icecast with a perl binding comes to rescue!
Requirements:
- installed and working shoutcast DNAS
- lame (for mp3 transcoding)
- libshout (if not available through your repos you can get it here)
- shout-perl
- MP3::Tag perl module
- Encode perl module (to make your id3 tags utf8 if a non-latin and non-utf8 charset is used)
perl Makefile.PLmakemake install
More information is provided here. If you face any problems make sure that you have libvorbis, libogg and libtheora libraries as well as their corresponding devel packages installed.
Install the MP3::Tag perl module through your repos (available in Centos rpmforge repo) or through CPAN otherwise (perl -MCPAN -e ‘install MP3::Tag’).
Before installing the Encode perl module check if it is already installed by trying to use it! In centos it is part of the perl installation so there is no need to install it!
Now for the nice part! I edited the example2.pl script that was included with Shout.pm installation files. You can see my script here:
#!/usr/bin/perl -w
use strict;
use bytes;
use Shout;
use MP3::Tag;
use Encode;
###############################################################################
### C O N F I G U R A T I O N
###############################################################################
use vars qw{$Debug $Lame};
chomp( $Lame = `which lame` );
my $Bitrate = 64;
my $Samplerate = 44100;
### Create a new streaming object
my $streamer = new Shout
host => 'localhost',
port => 8000,
mount => '',
password => 'my password',
name => 'my radio name',
url => 'http://myurl.example.com/',
genre => 'my genre',
description => 'my description',
bitrate => $Bitrate,
format => SHOUT_FORMAT_MP3,
protocol => SHOUT_PROTOCOL_ICY;
$streamer->set_audio_info(SHOUT_AI_BITRATE => $Bitrate, SHOUT_AI_SAMPLERATE => $Samplerate);
###############################################################################
### M A I N P R O G R A M
###############################################################################
### Try to connect, aborting on failure
if ( $streamer->open ) {
printf "Connected to %s port %d...\n", $streamer->host, $streamer->port;
printf "Will stream to mountpoint '%s'.\n", $streamer->mount;
} else {
printf "couldn't connect: %s\n", $streamer->get_error;
exit $streamer->get_errno;
}
### Stream each file specified in the playlist file on the command line
open(PLSFILE, '<', $ARGV[0]) or die $!;
while (<PLSFILE>) {
my $file = $_;
chomp($file);
print STDERR "Can't read '$file': $!\n" unless -r $file;
print "Sending $file...\n";
my $mp3file = MP3::Tag->new($file);
my $mp3title = $mp3file->title();
my $mp3artist = $mp3file->artist();
eval {
$mp3title = Encode::encode("utf8", Encode::decode("iso-8859-7", $mp3title));
$mp3artist = Encode::encode("utf8", Encode::decode("iso-8859-7", $mp3artist));
};
print "$mp3title - $mp3artist\n";
$streamer->set_metadata(song => "$mp3title - $mp3artist");
### Run lame in downsampling mode on the file we're going to send
open( LAME, "-|" ) || exec $Lame, qw{--mp3input -t -b}, $Bitrate, qw{-m j -f -S}, $file, "-";
my $buff;
READ: while ((my $len = sysread(LAME, $buff, 4096)) > 0) {
print STDERR "Read $len bytes...\n" if $Debug;
$streamer->send( $buff ) && next;
warn( "send failed: ", $streamer->get_error, "\n" );
last READ;
} continue {
$streamer->sync;
}
close LAME;
}
close (PLSFILE);
### Disconnect from the server
$streamer->close;
Copy and paste the above code in a file named streamer.pl and then make it executable (chmod +x streamer.pl).
Edit the fields in the configuration section to suit your needs, especially the host, port and password fields.
On lines 61-64 is the code for converting you id3 tags to utf8 if they are in some other charset. Many of my MP3s have greek characters so I used iso-8859-7 as the source encoding. You may have to edit this if you have id3 tags in other languages with non-latin characters. Or you can comment out (with #) these lines if you don’t need the conversion. Keep in mind that the webpage from shoutcast server defaults its encoding to a latin only charset. So to display your utf8 id3 tags you have to change the encoding manually in your browser. Nevertheless winamp displays utf8 id3 tags correctly so you listeners will be able to read the song title and artist without problems.
You can comment out (with #) lines 55 and 66 if you don’t want anything displayed on the command line while your music is streamed to the server.
You may see the error “fatal error: can’t update LAME-tag frame!” after each song ends. This is a bug in lame and you cannot disable it. I hope it will be fixed in a future version of lame.
Now create a playlist file that will be streamed to the server by doing this:
find / -name *.mp3 > myplaylist
That’s it! You are ready to stream your music by doing this:
./streamer.pl myplaylist
Happy streaming!