Skip to content

markferry/multizone-audio

Repository files navigation

A config generator for a multizone audio system based on snapcast, Mopidy and MQTT.

Features

  • support for common audio streaming protocols
    • SpotifyConnect
      • track transitions (crossfade and automix)
      • player controls
    • Airplay
    • Mopidy/MPD
    • Kodi
    • Bluetooth
  • seamless switching between protocols in each zone
  • high-priority announcement streams (alarms, doorbells)
  • invisible, automatic party reconfiguration
  • no clashing audio streams
  • no snapcast controls visible to end-users(!)
  • eliminate unnecessary software volume controls
  • replaygain support

Architecture

Multi Zone Architecture

Almost all media services run on a central media server.

Each media player is its own zone and there are also multiple (logical) "party zones" which group the real zones together. For more on logical zones see the snapcast-autoconfig README

Media Server

The media server runs:

  • one mopidy instance per zone (providing mpd + iris)
  • snapserver
  • mosquitto mqtt broker

Snapserver is configured with:

  • per-zone mopidy, shairport-sync and librespot streams
  • per-zone master meta streams

The snapserver itself runs and manages the librespot and shairport-sync media services.

snapcast-autoconfig manages the snapcast groups (including, for the benefit of Iris, naming them!).

Hardware

Software

See BUILDING for notes on building some of these from sources.

Media Players

Each media player runs:

  • snapclient
  • nginx, proxying http://<hostname>/ to http://<media-server>:66xx/iris
  • kodi, if-and-only-if the player has a screen or projector attached

While snapcast meta streams are neat for auto-switching between audio services it's still confusing when, say, both a spotify and airplay stream attempt to play to the same zone. Instead, when one service starts playing we want the others (in the same zone) to pause.

To accomplish this each media service (mopidy, librespot, ...) is configured to notify via MQTT when playback starts.

See:

Each media service (except librespot) can also be controlled via MQTT.

The idea for this came from hifiberry which implements control of concurrent playback streams via MPRIS.

Hardware

Software

  • snapclient v0.25+
  • nginx
  • dietpi
  • OSMC / Kodi v19+
  • kodi2mqtt

Controller

The pausing of media streams is done by a simple MQTT service - though it could be implemented as:

Volume Control

For end-users only (per-service) soft-volume control is available.

Hardware volume levels are preset by snapcast-autoconfig.

Each snapclient is configured to use an alsa hardware mixer (if available).

librespot and shairport-sync controlling a snapserver

While librespot and shairport-sync can both be configured to control a hardware mixer the snapserver can't be, nor does it create a virtual mixer.

Usage

Prerequisites

These requirements are sufficient to customize the configurations for your setup:

chevron is a python implementation of the mustache templating language.

On first run if chevron isn't found, make will create a python virtual environment and install it for you.

The services are configured by generating systemd service files. Many of them are template unit files so that multiple instances can be started on a single host. (e.g. systemctl start mopidy@study)

Customize

Configurations for each zone (and for all zones) are generated by merging the config.json data into the template files using chevron.

You will need to adapt my existing json config for your purposes. See also ALL_HOSTS in the Makefile.

Generate

⚠️ This will overwrite ../snapserver.conf
make

Test

All the services (except for nginx) can be run and tested locally as an unprivileged user.

To install and run mopidy in a python venv you will need:

sudo apt-get install libspotify-dev
.venv/bin/pip install -r requirements.txt

Generate configs and start all services:

make dev
make dev-install  # this will overwrite files in ~/.config/systemd/user!
# set `SYSTEMCTL_USER := --user` in the Makefile
make start

To start the services for just one zone:

# study only
make HOST=study start-host

Deploy

Server

Requirements: see #software.

⚠️ This will overwrite /etc/snapserver.conf

On your production system, as root:

git clone https://github.com/markferry/multizone-audio.git /etc/multizone-audio
cd /etc/multizone-audio
git checkout $your_branch   # your customizations
make live-install

Clients

For all client hosts:

git clone https://github.com/markferry/multizone-audio.git /etc/multizone-audio
cd /etc/multizone-audio
git checkout $your_branch   # your customizations

Then run the client-specific-install make $os-$host-install

Where $os is one of: debian, dietpi.

And $host is a host defined in config.json.

e.g.:

make dietpi-library-install

Resources

People to follow

  • @badaix - snapcast maintainer
  • @kingosticks - pimusicbox developer
  • @frafall - snapcast metadata contributor and kodi snapcast service developer
  • @ahayworth - snapcast-autoconfig maintainer

Projects

About

A config generator for a multizone audio system based on snapcast, Mopidy and MQTT.

Resources

Stars

Watchers

Forks