Obviously, if I'm going to keep up with the cool kids, my site here is going to have to display the exact song that I am listening to, in real time, with the complete information and cover art. No simple hand-updated list of "favorite CDs" or anything like that will do.
Now, my music playing device is the Squeezebox, which is fed by the Slimserver, which is open source and written in Perl, just like Blosxom. So this is certainly possible; the only question is how much work it is going to be.
Push or pull?
The first decision is going to be, do I want the web page to "pull" the song information off of the slimserver every time it is displayed, or is it better to have the slimserver "push" the updated information each time the song changes? Either network transaction would cost about the same, and they would be about equally easy to implement, so the question is, which will happen more times in a typical day: song transitions on the slimserver, or page views on my site?
Obviously, at the moment, there are far more song changes than site visitors, and it will probably stay that way for quite a while. However, there is a much firmer upper bound on the number of song transitions, because even when the Squeezeboxes are in continuous operation, there is only one update to push every three to five minutes. On the other hand, there could possibly be hundreds or thousands of hits to the web site in a day (I did not say likely, just possible). So I am going with the server-pushed updates for now. The idea is to get the slimserver to notify the blog somehow when the song changes.
Generate updates with Weblogger plugin for Slimserver.
Luckily, there is already a slimserver plugin by Danny Rego, called Weblogger, that can generate various kinds of notifications when the song changes. I installed this without any difficulty and configured my two Squeezeboxes to send HTTP POST updates to a URL on my web server. (NB: if the web server ran on the same machine as the slimserver, I would have been able to write the transitions to a file and read that file directly from the blog, which would have been easier.) I set the Weblogger plugin to "post as file" which is the only way to get the cover art sent as part of the update.
The bridge: a Perl CGI on the web server
Of course, Weblogger won't work until I put a CGI script at its
configured URL to catch the incoming updates and write them to the
disk. So I wrote a trivial Perl CGI script to do this, called
catch-weblogger. All it does is save the two files that Weblogger
POSTs (a bit of HTML called songinfo.txt, and a cover art
image named albumart.jpg) into the Blosxom plugins/state
directory. The active ingredients look like this:
my $STATE_DIR = '/home/mikey/www/blosxom/plugins/state';
my $q = new CGI;
print "Content-type: text/plain\n\n";
open OUT, ">$STATE_DIR/songinfo.txt" or die("can't open songinfo.txt: $!");
print OUT $q->param("songinfo.txt");
close OUT or warn("can't close songinfo.txt: $!");
open OUT, ">$STATE_DIR/albumart.jpg" or die("can't open albumart.jpg: $!");
print OUT $q->param("albumart.jpg");
close OUT or warn("can't close albumart.jpg: $!");
print "OK"; # weblogger looks for an "OK" response
exit(0);
The last piece: a Blosxom plugin to make the data available
Now that the files songinfo.txt and
albumart.jpg are being automatically created and updated
in the Blosxom plugins/state directory, all we need is
a
little Blosxom plugin to make them available to blog templates.
This is even simpler than the catch-weblogger part:
sub head {
# the songinfo.txt is already a bite-size piece of HTML, but we parse it
# ourselves so that we can display any format we want
my %song;
open SONG, "<$blosxom::plugin_state_dir/songinfo.txt";
while (<SONG>) {
m/<b>([\w ]+):<\/b> (.*?)<br>/ && ($song{$1} = $2);
m/<img src="(.*?)">/ && ($song{"url"} = $1);
}
close SONG;
our $now_playing;
$now_playing = "<div class=\"nowplaying\">\n";
$now_playing .= "<p align=\"center\"><img width=\"140px\" height=\"140px\" src=\"";
$now_playing .= $song{"url"};
$now_playing .= "\" alt=\"album cover art\" /></p>\n";
$now_playing .= "<p style=\"margin-left: 8px\">" . $song{"Song"} . "<br />";
$now_playing .= "from <i>" . $song{"Album"} . "</i> by " . $song{"Artist"} . "<br />";
$now_playing .= "in the " . $song{"Played on"} . "<br />";
$now_playing .= "at " . $song{"Last Updated"} . "</p>\n";
$now_playing .= "</div>\n";
return 1;
}
Now with this plugin running, all you have to do is put
$slimserver::now_playing in your Blosxom flavour
templates whereever you want, and you should get a nice fancy box such
as the one probably displayed somewhere on this page.
13 Nov 2005 23:56 PT - persistent link - trackback - 0 comments

4171622

