Build your own Spotify-like music streaming solution using mpd

Since I distrust centralized services such as Spotify that can delete content you love at any time they like, I’ve always bought my own music and have a huge collection. But there’s no denying that streaming music to any device or location is a useful feature. You still don’t need Spotify for that, thanks to the FOSS community you can build your own Spotify-like streaming system, and this guide shows one combination of software to accomplish this.

The goal: Stream your music collection from your own PC (or NAS or whatever storage you have) to any web browser, mobile phone and desktop clients.

The method: A little Linux magic involving the following components:

  1. Debian GNU/Linux as server OS. Should work with any other distro, too, but this guide will focus on Debian
  2. MPD (Music Player Daemon) as music server
  3. Bragi-MPD as web-based MPD client/streaming music player
  4. For Linux desktops:
    1. Cantata, as MPD client/streaming music player
  5. For Android mobile phones:
    1. ConnectBot in case you want to secure your streaming via SSH (optional but recommended)
    2. M.AL.P. as MPD client/streaming music player

Setting up the server

We’re going to set up mpd to run inside your own user account. I’m assuming you already have a Debian server set up and the following is true:

  • you: This is your username
  • /home/you: This is your home directory
  • /home/you/music: This is where your music lives
  • You allow SSH connections to this server as your user

Installing and configuring MPD

Install the required components (as root or with sudo):

apt-get install mpd flac libmp3lame
systemctl disable mpd

We are disabling the system-wide mpd because we want to run our own user-level MPD instead.

Switching to your normal user, create some required directories:

mkdir -p ~/.mpd/playlists

Then stick this in your ~/.mpdconf:

music_directory        "~/music"
playlist_directory     "~/.mpd/playlists"
db_file                "~/.mpd/database"
log_file               "~/.mpd/log"
pid_file               "~/.mpd/pid"
state_file             "~/.mpd/state"
sticker_file           "~/.mpd/sticker.sql"

bind_to_address        "0.0.0.0"
port                   "6601"

audio_output {
  type           "httpd"
  name           "lossless"
  encoder        "flac"
  port           "8000"
  max_clients    "8"
  mixer_type     "software"
  format         "44100:16:2"
}

audio_output {
  type           "httpd"
  name           "lossy"
  encoder        "lame"
  bitrate        "320"
  port           "8001"
  max_clients    "8"
  mixer_type     "software"
  format         "44100:16:2"
}

We’re doing some special things:

  1. bind_to_address: will bind to all IPv4 interfaces so you can control MPD directly from e.g. mobile phones in your wifi
  2. audio_ouput: We’re creating two of them, one for lossless audio so you lose no quality if you have enough bandwidth on your client, one for lossy audio in case you’re connected e.g. via mobile internet. The format option makes sure to normalize all your output to 44.1 KHz because some clients have problems streaming when the resolution or bitrate suddenly change. Note that we remove all other audio outputs. The goal of this guide is to have a streaming server, if you run MPD on your desktop you may of course want to leave some local audio outputs alive.

Try to start MPD now. It should start and log any problems to ~/.mpd/log:

mpd

To make this persistent through reboots, try to add a crontab to you‘s cron with crontab -e:

@reboot mpd

Controlling MPD and streaming to your desktop

To verify that everything is working and to reward yourself with some streaming audio, try to install a desktop MPD client. On Linux, I recommend Cantata because it has streaming support built in. Unfortunately, the Windows version of Cantata lacks this feature. On e.g. a Debian 9 desktop, you can simply install the package:

apt-get install cantata

Start it, then go to Settings > Configure Cantata… > Collection and add a new collection:

Configuring the media server as collection in Cantata

My media server’s hostname in the local network is simply “media”, replace that with your own. Make sure to adjust the port to 6601 because that’s what we set up earlier. The stream URL in this case points to port 8000 because the local network surely has enough bandwidth for the lossless stream. If you want the lossy one instead, use port 8001.

Once you click “Apply” you should be able to choose this collection under Music > Collection.  If the connection succeeds, Cantata probably automatically triggers a database update (it will show “Updating database”). This can take a while depending on how much music you have.

Once it is finished indexing, you should see your music on the left. Drag some albums to the playlist on the right and press play. If the player stays at 0:00 or if there is an error connecting, check ~/.mpd/log on the server to see what’s wrong. If the player plays but you hear no audio, make sure the streaming button (headphones indicated in the screenshot below) is clicked:

Congratulations, you now have a streaming server for your home network! Now let’s make this mobile.

Controlling MPD and streaming to your mobile phone using a native client

Natively, this only works on Android. Install ConnectBot and M.AL.P..

Securing your streaming using SSH

We use ConnectBot to connect to your home server and to forward some ports so you can control it and stream via the same encrypted connection. Setting this up is not too hard:

  1. Create a new host inside ConnectBot that connects to the server where your music is, using the user you and specifying the server’s external address so that you can stream from anywhere in the world. How to port forward SSH and get your own dynamic DNS pointing to your home connection is outside the scope of this guide, but searching for “port forwarding SSH home router” or something like that should get you there
  2. Save your connection
  3. Long-press on the connection in the connection list and select “Edit port forwards”
  4. Set up the forwards for ports 8001 (lossy audio) and 6601 (mpd control) as in the picture below, replacing 192.168.2.10 with the internal IP of your media server:
Adding port forward in ConnectBot
Port forwards in ConnectBot

Now connect to your server using ConnectBot.

Using M.A.L.P

After you start M.A.L.P., you’ll ned to set up a connection to MPD. Since we’re using the tunnel provided by ConnectBot, the address for the server will be appear to be localhost. Go to the hamburger menu in the top left and under “Settings” find “Profiles”:

Editing a profile in M.A.L.P.
Profiles in M.A.L.P.

If everything goes well, you should already be able to control your MPD server this way. To also start streaming, press the three dots menu in the upper right and select “Start streaming”:

Now you should have your entire music collection available to stream to your mobile device.

You could of course also skip ConnectBot and SSH by opening the MPD control and streaming ports directly to the Internet, but I wouldn’t recommend that. Who knows who might find your streaming port, and suddenly the copyright mafia shows up at your door because you were operating an unlicensed web radio.

Controlling MPD and streaming to most devices using any web browser

The final step is perhaps the coolest, you use a web-based player so you don’t have to install anything on any clients. This way, you can ruin people’s parties by streaming your choice of 80s German schlager to any available device.

On your media server, as root (or using sudo), install Python’s pip package manager and then websockify:

apt-get install python-pip
pip install websockify

Change to your normal user and go to its home directory, where you unpack the latest version of Bragi-MPD:

wget https://github.com/bobboau/Bragi-MPD/archive/master.zip
unzip master.zip

You should end up with a directory called Bragi-MPD. Change to it and copy the example config file to your own custom config file:

cd Bragi-MPD
cp default_config.js config.js

Edit the file and change the streaming and control ports:

var CONFIG = {
    clients:[
        {
            name:'main',
            port:8800,
            stream_port: 8001          
        }
    ]/*,
    theme:['alt_colors.css']*/
};

Now hook it all together using websockify:

websockify --log-file=/home/you/websockify.log -D --web /home/you/Bragi-MPD/ 8800 localhost:6601

If you point a web browser at the address of your media server on port 8800, you should see what music is currently playing and the current playlist. Plus, if anything is on, you should already hear the music. For me, that address would be http://media:8800 at home. What I haven’t done yet is put port forwarding in place and added SSL and a password, but I’ll leave that to your imagination.

To make this persistent across reboots, you can do something this in a crontab entry for you using crontab -e:

@reboot websockify --log-file=/home/you/websockify.log -D --web /home/you/Bragi-MPD/ 8800 localhost:6601

If I am ever not too lazy to add the instructions for SSL and passwords, I’ll update this article. Until then, enjoy your homemade streaming.

One thought on “Build your own Spotify-like music streaming solution using mpd”

Leave a Reply

Your email address will not be published. Required fields are marked *