home :: hacks :: slim

RSS 0.91 feeds Subscribe and save over 75% off newsstand price!

car - 9
games - 2
hacks - 21
  flac - 4
  photo - 5
  slim - 3
journal - 153
misc - 5
news - 9
pomona - 2
rants - 6

For the biographers:

2005 - 2006 - 2007 - 2008 - 2009

Now playing

Décollage (Cristobal Paz & Leo di Giusto remix)
from Remixed by Bajofondo
at Monday, December 14, 2009 12:51 AM

How this works

Hot Live Webcam

Yes, really.

Recently from Google

from (null), searching for 56 foot ketch

from Mountain View CA, searching for mikey dickerson

How this works

Contact me

mikey@singingtree.com
4171622
mdickers47
mike.dickerson@pomona.edu
pomonamikey
wii number7808 7239 7724 0213
blackberry pin204db8e4

On Notice

  • The sun
  • Librarians
  • Blue
  • Purple
  • David Gray
  • Whirlpool
  • Taco Bell

As seen on The Colbert Report.

This site does not represent my employer.

May look horrible in Internet Explorer.

blosxom logo   Creative Commons License

gotta
knock
a
little
harder

obstrepero.us banner
obstrepero.us mistakes you can learn from

And my old slimserver hack is new again

filed under: /hacks/slim

see also: cover art in FLAC tags

see also: now playing

After my desktop machine went OOM again today and had to be rebooted, I figured I would finally install the current version of the slimserver, which is the 100M of perl bloatware that drives my various squeezebox players. I hate to upgrade this, because I have to port forward my weird hacks each time.

(Aside: Another reason I haven't touched the slimserver in a year is that the current versions depend on a local MySQL server for some idiotic reason. BARF. No. You do not need a SQL engine to drive what is, in my case, about 1200 CDs, which weighs in at 500K of data. And even if you think you do, you never heard of sqlite? You had to bundle mysql, the rip-roaringest piece of half-assed crap that anyone ever mistook for a database? BARF.)

On the other hand, the new slimserver is a whole lot faster than the old one. Moving on.

My only local modification teaches the slimserver to understand the wacky FLAC coverart blocks which are an extension I made up. My old patch against 6.2.2 doesn't apply anymore, so I had to sort it out again, which fortunately wasn't too hard. Yeah, I'm just going to paste the patch right here, because I am lazy. Hope you like reading perl diffs with your morning coffee.

diff -rcN SlimServer_v6.5.4/Slim/Formats/FLAC.pm
SlimServer_v6.5.4-hacked/Slim/Formats/FLAC.pm
*** SlimServer_v6.5.4/Slim/Formats/FLAC.pm      2007-05-24
18:02:36.000000000 -0700
--- SlimServer_v6.5.4-hacked/Slim/Formats/FLAC.pm       2007-10-06--
--00:07:41.000000000 -0700
***************
*** 65,70 ****
--- 65,75 ----
  # as PIC1 + artwork. So the raw data is +4 from the beginning.
  my $ESCIENT_ARTWORK = 1163084622;

+ # flac-image also stores cover art in a FLAC application block, but with
+ # a different application id and a 72-byte header--same thing, only
+ # different.
+ my $FLAC_IMAGE = 0x696d6167; # == "imag" in ASCII
+
  =head2 getTag( $filename )

  Extract and return audio information & any embedded metadata found.
***************
*** 293,300 ****
                if (substr($artwork, 0, 4, '') eq 'PIC1') {
                        $tags->{'ARTWORK'} = $artwork;
                }
!       }

        return $tags;
  }
--- 298,318 ----
                if (substr($artwork, 0, 4, '') eq 'PIC1') {
                        $tags->{'ARTWORK'} = $artwork;
                }
!
!       } elsif ($flac->application($FLAC_IMAGE)) {
!
!               # we don't bother to look at the mime-type field except
!               # to check that it starts with 'image', because Info.pm is
!               # going to apply magic to try to guess the mime-type anyway.
!
!               my $artwork = $flac->application($FLAC_IMAGE);
!
!               if (substr($artwork, 4, 5) eq 'image') {
!                       $tags->{'ARTWORK'} = substr($artwork, 72);
!               }

+         }
+
        return $tags;
  }

diff -rcN SlimServer_v6.5.4/Slim/Music/Info.pm
SlimServer_v6.5.4-hacked/Slim/Music/Info.pm
*** SlimServer_v6.5.4/Slim/Music/Info.pm        2007-05-24
18:02:33.000000000 -0700
--- SlimServer_v6.5.4-hacked/Slim/Music/Info.pm 2007-10-06--
--00:22:13.000000000 -0700
***************
*** 944,950 ****
  sub isFLAC {
        my $pathOrObj = shift;

!       return isType($pathOrObj, 'flc', @_);
  }

  sub isAIFF {
--- 944,952 ----
  sub isFLAC {
        my $pathOrObj = shift;

!       return 1 if isType($pathOrObj, 'flc', @_);
!       return 1 if isType($pathOrObj, 'fec', @_);
!       return 0;
  }

  sub isAIFF {

That's all I need to do to the slimserver. I had to update the Weblogger plugin as well, and fyi, the current version 0.99c has a bug that stops multipart POST from working. You need to change this one line, or you will get nothing but "Can't coerce array to hash" errors out of it:

--- Plugin.pm~  2006-10-07 03:44:42.000000000 -0700
+++ Plugin.pm   2007-10-06 02:09:48.000000000 -0700
@@ -955,7 +955,7 @@
        my($client,$url,$paramlist,$timeout)=@_;

        # Prepare our HTTP request...
-       my $request=POST $url, Content_Type => 'form-data', Content => [%$paramlist];
+        my $request=POST $url, Content_Type => 'form-data', Content => $paramlist;

        # Create our UserAgent, and send the file/params...
        # (submit our faked "form" data)

I sent this last bit to Dan the weblogger man, so if it really is a bug, maybe it will get fixed.

06 Oct 2007 03:00 PT - persistent link - trackback - 0 comments

No, this is why Al Gore invented the Internets.

filed under: /hacks/slim

This isn't really a hack in the sense that I thought of something clever to do, but it amuses me nonetheless. One of my many squeezeboxes is in the bedroom, and it has its own remote control of course, but I can't read the screen from the bed without putting my glasses on. Obviously I could move the squeezebox, or the bed, or I could put my glasses on.

But why do that when there is a less obvious solution: I can forward a port so that the server that controls the squeezeboxes is reachable from the Internet. Then I can use the Blackberry which is always close by. So I can now change the volume or play a CD by sending commands up through T-Mobile, across the internets, to my ISP, down the DSL, through the NAT router, to the slimserver machine in the closet, across the ethernet to the squeezebox which is eight feet away. This works better than you would expect; the total round trip from me pressing a button to hearing its effect is about half a second.

Even more important, I now carry this power in my pants wherever I go, so if I suddenly need to play Cowboy Bebop in my living room while I am in the airport in Chicago, I can do so. Booya!

22 Jan 2007 01:04 PT - persistent link - trackback - 0 comments

Displaying "now playing" with the slimserver and Blosxom

filed under: /hacks/slim

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

Copyright © 2005-06 Michael A. Dickerson