Mopidy Multiple Instances - Integration with Shairport-sync

I finally figured out how to get two instances of both mopidy and shairport-sync running on pi-musicbox on a pi3 with two usb sound cards. My only issue is getting shairport-sync2 to stop mopidy when it is playing a stream and there is a request to stream via shairport-sync.

Session control is set to run_this_before_play_begins = “usr/bin/mpc stop” in the second config file, like the first. With two instances of mopidy running, how do I specify mpc to stop the second instance of mopidy to shairport-sync can play?

I’m pi-musicbox newby and not a linux guru, so some of this is above my head.

Figured it out. Forgot about port option for mpc. As simple as changing the stop command to correspond to the port of the second mopidy instance.

run_this_before_play_begins = "/usr/bin/mpc -p 6601 stop (second instance port in my case).

When I get a 6.1 usb sound card, I will try to write a tutorial here for setting up multiple instances with shairport-sync. The info I used was scattered all over the place. I will try to set it up to provide 4 sources on 4 different channels of my home multi-source set up. I think the pi3 can handle streaming 4 sources at one time.

I would say it depends on the sources. Spotify is a bit of a hog. Internet streams will be much better.

Only use shoutcast streams, tune in, and local network files. Shairport-sync for apple music (kid).

Almost got 5.1 card working with 3 services. Figured out asound.conf settings to dmix channels, but for some reason I can’t get asound.conf changes to persist after reboot. Can anyone give me advice on making these changes stick?

/opt/musicbox/startup.sh runs on each boot. One of the things it does is to call /opt/musicbox/setsound.sh which overwrites asound.conf. You probably don’t want any of setsound.sh so you can edit startup.sh and remove the source line.

Thank’s Nick, that did the trick. Just troubleshooting shairport-sync multiple instance startup issues, then should have 3 zones running. I thought the sound card I bought was 7.1, but it’s only 5.1. I’ll have to add one of the generic cards and revise the asound.conf to get 4 channels going. Then I will put up the how to here.

Guide for doing multiple mopidy and shairport-sync instances on pi-muiscbox: Part 1 - sound setup

A little history: I have a whole house audio system with 8 inputs and 6 zones. My old roku soundbridge was dying and the 3 modems that I used for mpd couldn’t be updated to use any new clients. I decided to upgrade and got 3 pi 3’s to all run pi music box in 3 different areas (2 in my shed and 1 in the house) for streaming radio, local files, and air play (kids). The first two music box installs were very easy as they were stock installs with a single usb card. In the house I decided to use a 5.1 usb card and a 2 channel card to create 4 outputs for the sound system, which required much research from many sources and many hours to complete. So here’s the recipe that I used.

I started with a base install pi musicbox .7 RC5 with a single usb card. I followed the docs and set fixed ip, hostname, etc. After getting the new 5.1 card, I rebooted with the new card and got the device info from aplay -l. Setting up asound.conf for this card was the most involved section of the this build. Here’s my asound.conf:

asound.conf

pcm.snd-card1 {
type hw
card 1
device 0
}
pcm.dmixer {
type plug
slave.pcm {
type dmix
ipc_key 10260
slave.pcm "snd-card1"
slave {
rate 44100
period_time 0
period_size 4096
buffer_size 131072
channels 6
}
bindings {
0 0
1 1
2 4
3 5
4 3
5 2
}
}
}
pcm.!default {
type plug
slave {
pcm "dmixer"
channels 6
}
ttable.0.0 1
ttable.1.1 1
ttable.0.2 1
ttable.1.3 1
ttable.0.4 1
ttable.1.5 1
}
pcm.ch1 {
type plug
slave {
pcm "dmixer"
channels 6
}
ttable.0.0 1
ttable.1.1 1
}
pcm.ch2 {
type plug
slave {
pcm "dmixer"
channels 6
}
ttable.0.2 1
ttable.1.3 1
}
pcm.ch3 {
type plug
slave {
pcm "dmixer"
channels 6
}
ttable.0.4 1
ttable.1.5 1
}

I based my config on this info, asound.conf info but had to do a bunch of testing with speaker-test to get everything working. If you have to use a custom asound.conf, you will also have to disable setsound.sh in /opt/musicbox/startup.sh so it doesn’t reset your conf file every reboot. As the second card I used was a standard two channel card, I just referenced the hardware id, instead of creating a pcm device for it. If you are like me and not a linux expert, this part maybe the most time consuming part of this setup. Alsa is very powerful but not simple to learn and like most linux app, learning the correct syntax makes it fun and frustrating at the same time.

Guide for doing multiple mopidy and shairport-sync instances on pi-muiscbox: Part 2 - mopidy setup

Once you have your sound card configured and working, you can prepare for running multiple instance of mopidy services. I used WinSCP to do most of the copying/editting as it’s much easier than using the command line with putty. You will need to have new cache_dir (/var/cache/mopidy) and data_dir (var/lib/mopidy) for each instance you will be running. I just duplicated the folders in each location and named them mopidy1-4.

I also duplicated /etc/mopidy/logging.conf and /etc/mopidy/logging-debug.conf for each instance, changing file name to match instance number. I left the original mopidy folders in place for ease of naming in config files.
Duplicate the mopidy binary file at /usr/local/bin/mopidy and again name each the instance number for ease of reference.

Next I created a blank config file - mopidy1.conf which will house only the changes needed for each instance. Attached is an example. You need [core] - cache_dir and data_dir info (folders you just made), [logging] config_file, debug_file, [http], port = new port for web interface, [mpd], port = new ports for mpd, and lastly you will need [audio], output pointing to your device for each stereo output. This will follow asound.conf created earlier, i.e. output = alsasink device = pcmName, or hw:X,X in my case for source 4.

mopidy1.conf

//Service Home Channel 1 Config
[core]
cache_dir = /var/cache/mopidy1
data_dir = /var/lib/mopidy1

[logging]
config_file = /etc/mopidy/logging1.conf
debug_file = /var/log/mopidy/logging-debug1.log

[http]
port = 6681

[mpd]
port = 6601

[audio]
output = alsasink device=ch1 //setting for channel 1 of 5.1 card from asound.conf
output = alsasink device=hw:0,0 // setting for hardware device of channel 4

Finally rename the init script for mopidy to mopidy1 (/etc/init.d/mopidy) and duplicate it and name each the instance number. Now you will have to edit each init script to run properly. Edit Provides, DESC, Name, DAEMON to match increment number (mopidy1-4). Also append CONFIG_FILES with :/etc/config/mopidy#.conf so mopidy will see the instance specific config files. This way you only need to specify changes for each instance. Once you have created all your init scripts, run “update-rc.d mopidy# defaults” for each instance so it will read your configs.

First part of /etc/init.d/mopidy1

//!/bin/sh

//BEGIN INIT INFO
// Provides: mopidy1
// Required-Start: $network $remote_fs
// Required-Stop: $network $remote_fs
// Should-Start: $named alsa-utils avahi dbus pulseaudio
// Should-Stop: $named alsa-utils avahi dbus pulseaudio
// Default-Start: 2 3 4 5
// Default-Stop: 0 1 6
// Short-Description: Mopidy music server
// END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=“Home Ch1 Mopidy music server"
NAME=mopidy1
DAEMON=/usr/local/bin/mopidy1
DAEMON_USER=mopidy
DAEMON_GROUP=audio
CONFIG_FILES=”/usr/share/mopidy/conf.d:/etc/mopidy/mopidy.conf:/etc/mopidy/mopidy1.conf"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
…rest is default

Now you can test mopidy services to see if they will run by running “service mopidy# start” for each instance. To access the web interface, you will have to use the port for each instance as in the config file. I would suggest rebooting to make sure all your mopidy instance start as they should.

1 Like

Guide for doing multiple mopidy and shairport-sync instances on pi-muiscbox: Part 3 - shairport-sync setup

Now to setup shairport-sync to handle multiple instances. This is similar to the steps above with a couple of differences. To get multiple instance of shairport-sync running you will have to create sym links to the binary located at /usr/local/bin/shairport-sync. Create symlinks for each instance you will be running using “ln -s shairport-sync shairport#-sync”. I had some problems with the sym links not working correctly, probably because I had some errors in my configs, but I just had to delete the old links and create new links.

Next duplicate the config file, /etc/shairport-sync.conf, naming each with an instance number. You will have to edit each changing name (as it defaults to hostname), port (increment to match instance), udp_port_base (I incremented by 10 as it says it uses 3 ports). If you stream other things, you will want to edit run_this_before_play_begins and change mpc -p 660# stop, to match mopidy port for that instance. Otherwise it won’t stop a stream to run shairport-sync. Lastly edit output_device to the pcm device from asound.conf.

shairport-sync1.conf

Here are the non-default changes that I made.
general =
{
name = “House-1”;
port = 5001;
upd_port_base = 6010;
sessioncontrol =
{
run_this_before_play_begins = “/usr/bin/mpc -p 6601 stop”;
alsa =
{
output_device = “ch1”; //1st stereo channel of 5.1 card from asound.conf
output_device = “hw:0,0”; //4th channel from second usb card

Finally, edit the init scripts for shairport-sync. I did the same duplication like mopidy init scripts. Edit Provides, DESC, and NAME to match the instance name. If your multiple output card is default, you don’t need to edit the start-stop-daemon info. For my 2 channel card, I had to change this line with the name and hw:#, as shown below. Once your done editting, run “update-rc.d shairport-sync# defaults” to update inits. Now you should be done if you don’t have errors in your configs. You can reboot and check if everthing is running with “service --status-all”. If you have issues with the service not starting, you can try and redo the symlinks. Otherwise it could be a typo in either the script or config files. I had a couple during my trials.

/etc/init.d/shairport-sync1

//! /bin/sh
//BEGIN INIT INFO
//Provides: shairport-sync1
//Required-Start: $all
//Required-Stop: $remote_fs $syslog
//Default-Start: 2 3 4 5
//Default-Stop: 0 1 6
//Short-Description: Shairport Synchronous AirPlay
//Description: Implements a synchronous (multi-room-capable) AirPlay receiver
//END INIT INFO

// Author: Mike Brady mikebrady@eircom.net

// Do NOT “set -e”

//PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="House Ch1 AirPlay Synchronous Audio Service"
NAME=shairport-sync1
DAEMON=/usr/local/bin/$NAME
… first part - then to start-stop-daemon area

start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON – -d || return 2
//start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON – -d -a “House-4” – -d hw:0 || return 2

First line for default sound card (5.1 in my case) and second line for second usb card used on instance 4

Hopefully this guide will make it easier to create a multi-source musicbox with air play for each source. The next project is to build a simple locally hosted web interface to get to the instances without having to deal with the ports.