m9u music server
Why create yet another music server?
Personally, I was never happy having to poll the server for the current playing song in mpd. xmms2 let me get around that (with a custom client), but had a tendency to stop working when I upgraded and not give any useful diagnostics.
More pressing is the fact that m9u takes advantage of 9p for inter-process communication, rather than making up its own protocol. 9p has a lot of personal interest for me - it offers a very unix approach, a way to keep each component of the system simple. So, the obvious way to learn about it was to write a 9p file server.
Wait, file server? I thought you said it was a music server!
Yes. It can be a confusing idea when you think of files as things that get stored on disk, and your operating system only offers crippled primitives for manipulating namespaces. However, the idea of a file server that offers files which aren't on disk is nothing new - the linux kernel does it with /proc and /sys, as does the httpfs FUSE filesystem.
Long before FUSE, the Plan 9 folks were playing with these ideas, and ended up implementing file servers for just about everything. Even hardware drivers export a filesystem in plan 9! For example, an ethernet driver exports files you can read() from/write() to to recieve/transmit packets. The TCP stack exports another filesystem, and these are generally mounted in /net, along with a name resolution service.
The file server approach has several nice properties:
- Kernel simplicity. 9p kills syscalls - when all network operations are done through /net, you only need open()/read()/write()/close() and the correct incantation to open a network connection. No need for tons of socket related syscalls. It kills ioctls aswell, because when your driver exports a filesystem it's easy to add a seperate file for that out-of-band data. Also note that the tcp stack need not be implemented in the kernel.
- If you've been clicking links, you probably noticed already that 9p is network transparent. This means you can import /net from another machine (eg, your gateway) and use it as if it was local. Good bye, NAT. Good bye, port forwarding. Of course, this also works for graphics/sound and other hardware, without needing a special protocol for each one (I'm looking at you, X11/NAS).
Uhh, that's great and all, but I'm actually here to read about m9u.
Right, sorry about that. Like I said, 9p is close to my heart.
The name m9u is a [not very imaginative] play on m3u, the playlist format from ages past (or maybe it's still being used, I haven't created a playlist file in years). In reality, m9u is not a music server but a playlist server. In fact, it is so dead simple/stupid that it doesn't even know it is storing a list of songs! m9u just stores a list of strings, and when it comes time to play the song it passes the string through to the "m9uplay" script, which looks at the string and decides what to do with it (eg mpg123 for *.mp3, ogg123 for *.ogg).
This approach has some disadvantages, of course:
- No intra-song operations (eg forward/back 5 seconds). Well, you could probably pull it off with the right decoder, but you wouldn't get any assistance from m9u (which is quite intentional, m9u's focus is squarely on inter-song operation, hence the builtin queue).
- No crossfading/gapless playback, since m9u doesn't actually know about the audio stream.
On the plus side:
- Easily supports obscure formats - all you need is a dumb decoder.
- Can be used for non-audio applications. Becomes a slideshow when populated with a list of images, and I can think of some interesting applications for URLs (if only I had a blocking "open url in browser" command I could add youtube links to the queue and have them automatically load up when the current song finishes).