technology from back to front

An AJAX Erlang Jukebox

Erlang Jukebox Screenshot

Sometime around the beginning of July I rewrote our internal jukebox in Erlang. It’s taken me four months to get a round tuit, but new stock has just arrived: here’s the code for our AJAX jukebox
web-application, as a tarball. (There’s also a mercurial repository:
hg clone http://hg.opensource.lshift.net/erlang-jukebox/.)
Click on the image for a screenshot.

To run it, you will need Erlang, Yaws (the Erlang webserver), a modern browser, href=”http://www.mpg123.de/”>mpg123, ogg123 (from
vorbis-tools)
, and some MP3 or OGG files to listen to.

I’ve made a start on a bit of href=”http://hg.opensource.lshift.net/erlang-jukebox/raw-file/default/doc/index.html”>documentation and design rationale. Here are a few highlights for the curious:

* You point the jukebox at one or more root URLs, which it then spiders, collecting URLs for MP3 and OGG files, which it puts into a simple flat-file database. Just expose, say, your iTunes folder via Apache, point the Jukebox at it, and you’re away.

* It relies on mpg123 and ogg123′s support for playing HTTP-streamed MP3 and OGG files, respectively, rather than retrieving or playing the media itself.

* The user interface is completely written in HTML+Javascript, using prototype for its event binding and href=”http://en.wikipedia.org/wiki/XMLHttpRequest”>XMLHttpRequest support.

* The server side of the application communicates with the user interface solely via JSON-RPC.

* Erlang made a great platform for the server side of the application. Its support for clean, simple concurrency let me design the program in a very natural way.

As part of the development of the program, I built a few stand-alone modules that others might be interested in reusing:

* the href=”http://hg.opensource.lshift.net/erlang-jukebox/file/default/priv/execdaemon/”>execdaemon
and its associated Erlang href=”http://hg.opensource.lshift.net/erlang-jukebox/file/default/src/execdaemon.erl”>controller
module is a filthy hack I threw together to get better than the built-in support for POSIX process control and signalling from Erlang.

* href=”http://hg.opensource.lshift.net/erlang-jukebox/file/default/priv/server_root/htdocs/jsonrpc.js”>jsonrpc.js
is a tiny, simple layer atop href=”http://hg.opensource.lshift.net/erlang-jukebox/file/default/priv/server_root/htdocs/json.js”>json.js
and prototype that supports basic parsing of href=”http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book9″>Simple Method Description (SMD) files, generating Javascript client proxy objects for each JSON-RPC service described by an SMD.

[Update: fixed an issue with json.js, tweaked the use of screen real-estate, and now seems to work with Safari, IE6, and Opera. I've changed the tarball link above to point to the new version.]

[Update: fixed a couple of links that had broken over time as the darcs repository evolved.]

[Update: moved from darcs to mercurial, and altered the links to reflect the change.]

by
tonyg
on
06/11/06
  1. Andrew Barilla
    on 07/11/06 at 4:27 pm

    I looked into Erlang for rewriting my jukebox program which is currently in Java. However, I couldn’t find any modules to read tag information which is what my jukebox uses instead of file names.

    In your travels, did you run across any such modules?

  2. Sorry, Andrew, I didn’t; I’ve been ignoring the whole issue of file tagging as “too difficult”. We’ve been finding that a stupid simple substring search on the whole file URL is good enough for us – “worse is better” strikes again?

    We’re mitigating the unstructured search approach a bit by exploiting the structure found in the URL itself, clustering result URLs together by their directory part and sorting results lexicographically. We end up with a search result list that is often both clustered by album and in track order (if tracks have “01…” etc. prepended to their filenames) within each album.

  3. Nice! In fact very nice!
    However, on my old laptop I didn’t have Java installed, which seem to be needed by the json.js code, so I couldn’t try it out. Apart from that, it is the first real Erlang/Ajax app. I’ve seen so far. Good work!!

  4. Doh! That was a remnant from an earlier hacking session – I’d taken json.js from this earlier project. I’m surprised it works at all! I’ll fix that now and update the tarball.

  5. As a pleasant side-effect, removing the Javaisms from json.js seems to have let the code run on Safari and IE6…

  6. Ok, I got past that problem. But I guess I have a to old Firefox version (1.5.0.7). Since it complains about line 168:

    color: red ! important;

    Perhaps I sould try and install Firefox 2.0 (if I can figure out how that is done in Ubuntu…).

    Another, thing: perhaps you should make use of some of the new nice Autoconf macros for Erlang to locate Yaws (they were presented at the EUC today btw :-) As it is now, I have to change the ref. to /opt every time.

  7. Update: I had to fix a small bug in Yaws. When having several servers listening to the same port, then the ‘start_mod’ module was not called properly. It is now fixed in Yaws CVS.

  8. Hey, great that you have it running!

    The CSS problem is odd – how does it manifest itself? I’m using 1.5.0.7 here and it seems to work okay. Perhaps you have a developer plugin I’ve not tried?

  9. Well, actually; I can’t get it to work :-)
    Follow my link and see if it works for you.
    It could be my server, I’ll have to check more closely.
    Btw: how do I start playing a tune, just by enque it, or ?

  10. Have you looked at jinzora? How is your Jukebox different than Jinzora? It has same functionality as yours and then some. Thanks.

  11. There’s really no comparison. This is a new, small, simple program, weighing in at 1,400 lines of Erlang and Javascript; Jinzora is a mature, large, complex program, with over 100,000 (!) lines of PHP code. Both are open-source, and both have something to do with playing MP3s in some kind of jukebox-like configuration, but that’s about where the similarities end, it seems to me.

  12. @Tobbe: yes, just enqueueing it ought to do the trick. It’s very strange, the installation you have: it seems that some of the features are working, while others aren’t. For instance, typing in a chat message causes the history list to update, but the timer-based history (and playlist) refresh seems to be broken. Weird.

  13. Another cool AJAX jukebox is at http://www.streampad.com

    Seems a lot more advanced than this although certainly not as tiny!

  14. Update: Found that I need to start Yaws in the same directory as the code. So now I don’t get any errors in the log at least. Still doesn’t work though.

    It could be a good idea to structure the code under src,ebin,priv directories. The execdaemon binary then goes into the priv directory. You can then locate it with code:priv_dir/1.
    Example:

    # erl -pa `pwd`/erlang_jukebox
    1> l(spider).
    {module,spider}
    2>  code:priv_dir(erlang_jukebox).
    "/home/www/site/erlang_jukebox/priv"
    
  15. Also: Where do I find this ‘hmix’ program that volume.erl wants to use ? (I’m running Gentoo btw and it doesn’t seem to exist among Gentoo’s packages)

  16. Tobbe, thanks for the tip. I’m still getting to grips with the Erlang way of working – anyway, I’ve just found the guide to application directory structure, and I’ll take your advice regarding priv. I’ll post again when I’ve committed the changes to darcs.

    Oh – there’s a copy of the hmix source code in the util/ subdirectory.

  17. A friend pointed out Music Playing Daemon to me; it’s the first thing I’ve found that makes it clear that it has similar goals to our jukebox software, ie a single playlist that’s under the control of multiple users.

 
 


two × = 6

2000-14 LShift Ltd, 1st Floor, Hoxton Point, 6 Rufus Street, London, N1 6PE, UK+44 (0)20 7729 7060   Contact us