I have a multi-channel home audio setup that works quite remarkably
well.
And all I wanted was the ability to say "I've finished being here
for a bit, so when you get to the end of the current track, pause
playback". Then I got interested.
The core of all this is a complete separation of roles: a control
client, that determines what's being played, is completely separate
from a storage server, which has access to the files, and a playback
client, which actually wiggles a speaker cone – even if they end up
running on the same machines. This requires a central audio server,
and a host for each set of speakers or headphones – a desktop or
laptop computer can do this as part of its other jobs, or for a
stand-alone player a Raspberry Pi will do the job nicely. (Snapcast
even comes with a custom lightweight OS image that just runs the
Snapcast client and nothing else.)
This setup comes in two parts: mpd
, the Music Player Daemon, and
snapcast
. Both of these have packages in Debian/stable, which is
what I run; if you're using something else, see MPD
homepage and Snapcast
homepage.
MPD first. Configure this to point at your audio repository. Note that
all filenames must be valid UTF-8 to be indexed. (Also, it'll read cue
files, but this is generally an error unless you're storing pairs of
cue/flac; when I get music that way, I prefer to break it down to
individual file-per-track.)
If you want another channel, i.e. a separately playable mpd
instance
that shares the same music database as the primary instance, set up a
new config file, changing playlist_directory
, log_file
, pid_file
state_file
and port to new values – and start it separately. Also
set:
database {
plugin "proxy"
host "localhost"
}
MPD can drive speakers directly, or serve http, but in this case we'll
be running the output through snapcast. Here's how I do that:
audio_output {
type "fifo"
encoder "flac"
name "snapserver"
format "44100:16:2"
path "/tmp/snapfifo"
compression "8"
mixer_type "software"
}
Other mpd
instances get a different path: /tmp/snapfifoB
etc.
Then add a matching entry for each instance in /etc/snapserver.conf
:
source = pipe:///tmp/snapfifo?name=mpd-A&sampleformat=44100:16:2&codec=flac
source = pipe:///tmp/snapfifoB?name=mpd-B&sampleformat=44100:16:2&codec=flac
etc.
Each of those is a stream name from mpd: mpd-A, mpd-B, etc. (and in
theory you could link in other streaming sources too, but I don't).
Then individual snapclient
installations can be pointed at the
server, and configured either with the official web interface or my
command-line tool (which I wrote because I didn't feel I needed yet
another thing driven through a web browser).
The end result of all this is that I have multiple players, all
synchronised, so that if I'm on my own in the house I can have audio
from everywhere – and of course the API in mpd
makes it very easy to
control playlists and such like. (See other "MPD" posts.)
mpd-tools package on
github
snapcast-tools package on
github
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.