Live radio streaming with MPD, part 1: basic setup

I have been using MPD for a good while as my media player, in conjunction with gmpc as a graphical interface (since MPD is just a server). It's really cute, works reasonably well, and is one of the only software that can handle my huge music collection gracefully. The cool thing with the setup is that, because MPD is a network-transparent server, I can control (and listen to!) my music remotely.

Basic HTTP / Icecast streaming

For a while, I have also been streaming my music through Icecast so that I can basically listen to my music from anywhere there is an internet connection with sufficient bandwidth. This configuration is simple enough:

audio_output {
    type            "shout"
    name            "Currently listening to..."
    host            "localhost"
    port            "8000"
    mount           "/radio.ogg"
    password        "hackme"
    quality         "4.0"
    format          "44100:16:2"
    description     "My playlist of the day. High quality (4) OGG/Vorbis stream."
}

This will make a stream available at http://radio.example.com:8000/radio.ogg, provided Icecast is configured properly.

That setup is a bit more complicated than necessary, because it needs an icecast server to be installed (which is just apt-get install icecast on Debian, but still). So an alternative, simpler setup, but which may not scale as well to many listeners, is:

audio_output {
   type            "httpd"
   name            "My HTTP Stream"
   encoder         "vorbis"                # optional, vorbis or lame
   port            "8000"
   quality         "5.0"                   # do not define if bitrate is defined
   bitrate         "128"                   # do not define if quality is defined
   format          "44100:16:1"
}

I haven't played around too much with that plugin, so I don't know how well it works - I am using the Icecast plugin instead.

Always on radio

Another cool thing is that I have actually two MPD daemons running at the same time - one is my regular player, but the other is the "shuffle" player. The basic idea is that when the regular player stops, the shuffle starts, and vice versa, so there is always something playing on the stream. The shuffle, by default, doesn't play on the local sound card so that even though the radio stream is up, it doesn't blast random music through my living room speakers all day (and night!).

This trick is accomplished through a hook in the Icecast daemon:

    /radio.ogg
    /random.ogg

    /home/anarcat/bin/mpd-stop-random

    /home/anarcat/bin/mpd-start-random

    Currently listening to...
    My playlist of the day. High quality (5) OGG/Vorbis stream. If I'm not listening to anything, you'll be redirected to the random playlist.




    /random.ogg
    Random!
    Random songs from a 33 days playlist

The mpd-start-random script is rather idiotic:

#!/bin/sh

export MPD_HOST=hackme@radio.anarcat.ath.cx
export MPD_PORT=6601

mpc play

You can guess what the mpd-stop-random script does (hint: the opposite of play is pause).

So that's the old way of doing things. The one problem I found with this setup is when I want to setup another listener in the same house - the problem is that the Icecast stream has significant delay: a good 14 seconds here, with ogg123 as a client.

Here's the special configuration for the mpd-slave daemon that runs the random playlist:

# same as main player
music_directory         "/var/lib/mpd/music"
playlist_directory      "/var/lib/mpd/playlists"
# those need to be different
db_file                 "/var/lib/mpd-slave/tag_cache"
log_file                "/var/log/mpd/mpd-slave.log"
pid_file                "/var/run/mpd/slave.pid"
state_file         "/var/lib/mpd-slave/state"
# avoids having to update the database by hand all the time
auto_update    "yes"
# disabled by hand after daemon is started    
audio_output {
    type            "alsa"
    name            "Sound card"
}
# main icecast stream
audio_output {
    type            "shout"
    name            "Random!"
    host            "localhost"
    port            "8000"
    mount           "/random.ogg"
    password        "hackme"
    quality         "4.0"
    format          "44100:16:2"
    description     "Random songs from a 33 days playlist"
}
# another player for low bandwidth situations, disabled
audio_output {
    type            "shout"
    name            "Random! (lowfi)"
    host            "localhost"
    port            "8000"
    mount           "/random.ogg"
    password        "hackme"
    quality         "0.0"
    format          "44100:16:2"
    description     "Random songs from a 33 days playlist"
}

filesystem_charset "UTF-8"

user               "mpd"
default_permissions     "read"

port    "6601"
mixer_type                      "software"
volume_normalization            "yes"

The random playlist is done by simply adding the whole library to the playlist. MPD chokes a little the first time you do that, but it's surprisingly fast. I also went through the playlist to remove spoken words and other stuff I don't want to stumble upon, and after I shuffled the playlist.

Final notes

Otherwise, this is a fairly standard MPD setup, although there are some special configuration that vary from the upstream default:

# this needs to be commented out for the server to be accessible from everywhere
#bind_to_address                "localhost"

# setup a password for remote access
password                "hackme@read,add,control"

# make sure the mixer controls don't affect the local hardware mixer
mixer_type                      "software"

# we are beyond the ASCII world, but MPD doesn't know
filesystem_charset              "UTF-8"
id3v1_encoding                  "UTF-8"

This is the first part of a series of articles I intend to write about my MPD configuration, next ones detail the configuration of a dumb player and RTP streaming.