Implementing “Bob’s Listening To”
I put up on my web page what I am listening to at the moment. This article tells how I do that.
I listen to music through the Squeezebox, a fabulous device made by SlimDevices that plays MP3s you have on your computer through your stereo system. “SlimServer” is the server that runs on whatever computer you have handy, that you talk to through a web interface, and feeds the music wirelessly to the Squeezebox. SlimServer can also report its current status, including the current song being played, in XML format, which turns out to be useful, via the URL:
http://slimserver:9000/xml/status.html
Using wget or lwp-request, I grab this data and then process it through XSLT to get a simple string of the form SONG by ARTIST from ALBUM:
<?xml version="1.0"?> <!-- slim-putsong.xsl: transform slimserver XML status output into SONG by ARTIST from ALBUM --> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sl="http://www.slimdevices.com/slimserver/xml" version="1.0" > <xsl:output method="html" omit-xml-declaration="yes"/> <xsl:template match="/"> <xsl:for-each select="sl:status/sl:player_status/sl:current_song/sl:song"> <b><xsl:value-of select="sl:title"/></b> by <b><xsl:value-of select="sl:artist"/></b> from <b><xsl:value-of select="sl:album"/></b> </xsl:for-each> </xsl:template> </xsl:transform>
With Slimserver 6.x, the XML format was changed. 🙁 The “sl:song” portion of the for-each statement above needs to be removed.
You can apply this XSLT through a tool such as xsltproc.
I wrote a little shell script which grabs the URL, transforms it, and FTPs it to my server:
#!/bin/sh # shell script to create HTML of current song playing on Squeezebox, # and ftp'ing a file containing that information to bob's blog. wget --quiet --output-document=- http://localhost:9000/xml/status.xml | \ xsltproc --novalid slim-putsong.xsl - > slim-putsong.html ftp -i -n my.host.name <<EOF user user password cd /some/directory/ put slim-putsong.html bye EOF
To prevent FTP’ing an unchanged file, precede the ftp line with
diff slim-putsong.html prev-slim-putsong.html > /dev/null ||
Run this script from cron however often you want.
All that remains is to include the HTML file into the web page you want the info to appear on, with something like
<? include 'slim-putsong.html'; ?>
May 4th, 2004 at 07:17
Hold it…. You r going to fast for me… 😉
I am using an windows machine and am not a wizard in programming… I\’ll get there in the end… How can I achieve this on my machine… Will/can you help me?
p.s. i have XSLT/XML PHP APACHE installed and working…
May 6th, 2004 at 10:21
On Windows, I\’d recommend doing this under Cygwin. That will give you all the pieces you need, including wget (to retrieve the information from the SlimServer), xslt (to transform it), and cron (to run the script every so often).
May 8th, 2004 at 00:30
Well i have my server running at home and have the info available. So i don\’t need to use wget. XSLT i have got working. I can use scheduling in windows to run a batch programme ever so often. My problem now is to get the xsltproc to work with the XML programme you have written. Where do you put the data the XML proc needs? I can\’t find any location information of the input and export file.
June 4th, 2004 at 04:34
A quick and dirty approach would be to read the XML from a php page on your web server, assuming you can get access to the slimserver http server from your normal web server – you may need to poke a hole through a firewall.
Something like this would work in that case (change localhost to the name or ip address of your slimserver or external nat router interface etc., and since you can\’t use angle brackets here replace the strings LEFTBRACKET and RIGHTBRACKET with left and right angle brackets respectively):
LEFTBRACKET?
$xml = fread(fopen(\”http://localhost:9000/xml/status.xml\”,r),9999);
if (eregi(\”LEFTBRACKETplaymodeRIGHTBRACKETplaying\”,$xml)) {
if (preg_match(\”/LEFTBRACKETtitleRIGHTBRACKET([^LEFTBRACKET]*)LEFTBRACKET\\/titleRIGHTBRACKET.*?LEFTBRACKETartistRIGHTBRACKET(.*?)LEFTBRACKET\\/artistRIGHTBRACKET.*?LEFTBRACKETalbumRIGHTBRACKET(.*?)LEFTBRACKET\\/albumRIGHTBRACKET/s\”, $xml, $m)) {
$track = $m[1] . \” by \” . $m[2] . \” (Album: \” . $m[3] . \”)\”;
}
echo \”I am listening to: $track\”;
}
?RIGHTBRACKET
November 1st, 2004 at 11:42
Here\’s a modified version of the bash script, which uses ssh instead of ftp:
#!/bin/sh
# shell script to create HTML of current song playing on Squeezebox,
# originally from http://bob.myers.name/blog/article/249
# modified by Joel Aufrecht Oct 2004 to use scp
# check for input
if [[ -z \”$1\” || -z \”$2\” ]]
then
echo \”Usage: putsong.sh target-destination identity-file
Example: To upload a song every 3 minutes, using a dedicated ssh
account called \\\”upload\\\”, put this in your crontab:
*/3 * * * * sh /etc/slimserver/putsong.sh upload@foo.bar:/tmp/song.html /home/me/.ssh/upload\”
exit
fi
STATUS=/tmp/status.xml
STATUS_HTML=/tmp/song.html
wget—quiet—output-document=$STATUS http://localhost:9000/xml/status.xml
# if song is not playing, do nothing
if [ \”`grep -c \’playing\’ $STATUS`\” -eq \”1\” ]
then
xsltproc -o $STATUS_HTML—novalid /etc/slimserver/slim-putsong.xsl $STATUS
echo \”at `date`\” >> $STATUS_HTML
scp -i $2 $STATUS_HTML $1
fi
December 1st, 2004 at 15:25
Here\’s a version of slim-putsong.xsl which does not output the \”by\” or \”from\” text if artist or album is missing:
0\”>
0\”>
by
0\”>
from
March 18th, 2005 at 07:54
Thanks Bob!
I’ve implemented this myself, in about 10 minutes (including installing libxslt). My scenarios easier than yours, as the web server and slimserver are the same, so mine just creates the file in the correct location. Great instructions though!
H
October 1st, 2006 at 15:44
For multiple squeezeboxes, don’t forget to query the right one!
Modify wget source as http://localhost:9000/xml/status.xml?player=name_of_player