stmllr.net

Streaming audio with MPD and Icecast2 on Raspberry Pi

by on stmllr.net

The main purpose of my Raspberry Pi is to act as a central music box. This task can easily be solved with MPD and Icecast2. Read on and get it working within 15 minutes.

Prerequisites

I strongly suggest to use the Raspbian distribution as operating system. It has built-in hardfloat support for the FPU on your Raspberry Pi. This truly boosts performance for audio encodings. Without hardfloat support, you'll probably end up with 100% CPU usage. The result would be playback hickups and no fun at all.

Icecast2 is a free audio streaming server which supporting the shoutcast protocol. MPD is a music player daemon which serves as a backend for playing audio. MPD uses the shoutcast library to stream to icecast2. Fortunately, Raspbian MPD is compiled with libshout and also mp3 support by default so we don't have to build any custom packages. MPC is a command line client to control MPD, for example to manage playlists or to start/stop playing a song.

Package installation

It's straighforward:

$ sudo aptitude install mpc mpd icecast2
The following NEW packages will be installed:
  icecast2 libao-common libao4 libaudiofile1 libavahi-glib1 libavcodec53 libavformat53
  libavutil51 libcurl3-gnutls libdirac-encoder0 libfaad2 libgsm1 libjack-jackd2-0
  libmms0 libmp3lame0 libmpcdec6 libmpdclient2 libschroedinger-1.0-0 libshout3
  libspeex1 libtheora0 libva1 libvpx1 libwavpack1 libx264-123 libxvidcore4 mpc mpd

The package manager will ask you to configure Icecast2. You should do so and set a hostname and passwords for source, relay and administration. Needless to say to use strong passwords. The source password will be needed in the MPD configuration. (I used ICECAST_SOURCE_PASSWORD in the example)

The autoconfiguration of the MPD package could report some warnings about ipv6 and tag_cache:

Setting up mpd (0.16.7-2) ...
[....] Starting Music Player Daemon: mpd
listen: bind to '[::1]:6600' failed: Failed to create socket: Address family not supported
by protocol (continuing anyway, because binding to '127.0.0.1:6600' succeeded)
Failed to load database: Failed to open database file "/var/lib/mpd/tag_cache":
No such file or directory

The tag_cache issue doesn't harm. The file will be added anyway and the warning will not appear again. This will hopefully be fixed by the package maintainer. The other issue relates to missing ipv6 network support. You probably need to load the ipv6 kernel module to get rid of this warning:

$ sudo modprobe ipv6

Configuring MPD

A configuration set for the shout output needs to be added to /etc/mpd.conf

audio_output {
  type            "shout"
  name            "RasPi MPD Stream"
  description     "MPD stream on Raspberry Pi"
  host            "localhost"
  port            "8000"
  mount           "/mpd"
  password        "ICECAST_SOURCE_PASSWORD"
  bitrate         "128"
  format          "44100:16:2"
  encoding        "mp3"
}

This will stream to the icecast2 server on localhost:8000, using /mpd as mount point. The stream will be encoded on the fly to 16bit, 2 channel stereo mp3 at 128k bitrate.

If you ran into the ipv6 warning before, you could alternatively solve that by setting an ipv4-only address:

bind_to_address "127.0.0.1"

Now restart MPD to reload the configuration:

$ sudo /etc/init.d/mpd restart

Check if things are up an running

A new output should have been added and enabled:

$ mpc outputs 
Output 1 (My ALSA Device) is enabled
Output 2 (RasPi MPD Stream) is enabled

If the stream output is disabled, you can enable it using:

$ mpc enable 2

Icecast2 should be running out of the box without any additional configuration.

Check if both icecast2 and mpd are listening on tcp:

$ sudo netstat -ltpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      1299/icecast2
tcp        0      0 127.0.0.1:6600          0.0.0.0:*               LISTEN      1734/mpd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1531/sshd
tcp6       0      0 ::1:6600                :::*                    LISTEN      1734/mpd

Start streaming

First you need to add a minimal playlist with a song. If neccessary, fix permissions for the music and playlist directories and check if your user (pi) is member of the audio group:

$ groups
pi adm dialout cdrom sudo audio video plugdev games users input

If audio does not appear in this list, add it:

$ sudo usermod -a pi -G audio

Fix permissions:

$ sudo chmod g+w /var/lib/mpd/music/ /var/lib/mpd/playlists/
$ sudo chgrp audio /var/lib/mpd/music/ /var/lib/mpd/playlists/

Now download a demo song:

$ cd /var/lib/mpd/music/
$ wget http://www.jonobacon.org/files/freesoftwaresong/jonobacon-freesoftwaresong2.ogg

Add the song to the actual playlist:

$ mpc update
$ mpc ls | mpc add
$ mpc playlist
Jono Bacon - Free Software Song

Enable repeat mode in the test phase to prevent MPD from stoping:

$ mpc repeat on
volume: 80%   repeat: on    random: off   single: off   consume: off

Now start to play the song:

$ mpc play
Jono Bacon - Free Software Song 2
[playing] #1/1   0:00/3:18 (0%)
volume: 80%   repeat: on    random: off   single: off   consume: off

If your speakers are connected, you should hear the song playing. Credits for the Free Software Song go to Richard Stallmann and Jono Bacon ;-)

Then open your browser and point it to your raspberry host on port 8000: !http://your.raspberry.hostname:8000/
You should get the icecast status page with your stream at the mount point /mpd.

If you navigate to http://your.raspberry.hostname:8000/mpd.m3u the browser should ask you to open the stream with your favorite music player. Have a look at the codec of the stream and notice that it's mp3 at 128k, although the original song is ogg at 160k. On-the-fly encoding is obviously working.

Check your CPU usage using the top or htop command: it should be about 80%.

Which MPC clients to use?

If you have an Android smartphone, I suggest to use MPDroid.

On the desktop I use Sonata, a lightweight GTK+ client written in Python.

Did this article help you? Spread the word!

If you liked this article, please share it in your preferred social media circles (twitter, g+, facebook, etc.)

Related articles

Tags

Comments

  1. Dave LaDelfa

    After the wget, I needed to do this, otherwise mpc ls wasn't seeing the file:

    mpc update

  2. Steffen

    Thx Dave, I added it to the text.

  3. Steffen

    If you have a whole bunch of songs to be added to the actual playlist, better use:

    $ mpc add /

    instead of

    $ mpc ls | mpc add

  4. ALI AKIN

    Dear MR. Steffen MULLER..

    I'bout a Raspberry PI board for make a Live Audio Streamer
    I red your wroute at above..
    But I am junior beginner to Raspbian and RaspberryPI.
    I tried to install Darkness and Icecast to Raspberry,but it's
    not succesfully.
    Couyld you advice me that how can I ?nstall and configure of my Raspberry PI board for create a Audio IP Streamer,

    Thank you for your kindly help

    Best Regards

  5. Jeremy

    I actually had to add the following to my icecast.xml file to get it to work:


    /mpd


    Did anyone else have to do this?

  6. Jeremy

    Crap! The form removed the code:

    <mount>
        <mount-name >/mpd< /mount-name>
    </mount>

  7. Jeremy

    Remove the spaces of course. I had to put those since the form removed it otherwise.

  8. Steffen

    Sorry Jeremy for the hassle. The comments module is indeed crap.

  9. mmmatjaz

    I'm using the built in httpd stream instead of icecast and the stream isn't exactly continuous, it keeps stopping and skipping. I think the reason is that mpd has to transcode the sound in realtime, which is probably to much to handle for the PI's cpu. Is there any other option that would allow to stream the sound in it's original format? I've got plenty of bandwidth, so that won't be a problem. I just won't to take that load off the CPU.

  10. mmmatjaz

    FIX:
    * I want to take that load off the CPU.

  11. Steffen

    I never used the builtin http streaming of mpd. AFAIK it also requires encoding, so you won't gain much performance here. I suggest to use raspbian, which ships hardfloat FPU support. This will reduce the load on your CPU significantly.

  12. ronald

    Dr Muller
    New to Raspbian!
    Found the tutorial
    Error on install - fetch fails because they have changed the file name recently:

    E: Failed to fetch http://mirrordirector.raspbian.org/raspbian/pool/main/j/jackd2/libjack-jackd2-0_1.9.8~dfsg.4+20120529git007cdc37-4_armhf.deb: 404 Not Found

    Please, any suggestions?
    thanks

  13. Steffen

    Dear ronald,

    try:

    $ aptitude update
    $ aptitude safe-upgrade

    Then continue with installation. It's safe to do that before installing new packages.

  14. om

    Thanks very useful information

  15. om

    why'd it link my name to a site? lol

  16. Gethin Evans

    Excellent stuff! Great tutorial. Appreciated.

    This actually stopped my DAC from crunching, one of the libraries must have fixed it. Before I installed these libraries, my Wolfson DAC would sound horrible. Maybe now it bypasses alsa? Not sure, but now it sounds clean, even with 24bit 96khz flac files. mpc and vlc now plays back perfectly on my first gen pi.

  17. Mitesh

    i m getting error...

    after typing: sudo /etc/init.d/mpd restart

    Starting Music Player Daemon: mpdFailed to load database: Failed to open database file "/var/lib/mpd/tag_cache": No such file or directory
    Failed to create sticker table: database or disk is full
    failed!

  18. Nikola

    Hey, thanks for the tutorial. I was wandering if it is possible to make it work other way around. I have a music library in my Android and a Raspberry Pi (with speakers) in my bedroom. I want to play the music from my Android on the Raspberry speakers.
    Thank you in advance.

  19. Steffen

    Hi Nikola.

    Sticking to my setup, you would need an app for android which is capable of sending audio streams (e.g. http streams). On RasPi you could run icecast which receives the stream from android. A simple command line player (like mplayer) on RasPi could then connect to the icecast instance and play the stream.
    Unfortunately I don't know such an android app.

    There might be other ways to solve your need, for example with upnp. But I'm sorry I don't know much about this and can't help you.

  20. matt

    Brilliant tutorial, worked perfectly for me. As you mentioned, my RasPi's CPU is stuck at around 80% when I have mpd running in this configuration. I'd like to send multiple channels, and even do other things with the RasPi at the same time. Does anyone know of a way to reduce the CPU load? Perhaps by doing less or no processing on the sound files?

  21. Niko

    all this manipulation works ;)
    thanks!!

  22. Carl

    No Longer Works on pi 2 latest version. What am I doing wrong?
    pi@raspberrypi:~ $ sudo mpc outputs
    error: Connection reset by peer

  23. Daniel

    I have a public webserver (apache2) and followed this guide, but <<myaddress>>:8000/ doesn't respond. I chose <<myaddress>> as the hostname during the icecast configuration and changed it to "localhost" in the "icecast.xml" after it didn't work.

    I did *not* typed in "sudo modprobe ipv6", I changed bind_to_address "localhost" to bind_to_address "127.0.0.1" in the mpd.conf instead.

    The result of "sudo netstat -ltpn" looks equals to mine (except the missing tcp6 entry).

    Once I tried to replace in the mpd.conf every "localhost" and "127.0.0.1" with <<myaddress>> but then I got the error "Failed to bind to '<<ipaddress>>:6600': Cannot assign requested address", so I changed it back.

    Had somebody similar problems?"

  24. Zsolt

    When I running the mpc update
    I got: error: No database
    I have the following config:
    log_file "/var/log/mpd/mpd.log"
    db_file "/var/lib/mpd/tag_cache"
    user "mpd"
    group "audio"
    audio_output {
    type "shout"
    name "My Rspberry Pi Stream"
    description "This is a Icecast2 stream on my Raspberry Pi"
    host "localhost"
    port "8000"
    mount "/mpd"
    password "hackme"
    bitrate "128"
    format "44100:16:2"
    encoding "mp3"
    }
    rights looks like good:
    pi@raspberrypi:/var/lib/mpd $ cd /var/lib/mpd
    pi@raspberrypi:/var/lib/mpd $ ls -lrt
    total 20
    drwxrwxr-x 2 mpd audio 4096 Dec 12 2014 playlists
    -rw-r--r-- 1 mpd audio 3072 Feb 22 19:44 sticker.sql
    -rw-r--r-- 1 mpd audio 204 Feb 22 19:44 tag_cache
    -rw-r--r-- 1 mpd audio 189 Feb 22 19:50 state
    drwxrwxr-x 2 mpd audio 4096 Feb 22 19:52 music

  25. Mario

    I can't get that mount point "/mpd" working.
    I added the config in the icecast2.xml but no luck!

  26. mikeziri

    what's the advantage of using icecast audio output on mdp insted of audio_output http stream directly?

  27. Steffen

    Icecast is a full featured streaming service, while mpd http stream is very limited. Icecase can be run on a separate machine and scales much better than mpd http stream.