My music setup at home with mopidy, forked-daapd and shairport-sync

UPDATE 1: I've modified a bit of a section from this here.

Here is my music setup at home. I have a mac mini that's been transformed to a server running debian stretch. It runs a few deamons. I have mopidy as my main web interface which is also connected to Spotify and Soundcloud through mopidy plugins. What is mopidy? Taken from their github site 'Mopidy is an extensible music server that plays music from local disk, Spotify, SoundCloud, Google Play Music, and more.' The backend is forked-daapd which is a Linux/FreeBSD DAAP (iTunes) with support for AirPlay devices (multiroom). Mopidy connects to forked-daapd that then streams to any AirPlay devices to multiple rooms in my house. Im pretty happy with this setup but I wanted more. I wanted to be able to use my iDevices or having my spouse or kids to be able to steam to our multiroom setup. That's when shairport-sync comes in. I can pipe the music stream to forked-daapd that send audio to all AirPlay devices and not only that but also the metadata from the shairport-sync.

I know you could do with something like Rogue Amoeba Airfoil but then you need your mac to be on at all time which I didnt want to do. Part of the reason that I installed linux on the mini is also because I run Kodi on it. It runs these daemons and kodi. I didnt want the bloat of running macOS just for that.

Here is the kicker with this setup, I could put speakers anywhere either inside or outside the house thats connected to the network and play music from any devices to them. Putting speakers outside is on my to-do list which seems to be getting longer and longer. Ohh the joy of owning a house in Upstate NY. But in any case I digress, it's super easy to transform a raspberrypi into an audio hub with shairport-sync. The quality of the audio isnt that great on the first generation of raspberrypi devices but seem to be fairly decent on newer 2+ models. Dont quote me on this.

Here are the steps I've used.

mopidy

To download mopidy you should follow the instructions on this page https://docs.mopidy.com/en/latest/installation/. For my debian box, here is what I did.

I added the mopidy GPG key:

$ wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -

Added the APT repo to your package sources:

$ sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/stretch.list

Install Mopidy and all dependencies:

$ sudo apt-get update
$ sudo apt-get install mopidy

You can search for every extensions on the repository with the search command which is very useful. For example, installing extensions spotify and soundcloud.

$ apt search mopidy
$ sudo apt install mopidy-spotify mopidy-soundcloud

mopidy config files

If you have a local music library then make sure you point it to the right directory. Here is my config file located in /etc/mopidy/mopidy.conf. You should check out https://docs.mopidy.com/en/latest/config/ to fully understand all the possibilities. I disabled MPD because I didnt need it. You should replace $USER with your actual home folder.

[core]
cache_dir = /var/cache/mopidy
config_dir = /etc/mopidy
data_dir = /var/lib/mopidy

[logging]
config_file = /etc/mopidy/logging.conf

[audio]
output = audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink
location=/home/$USER/music/mopidy

[mpd]
enabled = false

[http]
enabled = true
hostname = 0.0.0.0
port = 6680
zeroconf = Mopidy HTTP server on $hostname

[softwaremixer]
enabled = true

[local]
enabled = true
library = json
media_dir = /home/$USER/music
scan_timeout = 1000
scan_flush_threshold = 100
excluded_file_extensions =
.directory
.html
.jpeg
.jpg
.log
.nfo
.png
.txt

[spotify]
enabled = true
username = alice
password = secret
bitrate = 320
client_id = client_id value you got from mopidy.com
client_secret = client_secret value you got from mopidy.com

[scrobbler]
username = alice
password = secret

[soundcloud]
auth_token = 1-1111-1111111

mopidy-spotify

For more information on the mopidy-spotify plugins check out https://github.com/mopidy/mopidy-spotify. What I had to do to be able to fun spotify was to modify the config files /etc/mopidy/mopidy.conf. You will need to find your spotify username and password that are located in your account overview page at https://www.spotify.com/us/account/overview/ and put it instead of the ones below. After you put your info in the conf files you will need to visit https://www.mopidy.com/authenticate/#spotify to authorize this extension against your Spotify account:

[spotify]
username = alice
password = secret
client_id = client_id value you got from mopidy.com
client_secret = client_secret value you got from mopidy.com

mopidy-soundcloud

To configure mopidy-soundcloud located https://github.com/mopidy/mopidy-soundcloud you need to follow the following steps stated on the website:

  1. You must register for a user account at http://www.soundcloud.com/
  2. You need a SoundCloud authentication token for Mopidy from http://www.mopidy.com/authenticate
  3. Add the authentication token to the mopidy.conf config file:
[soundcloud]
auth_token = 1-1111-1111111
explore_songs = 25

mopidy running as a service

Systemd ways of running services is fairly easy. You should enable it using:

$ sudo systemctl enable mopidy

Now that this is enabled, it will start mopidy after each boot.

To start, stop and restart you use the following command:

$ sudo systemctl start mopidy
$ sudo systemctl stop mopidy
$ sudo systemctl restart mopidy

You can check the status of the service with:

$ sudo systemctl status mopidy

mopidy web extensions

We will need a web interface to be the front end of mopidy. My two favorite are Mopidy-MusicBox-Webclient and Mopidy-Mopify both available with pip. Mopify is great for spotify access and musicbox is great for iDevices.

$ sudo pip install Mopidy-Mopify
$ sudo pip install Mopidy-MusicBox-Webclient

Now that its installed you should go to the URL 0.0.0.0:6680 to see if it worked.

forked-daapd

Here are the step that I use to install forked-daapd.

$ sudo apt-get install build-essential git autotools-dev autoconf libtool gettext gawk gperf antlr3 libantlr3c-dev libconfuse-dev libunistring-dev libsqlite3-dev libavcodec-dev libavformat-dev libavfilter-dev libswscale-dev libavutil-dev libasound2-dev libmxml-dev libgcrypt11-dev libavahi-client-dev zlib1g-dev libevent-dev libplist-dev libsodium-dev libjson-c-dev libwebsockets-dev

Optional packages:

Feature Configure argument Packages
Chromecast --enable-chromecast libgnutls-dev libprotobuf-c-dev
LastFM --enable-lastfm libcurl4-gnutls-dev OR libcurl4-openssl-dev
iTunes XML --disable-itunes libplist-dev
Device verification --disable-verification libplist-dev libsodium-dev
Live web UI --with-libwebsockets libwebsockets-dev
Pulseaudio --with-pulseaudio libpulse-dev
$ git clone https://github.com/ejurgensen/forked-daapd.git
$ cd forked-daapd
$ autoreconf -i
$ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --with-pulseaudio --enable-lastfm
$ make
$ sudo make install

Now that it's installed check the config file /etc/forked-daapd.conf and make sure you have your music directory in the config file like below.

# Directories to index
directories = { "/home/$USER/music" }

and to stream the music from other devices via the pipe that we will create later we need to make sure it set to true. Let's adjust one more thing in the config file.

# Watch named pipes in the library for data and autostart playback when
# there is data to be read. To exclude specific pipes from watching,
# consider using the above _ignore options.
pipe_autostart = true

I disabled a bunch of other options because I didnt need them like MPD, spotify and such.

forked-daapd running as a service

Done with config file, lets move to have it run it as a service. Here is my forked-daapd.service file located in my /etc/systemd/system folder. I use the following options are

  • Running in the foreground with -f
  • Debug log level -d 0
  • Location of the config file with -c /etc/forked-daapd.conf
[Unit]
Description=DAAP/DACP (iTunes), RSP and MPD server, supports AirPlay and Remote
Documentation=man:forked-daapd(8)
After=network.target sound.target remote-fs.target pulseaudio.service avahi-daemon.service

[Service]
ExecStart=/usr/sbin/forked-daapd -f -d 0 -c /etc/forked-daapd.conf

# Restart, but not more than once every 10 minutes
Restart=on-failure
StartLimitBurst=2
StartLimitInterval=600

[Install]
WantedBy=multi-user.target

Like mopidy and any other systemd services, to enable forked-daapd to run here is what I do.

$ sudo systemctl enable forked-daapd

Now that this is enabled, it will start forked-daapd after each boot.

To start, stop and restart you use the following command:

$ sudo systemctl start forked-daapd
$ sudo systemctl stop forked-daapd
$ sudo systemctl restart forked-daapd

You can check the status of the service with:

$ sudo systemctl status forked-daapd

If it's running you should be able to go to http://[your_server_address_here]:3689 and see your current AirPlay devices. You will be able to toggle them on or off.

Shairport-sync

Now, here is where the magic will happen, creating a pipe. Make sure you have the right permissions meaning that $USER can read/write to the music folder. Maybe perharps a chmod -R 755 music. Lets also restart forked-daapd.

$ mkfifo /home/$USER/music/shairport
$ mkfifo /home/$USER/music/shairport.metadata
$ chmod 777 shairport shairport.metadata
$ sudo systemctl restart forked-daapd

Now that we have forked-daapd running we need to start installing shairport-sync in order to have other user or devices able to stream to the AirPlay devices.

sudo apt install build-essential git xmltoman autoconf automake libtool libdaemon-dev libpopt-dev libconfig-dev libasound2-dev libpulse-dev avahi-daemon libavahi-client-dev libsoxr-dev

Let's download shairport-sync and build it. I used the following settings for building shairport-sync. Do check the README.md file for more information about each settings. It has tons of information. I also run shairport-sync on a raspberrypi

$ git clone https://github.com/mikebrady/shairport-sync.git
$ cd shairport-sync
$ autoreconf -i -f
$ ./configure --sysconfdir=/etc --with-alsa --with-pa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemd
$ make -j4
$ sudo make install

My shairport-sync.conf file in /etc

general = {
  name = "SHAIRPORT";
  output_backend = "pipe";
};

metadata = {
  enabled = "yes";
  include_cover_art = "yes";
  pipe_name = "/home/$USER/music/shairport.metadata";
}

sessioncontrol = {
  allow_session_interruption = "yes";
  session_timeout = 20;
}

pipe = {
  name = "/home/$USER/music/shairport";
  audio_backend_buffer_desired_length = 48000;
}

Now that you have the pipe set up you will be able to have music sent to all your speakers selecting the SHAIRPORT device. You should now make shairport-sync start at boot time. Lets use systemd again. It should have installed the file already in the /lib/systemd/system/shairport-sync.service folder and possibly created a shairport-sync user and group. Here is the conf file just in case.

[Unit]
Description=ShairportSync AirTunes receiver
After=sound.target
Requires=avahi-daemon.service
After=avahi-daemon.service
Wants=network-online.target
After=network.target network-online.target

[Service]
ExecStart=/usr/local/bin/shairport-sync
User=shairport-sync
Group=shairport-sync

[Install]
WantedBy=multi-user.target

Let's make sure it will run after each reboot enabling it in systemd and then let's restart it.

$ sudo systemctl enable shairport-sync.service
$ sudo systemctl restart shairport-sync.service

In any of the systemd services conf file above either for mopidy, forked-daapd or shairport-sync you should make sure if it's running. Troubleshooting various issues like permissions, wrong ExecStart configuration would be where I would start if you run into trouble.

Now you should be able to stream either via mopidy using the web interface within the URL 0.0.0.0:6680 to your AirPlay speakers or you could also use your iDevices/laptop to stream to all your AirPlay speakers. Ive been running this setup for quite some time and its rocking the house. I should also mention that it does have a 4-5 sec latency issue but I dont mind since its only for our listening pleasure. No mixing involve yet..