Saturday, May 2, 2009

RhythmToWeb

Attention: RhythmToWeb has moved to Google Code

RhythmToWeb is a plugin for Rhythmbox (a music player for the GNOME desktop). It sends information about the currently playing song over the web. The information is sent as a series of GET variables: artist, title, album, genre, year, duration (seconds). The configuration dialog:
  • URL: This is the URL that is going to be called.
  • Interval: This is NOT the interval at which the URL will be called. This is the interval at which the plugin checks if the song changed (this has multiple advantages). The reason for polling at an interval is that this way you don't risk the server to be flooded if you change songs really quickly.
Installation
  1. Download: RhythmToWeb.tar.gz
  2. Extract the RhythmToWeb directory to ~/.gnome2/rhythmbox/plugins/
  3. (Re)start Rhythmbox, go to Edit → Plugins, find RhythmToWeb, enable it and configure it
If you have any problems with it (won't activate, crashes Rhythmbox, something doesn't work), run Rhythmbox like this: $ rhythmbox -D RhythmToWeb and send me the output, either as a comment on this post or on my email (it's in the plugin properties). As you may have guessed, I'm using this plugin for the widget in the sidebar of this blog (the "Now Playing" one). Thus, I will show the PHP script that is called when I change the song which creates a simple Javascript file: <?php $G = $_GET; function prep($var) { // Prepare a value to be included in a Javascript string $var = htmlentities($var, ENT_COMPAT, 'utf-8'); if (!get_magic_quotes_gpc()) $var = addslashes($var); return $var; } function test($var) { if ( strlen($var) && mb_strtolower($var) != 'unknown' && $var != '0' ) { return true; } return false; } $s = 's_nowplaying = "'; if (test($G['title'])) { $s .= '<b>Song:</b> ' . prep($G['title']) . '<br />'; } if (test($G['artist'])) { $s .= '<b>By:</b> ' . prep($G['artist']) . '<br />'; } if (test($G['album'])) { $s .= '<b>From:</b> ' . prep($G['album']) . '<br />'; } if (test($G['genre'])) { $s .= '<b>Genre:</b> ' . prep($G['genre']) . '<br />'; } if (test($G['year'])) { $s .= '<b>Year:</b> ' . prep($G['year']) . '<br />'; } if (test($G['duration'])) { $min = floor($G['duration'] / 60); $sec = $G['duration'] % 60; if ($sec < 10) $sec = '0' . $sec; $s .= '<b>Length:</b> ' . $min . ':' . $sec; } if (empty($G)) { $s .= 'Not playing anything.'; } $s .= '";'; $s .= <<<EOS if (document.getElementById && document.getElementById('nowplaying_info')) document.getElementById('nowplaying_info').innerHTML = s_nowplaying; else document.write(s_nowplaying); EOS; $fp = fopen('nowplaying.js', 'w'); fwrite($fp, $s); fclose($fp); ?> Then, in my blog I have a HTML widget with the following content: <span id="nowplaying_info">Loading...</span> <script src="http://znupi.ath.cx/felix/nowplaying/nowplaying.js" type="text/javascript"></script> And there you have it :). This is just an example, you could make a script that generates an image on which it writes that information. This way, you could include that image in your signature on forums or emails. Don't hesitate to ask questions either here or on my email address if you have them.

13 comments:

  1. Hey, this seems a really awesome idea, but it doesnt work for me, and I'm wondering why. I installed the plugin, went to my site and made a nowplaying.js file, copy and pasted the first section of code, then edited my homepage, with the second bit of code, replacing http://znupi.ath.cx/felix/nowplaying/nowplaying.js with just "nowplaying.js" and then i set the URL in the plugin with http://nickisawesome.izfree.com/nowplaying.js

    What am I doing wrong? Am i supposed to actually have my own server, or should that not matter? Thanks in advance

    ReplyDelete
  2. You're not supposed to have your own server, but your host has to allow running PHP scripts (and your site seems to have PHP enabled). You see, the way this works is that the plugin sends the information to a PHP script that writes a javascript file (nowplaying.js) to the hard disk. Then, the browser requests that file which is constantly updated. So you basically need two files:
    1) store.php - this is the file called by the plugin. It contains the first big bit of code in the post.
    2) nowplaying.js - this is empty because it will be filled in by store.php script when it will be called. It is probably necessarry to create it because it needs to have permissions set in such a way that PHP can write to it (actually, it's the server process that writes to it, but whatever).

    ReplyDelete
  3. Mmk, thanks, I've now done that. What permissions should i set the files for? And, if I visit http://nickisawesome.izfree.com/nowplaying.js , should the song thats playing appear?

    ReplyDelete
  4. The nowplaying.js file should be world-writable, so that means something like "chmod +w nowplaying.js". The currently playing song will only appear in nowplaying.js after the plugin has made a request. Again, you have to set the plugin URL to the php file, so something like http://nickisawesome.izfree.com/store.php

    ReplyDelete
  5. Thanks a million, its working now :D

    ReplyDelete
  6. Great! Lets write Ruby on Rails plugin for this :)

    ReplyDelete
  7. Why would we? There already is this one and on top of that, writing a Ruby plugin would mean first writing a Ruby plugin loader for Rhythmbox (in C).

    ReplyDelete
  8. have question about example script png.php. what is that RTWUtils.class.php?

    ReplyDelete
  9. Sorry, I forgot to add it to the project. It can be found in the source under examples/php/RTWUtils.class.php or in the examples-0.1.1.tar.gz download.

    ReplyDelete
  10. Great idea but I am having a little trouble getting it going.

    1. I copied the code in the code box above,saved as store.php, and uploaded to my web site (www.eclectic-saddlebag.com). I also uploaded an empty file named nowplaying.js with write permissions.

    2. I added a html widget with the code above.

    3. Configured the RhythmtoWeb plugin with the URL: http://www.eclectic-saddlebag.com/store.php, but all I get is "Loading ..." on the web site.

    What am I missing?

    Using Rhythmbox 12.8
    Ubuntu Karmic 9.10

    ReplyDelete
  11. been using this for a while with store.php, wanted to try out png.php for kicks. It creates the png image, but it's a tiny one pixel image... any idea why it would do this?

    ReplyDelete
  12. Hey, I am trying to get this to work on Ubuntu 11.10. I have copied the plugin files to both /usr/lib/rhythmbox/plugins and ~/.gnome2/rhythmbox/plugins. It still doesn't show up in the plugins dialog, so I can't configure it. Here's the output of Rhythmbox -D RhythmToWeb:

    Rhythmbox-DEBUG: Received SaveYourself(SmSaveLocal, !Shutdown, SmInteractStyleNone, !Fast) in state idle
    (rhythmbox:1930): Rhythmbox-DEBUG: Setting initial properties
    (rhythmbox:1930): Rhythmbox-DEBUG: Sending SaveYourselfDone(True) for initial SaveYourself
    (rhythmbox:1930): Rhythmbox-DEBUG: Received SaveComplete message in state save-yourself-done


    Any ideas?

    Thanks.

    ReplyDelete