An AJAX Erlang Jukebox

This page is a mirrored copy of an article originally posted on the LShift blog; see the archive index here.

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, mpg123, ogg123 (from vorbis-tools), and some MP3 or OGG files to listen to.

I’ve made a start on a bit of 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 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:

[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.]


On 7 November, 2006 at 4:27 pm, Andrew Barilla wrote:

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?

On 7 November, 2006 at 5:22 pm, tonyg wrote:

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.

On 7 November, 2006 at 11:16 pm, Tobbe wrote:

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!!

On 8 November, 2006 at 11:46 am, tonyg wrote:

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.

On 8 November, 2006 at 12:15 pm, tonyg wrote:

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

On 9 November, 2006 at 8:42 pm, Tobbe wrote:

Ok, I got past that problem. But I guess I have a to old Firefox version ( 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.

On 9 November, 2006 at 9:34 pm, Tobbe wrote:

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.

On 10 November, 2006 at 12:51 pm, tonyg wrote:

Hey, great that you have it running!

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

On 10 November, 2006 at 5:04 pm, Tobbe wrote:

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 ?

On 10 November, 2006 at 7:16 pm, Samir wrote:

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

On 10 November, 2006 at 8:27 pm, tonyg wrote:

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.

On 10 November, 2006 at 8:31 pm, tonyg wrote:

@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.

On 11 November, 2006 at 9:08 am, Henry wrote:

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

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

On 11 November, 2006 at 9:57 am, Tobbe wrote:

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.

# erl -pa `pwd`/erlang_jukebox
1> l(spider).
2>  code:priv_dir(erlang_jukebox).

On 11 November, 2006 at 10:02 am, Tobbe wrote:

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)

On 11 November, 2006 at 2:57 pm, tonyg wrote:

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.

On 14 November, 2006 at 10:42 am, Paul Crowley wrote:

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.