-
Notifications
You must be signed in to change notification settings - Fork 3
multi room audio
Although there are some projects with capabilities for sharing or sending playlists between players based in different rooms, or zones, of your house (or office, etc) the problem is usually that some play with a very slight delay, which is off-putting to the human ear.
This article looks at technologies for local streaming of audio from one room to another, especially where the timing can be syncronised
see also:
-
Volumio and MPD
- Dedicated headless music player distro based on MPD - see intro below
- snapcast volume web ui
-
Media Centre
- Full media centre solutions for Pi, rather than simple audio
-
Audio Hub
- looks at software for playing audio files, especially music
-
lubuild Music and Multimedia
- Common clients for audio server software
- options for remote control
- architecture of DLNA / UPnP
- how to create and manage playlist files
- lots of other useful info
-
Audio & Video diagnostics
- troubleshooting devices and configuration for Audio and Video input and output
This uses a project called SyNchronous Audio Player, which transmits chunks of your music across your home network and ensures they are all played simultaneously.
Snapcast is specifically designed for multi-room audio, actively keeping clients playing in sync. On the master device you configure your player to pipe the audio out to SnapServer, then it plays through SnapClient both on the master and on any secondary devices.
This makes it a self-managing networked Audio Repeater. See #Volume Controller below for how to balance volume levels between nodes. Additionally you can use it to switch between multiple audio sources, like a virtual AVR - see #Snapserver sources below.
If you don't mind a couple of versions ago, use the debian package:
sudo apt install snapserver
sudo apt install snapclient
These are command line instructions for setting up both the client and the server on Raspbian Lite. They have been tested as working up to Raspberry Pi OS Bullseye in 2022 and since Raspbian Jesse Nov 2016. Before then we had to build from source.
- not currently available in Debian
-
[https://github.com/badaix/snapcast#install-debian-packages]
-
Notes on package architecture
- Raspbian is a port of Debian for
armel
- Pi 3 supports debian
armhf
(hard float)
- Raspbian is a port of Debian for
-
Check and set the version
-
Set True or false whether you want the server as well
### Prepare
# check if you need to enter sudo password
sudo echo
# check the latest version at
# [https://github.com/badaix/snapcast/releases/latest]
SNAPCAST_VERSION=0.26.0
# only set this next one if the DEB has a -1 suffix on the version number
SNAPCAST_DEB_SUFFIX=${SNAPCAST_VERSION}-1
# Omit or set these to false if you don't want to...
SNAPCAST_INCLUDE_SERVER=TRUE
SNAPCAST_INCLUDE_CLIENT=TRUE
### Download
# download packages for Raspberry Pi architecture
if [[ $SNAPCAST_INCLUDE_SERVER = TRUE ]] ; then (
wget https://github.com/badaix/snapcast/releases/download/v$SNAPCAST_VERSION/snapserver_${SNAPCAST_DEB_SUFFIX:-$SNAPCAST_VERSION}_$(dpkg --print-architecture)_$(lsb_release --codename --short).deb
) ;
fi
if [[ $SNAPCAST_INCLUDE_CLIENT = TRUE ]] ; then (
wget https://github.com/badaix/snapcast/releases/download/v$SNAPCAST_VERSION/snapclient_${SNAPCAST_DEB_SUFFIX:-$SNAPCAST_VERSION}_$(dpkg --print-architecture)_$(lsb_release --codename --short).deb
) ;
fi
### Install packages and dependencies
if [[ $SNAPCAST_INCLUDE_SERVER = TRUE ]] ; then (
sudo apt install -y ./snapserver_${SNAPCAST_DEB_SUFFIX:-$SNAPCAST_VERSION}_$(dpkg --print-architecture)_$(lsb_release --codename --short).deb
#sudo dpkg -i snapserver_${SNAPCAST_DEB_SUFFIX:-$SNAPCAST_VERSION}_armhf.deb
) ; fi
if [[ $SNAPCAST_INCLUDE_CLIENT = TRUE ]] ; then (
sudo apt install -y ./snapclient_${SNAPCAST_DEB_SUFFIX:-$SNAPCAST_VERSION}_$(dpkg --print-architecture)_$(lsb_release --codename --short).deb
#sudo dpkg -i snapclient_${SNAPCAST_DEB_SUFFIX:-$SNAPCAST_VERSION}_armhf.deb
) ; fi
# add any missing dependencies
#sudo apt update
#sudo apt -f install -y
You may get a warning at the end, .deb couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
. In most cases you can ignore this, especially if the snapcast component installation was carried out. Ideas to avoid the error altogether include switching to dpkg install or downloading the .deb into the more permissive location /tmp
.
An example client configuration
cat <<EOF! | sudo tee /etc/default/snapclient
# defaults from installed /etc/default/snapclient file
START_SNAPCLIENT=true
USER_OPTS="--user snapclient:audio"
# run sudo snapclient --help to see options available
# and sudo snapclient --list to see PCM devices for soundcard option
SNAPCLIENT_OPTS="--soundcard 1 --host localhost"
EOF!
For regular ArchLinux the package is also available from AUR at https://aur.archlinux.org/packages/snapcast/ (see https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages) but that would likely not work on ArchinuxArm.
# Build snapcast from source
# credit - https://github.com/badaix/snapcast/blob/master/doc/build.md
sudo pacman -S git
git clone https://github.com/badaix/snapcast.git
cd snapcast/externals
git submodule update --init --recursive
cd ..
sudo pacman -S base-devel
sudo pacman -S alsa-lib avahi libvorbis flac alsa-utils
# either build and install both
make
sudo make installserver
sudo make installclient
# or just make and install client
cd client
make
sudo make install
cd ..
This is a BuildRoot-based embedded OS created by the SnapCast author. Buildroot allows you to created a custom embedded OS image from a linux PC.
For instructions see:
https://github.com/artmg/MuGammaPi/wiki/buildroot#snapos
For the client, that's it. There is a config file /etc/default/snapclient
but it should not need tweaking. It normally finds the host using bonjour,
but if you have multiple hosts you can specify which in there.
If you have installed on Ubuntu derivatives using the instructions above, this will create a service to run automatically as the snapclient user, but that might not give you the control you want.
If you want to change the user context
sudo editor /etc/default/snapclient
sudo systemctl restart snapclient.service
However that still doesn't make it easy to start, stop and change audio settings (volume and output) on the fly, so you can create a shortcut for a manual start in your own context:
#disable the service
sudo systemctl disable snapclient.service
# create the icon
cat <<EOF > .local/share/applications/snapclient.desktop
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=SnapCast client
Exec=lxterminal --title="SnapCast client" --command="snapclient"
Terminal=false
Categories=AudioVideo;Player;Audio;Mixer
Comment=Start the SnapCast client
GenericName=Synchronised Audio Player
Icon=sound
Keywords=Player;snapclient;snapcast
EOF
If you have issues with audio volume, first check the log or command output to see
ServerSettings - buffer: 1000, latency: 0, volume: 100, muted: 0
which should not be muted - if in doubt also check the any multiroom volume control app you may have set up.
Otherwise try diagnosing using the pavucontrol
GUI audio settings app,
or using pactl
on the command line.
# find the current sink inputs
pactl list sink-inputs
# see which client is snap
pactl list short clients
# see full details
pactl list clients
### Install Prerequisites
# credit https://github.com/badaix/snapcast/blob/master/doc/build.md#macos-native
# 1. command line to for xcode tools
$ xcode-select --install
# accept when prompted to Install around 130 MB of command line dev tools
# 2. installed homebrew from http://brew.sh/
# 3. required libraries
$ brew install flac libsoxr libvorbis boost opus
### Obtain Source
# 4. load the source version you want
$ git clone https://github.com/badaix/snapcast/
# no longer using...
# git submodule update --init --recursive
$ cd snapcast/
$ git checkout develop
$ git branch -v
### Build Snapclient
$ cd client
$ make TARGET=MACOS
# this gave only one warning (macos support is experimental) and created:
# snapclient browseZeroConf player decoder
# and controller.o time_provider.o client_connection.o stream.o snapclient.o
$ sudo make install TARGET=MACOS
# echo macOS
# macOS
# install -s -g wheel -o root snapclient /usr/local/bin/snapclient
# install -g wheel -o root snapclient.1 /usr/local/share/man/man1/snapclient.1
# install -g wheel -o root etc/snapclient.plist /Library/LaunchAgents/de.badaix.snapcast.snapclient.plist
# launchctl load /Library/LaunchAgents/de.badaix.snapcast.snapclient.plist
Note that this installs the program as a launchd 'service' so you would control it using the following commands:
# suspend the service
launchctl unload /Library/LaunchAgents/de.badaix.snapcast.snapclient.plist
# rei
launchctl unload /Library/LaunchAgents/de.badaix.snapcast.snapclient.plist
see #macOS Snapclient diagnostics below for troubleshooting tips
Snapserver not only feeds audio streams to numerous synced clients, but it can also
- switch between multiple sources
- control master volume (as well as volume to specific clients)
In this way it is similar to an Audio Amplifier unit (an 'amp' in 1970s hifi terms) or an Audio Video Reciever (an 'AVR' in 2000's home cinema terms). Look for the #Volume controller section below - we will look at sources after some tech notes
Snapcast server reads PCM chunks from the named pipe /tmp/snapfifo, so can transmit any PCM audio you can send to this file.
The Snapcast transmissions use TCP port 1704, previously registered to IANA as bcs-broker, from knoware.nl. The developer still hopes to publish details of the Snapcast binary streaming protocol.
The Snapcast Control protocol uses TCP port 1705, previously registered to IANA as Slingshot, a financial market data feed protocol from the nineties. The developer has published the API details at https://github.com/badaix/snapcast/blob/master/doc/json_rpc_api/v2_0_0.md
Here are some suggested sources of audio input for snapcast:
- Spotify
- using the librespot free library,
- providing you have a paid Spotify subscription
- there are various packages using librespot, or you can compile using Rust Cargo
- using the librespot free library,
- Music Player Daemon
- the classic linux way to network your music uPnP style
- mpd package makes it easy to 'sink' your audio into snapcast's 'fifo pipe'
- mopidy wraps mpd and also makes it easy
- Bluetooth
- the easy way to throw audio from most devices
- the simplest way to make the back-end can vary
- now using custom combined auto-configure script for BlueZ + ALSA combo
- Airplay
- for your Apple (and compatible) devices
- Shairport-sync is a mature and packaged project
- cornrow works but has less docs and community power
Some audio players are installed as a service,
but it can be useful (where possible) to have sources
executed directly by Snapcast, so that it grabs
their audio output directly via stdout
.
The simplest way to connect to a spotify source is using the
excellent librespot
library, which is well-supported in snapserver.
Unfortunately for debian-based systems like RaspberryPi there
are no direct packages from the developers, but it is quite straightforward to build and install librespot using the rust cargo toolchain.
# use the recommended command to install the rust compiler and its package manager
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- when prompted, press Enter for default installation type
- that might take a while, then you continue
# source the environment into your current shell
. "$HOME/.cargo/env"
# install the dependencies recommended by librespot https://github.com/librespot-org/librespot
# (so also-sys build finds 'alsa.pc' and compiles without errors)
sudo apt install -y build-essential libasound2-dev cmake libclang-dev
# now get the librespot package and dependencies and compile them
cargo install librespot
# that command may take some time to download and compile over 300 individual crates
# finally, place the binary you just compiled into a common system path
sudo cp ~/.cargo/bin/librespot /usr/local/bin/
There were some tribulations behind getting that neat code - all the messing around is documented in Snacast issue #1035. The cmake and libclang-dev requirement came from 'ring' dependency 'aws-lc-sys' and from 'bindgen'. Other options were used previously, but they have now been moved below for posterity.
Spotify has deprecated password login, so we suggest you use the new Headless OAuth to authenticate your Spotify account.
sudo -u snapserver librespot --cache /var/lib/snapserver --enable-oauth --oauth-port 0
- copy the
Browse to:
url to into any browser from where you can access the Spotify account- You are asked to 'Allow Spotify', so click the button to 'Continue to the app'
- you WILL get a 'Connection Refused' error, which is fine :)
- now simply copy the entire url from your browser address bar and paste it back into the command line where prompted
Provide redirect URL
- now simply copy the entire url from your browser address bar and paste it back into the command line where prompted
- wait for the authentication to show in the command line
- CTRL C to break
- the credentials should now be in place with snapserver having access
- to check
sudo ls -la /var/lib/snapserver/
- to correct if not
sudo chown -R snapserver:snapserver /var/lib/snapserver
- to check
The Shairport-sync project now has debian packages, making it an easy install.
sudo apt install -y shairport-sync
# disable the service as snapcast runs the process itself
sudo systemctl disable --now shairport-sync
FOLDER_MUSIC=/path/to/Music/
FOLDER_PLAYLIST=/path/to/Playlists/
BONJOUR_NAME="My MPD Player"
### mpd
sudo apt install -y mpd
sudo cp /etc/mpd{,.old}.conf
sudo tee /etc/mpd.conf <<EOF!
music_directory "${FOLDER_MUSIC}"
#music_directory "/var/lib/mpd/music" # was default
playlist_directory "${FOLDER_PLAYLIST}"
#playlist_directory "/var/lib/mpd/playlists" # was default
user "mpd" # was default
#user "pi" # this failed as installed granted perms to user mpd
#bind_to_address "localhost" # was default
bind_to_address "any" # was default
#group "audio"
log_file "syslog"
#log_file "/var/log/mpd/mpd.log" # was default
#log_level "default"
db_file "/var/lib/mpd/tag_cache" # was default
pid_file "/run/mpd/pid" # was default
state_file "/var/lib/mpd/state" # was default
sticker_file "/var/lib/mpd/sticker.sql" # was default
zeroconf_enabled "yes"
zeroconf_name "${BONJOUR_NAME}"
#filesystem_charset "UTF-8" # was default
#id3v1_encoding "UTF-8" # was default
# snapcast help - https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#mpd
audio_output {
enabled "yes"
type "fifo"
name "${BONJOUR_NAME} MPD to Snapserver"
path "/tmp/snapMPDfifo"
format "48000:16:2"
mixer_type "software"
}
playlist_plugin {
name "m3u"
enabled "true"
}
EOF!
sudo systemctl restart mpd
#### Test mpd
# Now try to connect with a client.
# You may need to 'Refresh Database' before you see any content
Start by setting up the Bluetooth Audio Sink using the instruction block in Bluetooth audio sink # Legacy Rpi Audio Receiver. This makes it ready to receive sound to the internal headphone jack. Then you need to configure it to go to snapcast instead.
sudo tee -a /etc/modules <<EOF!
# add alsa loopback module for bluealsa-aplay to send bluetooth to snapcast
snd-aloop
EOF!
# direct the bluealsa sound into the loopback device
sudo sed -i.orig 's/--pcm=default/--pcm=plughw:0,0,0/' /etc/systemd/system/bluealsa-aplay.service
### Now set the source(s) you want in snapserver
sudo tee /etc/snapserver.conf <<EOF!
# help - https://github.com/badaix/snapcast/blob/master/doc/player_setup.md
# and - https://github.com/badaix/snapcast/blob/master/doc/configuration.md
# Name is what will appear when choosing the stream using snapcast API
[stream]
# when you send to device 0,0,0 it will loop back on the next device 0,1,0
# to hear a bluetooth stream appears to need a silence trigger
source = alsa://?name=Bluetooth&device=hw:0,1,0&silence_threshold_percent=0.1
EOF!
### and reboot ready to Test it out
sudo reboot 0
# you need to restart so the loopback device gets card #0
#### diagnostics
# list the alsa devices
aplay -l
# list the devices connected through bluetooth
bluealsa-aplay -l
SYSTEMD_PAGER=
service bluealsa-aplay status
service snapserver status
sudo service snapserver stop
snapserver --logging.filter debug
Previous configs used or tried
### Create and use a 'PCM.bluetooth' device
#
# this is an alternative to using --pcm=hw:0,0,0 in bluealsa-aplay
# https://github.com/badaix/snapcast/blob/master/doc/configuration.md#alsa
#
# see section needing debugging below
sudo sed -i.orig 's/--pcm=default/--pcm=bluetooth/' /etc/systemd/system/bluealsa-aplay.service
sudo tee /etc/asound.conf <<EOF!
# /etc/asound.conf
# systemwide equivalent of the per-user .asoundrc files
#
# This prepares the PCM settings going into the alsa loopback device
# credit https://github.com/badaix/snapcast/issues/379#issuecomment-830112664
#
# prefer this over the fifo pipe solution proposed in snapcast player docs
# https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#alsa
#
# with snd-aloop module pre-loaded the loopback device comes first
pcm.snd_card {
type hw
card 0
device 0
subdevice 0
}
ctl.snd_card {
type hw
card 0
device 0
subdevice 0
}
# this is the device we name in the bluesalsa-aplay command
pcm.bluetooth {
type plug
slave.pcm "snd_card"
}
EOF!
sudo tee /etc/asound.conf <<EOF!
# credit https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#alsa
pcm.!default {
type plug
slave.pcm rate48000Hz
}
pcm.rate48000Hz {
type rate
slave {
pcm writeFile # Direct to the plugin which will write to a file
format S16_LE
rate 48000
}
}
pcm.writeFile {
type file
slave.pcm null
file "/tmp/snapfifo"
format "raw"
}
# left the pipe path as this is the default in snapserver
# you should choose alternative names for other services in a multiple-source configuration
EOF!
sudo tee /etc/snapserver.conf <<EOF!
# help - https://github.com/badaix/snapcast/blob/master/doc/player_setup.md
# and - https://github.com/badaix/snapcast/blob/master/doc/configuration.md
# Name is what will appear when choosing the stream using snapcast API
[stream]
source = alsa://?name=Bluetooth&device=hw:0,1,0&silence_threshold_percent=0.2
source = pipe:///tmp/snapMPDfifo?name=MPD
source = airplay:///shairport-sync?name=Airplay&devicename=My%20Play%20TEST%20air&port=5050
source = spotify:///librespot?name=Spotify&username=myUserName&password=myPassWord&devicename=MyServer&bitrate=320&volume=40¶ms=--device-type%20avr
EOF!
For more help on configuring sources see https://github.com/badaix/snapcast/blob/master/doc/player_setup.md
# check the status
sudo service snapserver status
# stop for tests
sudo service snapserver stop
# test until you get it working
snapserver --logging.filter debug
# now restart the service
sudo service snapserver start
Cornrow has been suggested as a lightweight bluetooth (AND AirPort) sink. It defaults to using Alsa, but can also output an IP stream. https://github.com/badaix/snapcast/discussions/911
# help https://github.com/mincequi/cornrow
# check version https://github.com/mincequi/cornrow/releases/latest/
VERSION=0.8.1
wget https://github.com/mincequi/cornrow/releases/download/v${VERSION}/cornrowd_${VERSION}_armhf.deb
sudo apt install -y ./cornrowd_${VERSION}_armhf.deb
sudo systemctl unmask cornrowd.service
sudo systemctl enable cornrowd.service
sudo tee /etc/cornrowd.conf <<EOF!
# This is a TOML document.
[bluetooth_source]
codecs = [ 0x0 ] # As defined in the A2DP specification (SBC (0x0) is ma$
sample_rates = [ 44100, 48000 ]
#[airplay_source]
#name = "myAirplay"
# port = 0 # port to listen on (0 for auto select)
# buffer_time = 2000 # in ms (defaults to 2000ms)
#[alsa_sink]
#device = "default"
[tcp_sink]
host = "127.0.0.1"
port = 4953
EOF!
sudo systemctl start cornrowd.service
And added the following to /etc/snapcast.conf:
source = tcp://127.0.0.1:4953?name=Bluetooth&sampleformat=44100:16:2
It is very simple, and doesn't have much built-in logging or diagnostics, but you could diagnose Bluetooth issues with bluetoothctl
. Note that the cornrow package makes itself mutually exclusive with
NicoKaiser's RPi Audio Receiver was as turnkey as you could get. See Bluetooth audio sink # Rpi ready install if you want to know the rights and wrongs in choosing this solution. Or just use it...
wget https://raw.githubusercontent.com/artmg/rpi-audio-receiver/master/install-bluetooth.sh
sudo ./install-bluetooth.sh
Now you can add your source to the snapserver.conf [streams]
source = pipe:///tmp/snapBTfifo?name=Bluetooth
BLUETOOTH_DEVICE_NAME="My Bluetooth Sink"
# set pretty name
# credit https://github.com/artmg/lubuild/blob/master/help/diagnose/hardware.md#bluetooth-devices
sudo tee /etc/machine-info <<EOF!
PRETTY_HOSTNAME=${BLUETOOTH_DEVICE_NAME}
EOF!
If you get PIN/passkey errors it might be because previous connections are getting in the way. Try to run bluetoothctl
and list devices
, then specify the MAC addresses to remove
.
To diagnose issues with PulseAudio try pacmd list-sources
or pacmd list-sinks
If you want both snapserver and snapclient on the same device, and therefore need to configure ALSA in different ways for each, you could use a separate user with a .asoundrc file that sends the output to a special bluetooth pipe.
There is a very handy collection of install scripts for various different audio sources: bluetooth, airplay, spotify, upnp, etc
https://github.com/nicokaiser/rpi-audio-receiver
This installs most items as a service,
however we want Bluetooth and Spotify to be
executed directly by Snapcast so that it grabs
the audio from those sources via stdout
.
However we are currently using our own fork, whilst waiting for upstream PR to be accepted, to allow Shairport variables before reverting to upstream.
Update PR now accepted, use upstream instead
sudo apt install -y git
git clone https://github.com/artmg/rpi-audio-receiver.git
cd rpi-audio-receiver
# for latest release see https://github.com/mikebrady/shairport-sync/releases
export SHAIRPORT_VERSION=3.3.5
# make sure Shairport install will run with alternative settings
export SHAIRPORT_CONFIGURE="--with-stdout --with-metadata --with-avahi --with-ssl=openssl --with-soxr"
./install.sh
- Say yes to run bluetooth script
- configure
asound.conf
following https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#alsa
NB: If you later wish to alter the 'pretty name' that Bluetooth announces, then see https://github.com/artmg/lubuild/blob/master/help/diagnose/hardware.md#bluetooth-devices
# not sure this is needed any more
# sudo usermod -a -G pulse-access shairport-sync
# disable the service as snapcast runs the process itself
sudo systemctl disable --now shairport-sync
(if it needs Pulse audio then see the config option output_backend = "pa";
)
sudo tee -a /etc/snapserver.conf <<EOF!
# help - https://github.com/badaix/snapcast/blob/master/doc/player_setup.md
# Name is what will appear when choosing the stream using snapcast API
[stream]
source = pipe:///tmp/snapfifo?name=Bluetooth
source = pipe:///tmp/snapMPDfifo?name=MPD
source = airplay:///shairport-sync?name=Airplay&devicename=Kitchen%20sink%20airplay&port=5050
source = spotify:///librespot?name=Spotify&username=userIdNotEmail&password=NotSureHowToEncodeSpecialChars&devicename=MyAudioIn&bitrate=320
EOF!
Many articles propose Raspotify as a 'thin wrapper' around librespot, to run it as a daemon, but we don't actually need that (as snapcast runs it).
One pre-compiled package for vanilla librespot is the snap package librespot-dev
# if you have not installed `snapd`
# see https://snapcraft.io/install/librespot-dev/raspbian
sudo snap install librespot-dev
you would then need to address snapcast.conf to the location of the snap executable:
source = librespot:///snap/librespot-dev/current/bin/librespot?name=Spotify&username=myuser&password=mypass&devicename=Spotify%20for%20Sanpcast&bitrate=320
The issue with this is that librespot-dev package still appears to be version 0.2 from 2021
- say No to install script
- do not use rpi-audio-receiver version
- that installs spotifyd as a service
- we want to run librespot from snapserver
- For now we use https://github.com/dtcooper/raspotify/
- we might consider using the cargo package
wget https://dtcooper.github.io/raspotify/raspotify-latest.deb
sudo dpkg -i raspotify-latest.deb
sudo apt-get -f install
sudo systemctl disable --now raspotify # disable the service as snapcast runs the process itself
- configure options via
/etc/default/raspotify
- including any command line options for librespot
- https://github.com/dtcooper/raspotify#configuration
- other help:
- config snippets and how to log librespot events
- stream syntax https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#spotify
- snapcast issue resolution https://github.com/badaix/snapcast/issues/425
- other use https://github.com/djmaze/librespot-snapserver
After the server install the following is in /etc/mpd.conf
# Audio Output ################################################################
audio_output {
type "alsa"
name "alsa"
device "hw:0,0"
}
audio_output {
type "fifo"
enabled "no"
name "multiroom"
path "/tmp/snapfifo"
format "44100:16:2"
}
editor /etc/mpd.conf
- Set
enabled "yes"
- should alsa section be commented out?
- set format to
48000:16:2
- this dramatically reduces dropouts by avoiding resampling
- try
mixer_type "software"
- this allows you to control master volume with MPD
- does not appear to control it with volumio web interface
- sync and reboot
For more help see
For snapcast Bluetooth sources:
- Bluetooth as snapserver source via pulse /tmp/fifobt
- User context issues with bluealsa
See more for using Bluetooth A2DP as a source in Bluetooth-audio-sink
- consider removing audio in
boot.txt
withdtparam=audio=off
- if integrating into single implementation consider snapcastc https://github.com/christf/snapcastc
Here's an example config for snapcast, but the PulseAudio configuration was not complete
#wget https://raw.githubusercontent.com/nicokaiser/rpi-audio-receiver/main/install-bluetooth.sh
#sudo ./install-bluetooth.sh
# additional pulse config for snapserver
# credit https://github.com/badaix/snapcast/blob/master/doc/player_setup.md#pulseaudio
sudo tee -a /etc/pulse/default.pa <<EOF!
load-module module-pipe-sink file=/tmp/snapBTfifo sink_name=SnapcastBT format=s16le rate=48000
update-sink-proplist Snapcast device.description=Snapcast
EOF!
Although these solutions can provide snapserver with a bluetooth A2DP source as an input, would it be feasible to automatically switch sources?
How could we satisfy the following use case:
- play an MPD-controlled source by default
- accept incoming bluetooth A2DP connections
- automatically switch snapserver over to the BT when connected
- automatically revert to the MPD source when disconnected
- could MPD player status be used in the logic (e.g. do not switch to BT Sink when MPD is playing)
If you get no audio on clients, check server status quickly via Android app
Log onto server and check with sudo service snapserver status
If you are not sure what is happening, or whether your conf file is even valid, stop
the service and run the server in command line diagnostic mode:
snapserver --logging.filter debug
For clients use snapclient
for both the service and the debug mode.
which snapclient
snapclient --version
snapclient --help
sudo launchctl unload /Library/LaunchAgents/de.badaix.snapcast.snapclient.plist
snapclient
snapclient --logfilter *:debug
if that doesn't stop the service use
ps -a | grep snap
sudo launchctl list | grep snap
sudo launchctl remove de.badaix.snapcast.snapclient
Now you will be able to see the detailed Info logs on the console
# this DOESN'T show much
log show --style syslog --predicate 'senderImagePath contains[cd] "snap"' --info --last 48h
Snapcast has an API for balancing the volume between different 'rooms' playing snap streams.
There is a simple and quick Android client. Thanks to the efforts of other developers, badaix has integrated their APK generation upstream to create the Play Store app:
https://play.google.com/store/apps/details?id=de.badaix.snapcast
As well as for tweaking volume and listening, this can be a useful tool for diagnosing the status of Snapcast deployment on your network.
Note that you also appear to be able to create groups and add members with this app. Not sure where else this can be done.
See https://github.com/artmg/MuGammaPi/wiki/home-automation
This easy to use plug in scans as startup to find all snapclients in your network and for each one it allows you to control volume, mute and source.
It also finds any defined groups, and allows you to control them in the same way, although I have not yet found if it can also manage group memberships.
For this Dancer2 application, written in perl, ready to be deployed onto volumio's plack web engine, see Volumio and MPD
As well as the sound sources above, including Spotify, here are some integrations with other audio players.
For Volumio instructions see:
- [https://volumio.org/forum/multiroom-audio-output-from-volumio-with-snapcast-t3217.html]
- [https://volumio.org/forum/how-get-multi-room-sync-audio-working-t4685.html]
- although the logical requests have been made
- e.g. [https://discourse.osmc.tv/t/multiroom-audio-via-snapcast/16836]
- the limitation on Snapcast with Kodi is that it's linux only
- [http://forum.kodi.tv/archive/index.php?thread-285516.html]
This is a build with MPD and snapcast
#### Base OS install
MEDIA_DEVICE=sdbX
MEDIA_LABEL=mySDcard
IMAGE_FILENAME=/path/to/ArchLinuxARM-rpi-2-latest.tar.gz
NEWHOSTNAME=myHostname
USER_NAME=mpd
USER_GROUP=mpd
USER_DESC="Music Player Daemon"
USER_PWD=secret
ROOT_PWD=stronger
# NB: Wired Ethernet for now!
# follow instructions in [https://github.com/artmg/MuGammaPi/wiki/arch-linux-install]
#### Audio hardware
sudo pacman -S alsa-utils
# for changes to /boot/config.txt see
# [https://archlinuxarm.org/wiki/Raspberry_Pi]
sudo tee -a /boot/config.txt <<EOF!
dtparam=audio=on
## If you experience distortion using the 3.5mm analogue output:
#audio_pwm_mode=2
EOF!
# if you have a DAC you may need further changes, see
# [https://github.com/artmg/MuGammaPi/wiki/Audio-Hub#dac-drivers]
# NB DACs use I2S (streaming, fire and forget) NOT I2C (Command)
#### Install Music software
##### MPD, ympd - not currently adding upmpdcli
sudo pacman -S mpd
sudo pacman -S ympd
sudo pacman -S nfs-utils
PACKAGE_NAME=snapcast
# see [https://github.com/artmg/MuGammaPi/wiki/arch-linux-install#aur-packages]
sudo systemctl enable mpd
sudo systemctl enable ympd
sudo systemctl enable snapserver
sudo systemctl enable snapclient
#### configure
##### nfs
# NB instead of using FQDN either
# a) work out why DHCP client does not pick up suffix
# b) add suffix e.g. via /etc/dhcpcd.conf with `option domain-name "domain1.com";`
# nfs variables
NFS_SERVER=MyNAS.fqdn
NFS_EXPORT=Music
LOCAL_MOUNT=NasMus
# credit [https://github.com/artmg/lubuild/blob/master/help/configure/Networked-Services.md#nfs]
sudo mkdir -p /mnt/nfs/$LOCAL_MOUNT
cat <<EOF | sudo tee -a /etc/fstab
$NFS_SERVER:/srv/exports/$NFS_EXPORT /mnt/nfs/$LOCAL_MOUNT nfs defaults,timeo=14,soft 0 0
EOF
# arch alternative - no export root and additional options
# $NFS_SERVER:/$NFS_EXPORT /mnt/nfs/$LOCAL_MOUNT nfs rsize=8192,wsize=8192,timeo=14,_netdev 0 0
NFS_SERVER=MyNAS.fqdn
NFS_EXPORT=PlayRw
LOCAL_MOUNT=NasPlayRw
### snapcast
cat <<EOF! | sudo tee /etc/default/snapclient
# defaults from installed /etc/default/snapclient file
START_SNAPCLIENT=true
USER_OPTS="--user snapclient:audio"
# run sudo snapclient --help to see options available
# and sudo snapclient --list to see PCM devices for soundcard option
SNAPCLIENT_OPTS="--soundcard 1 --host $NEWHOSTNAME"
EOF!
##### mpd
sudo mkdir -p /var/lib/mpd/
# to use user mpd...
sudo touch /var/log/mpd.log
sudo chown mpd.mpd /var/log/mpd.log
sudo gpasswd -a mpd audio
cat <<EOF! | sudo tee /etc/mpd.conf
# /etc/mpd.conf uses spaces NOT tabs
user "mpd"
# defaults from installed /etc/mpd.conf
pid_file "/run/mpd/mpd.pid"
db_file "/var/lib/mpd/mpd.db"
state_file "/var/lib/mpd/mpdstate"
# ready for debugging
#log_file "/var/log/mpd.log"
# local locations
music_directory "/mnt/nfs/NasMus/Music/"
playlist_directory "/mnt/nfs/NasPlayRw/Playlists/"
# snapcast server integration
audio_output {
type "fifo"
enabled "yes"
name "my multiroom (snapcast)"
path "/tmp/snapfifo"
format "48000:16:2"
mixer_type "software"
}
## test direct to alsa in case of issues
#audio_output {
# type "alsa"
# name "Default Audio Device"
## device "bcm2835"
# mixer_type "software"
#}
playlist_plugin {
name "m3u"
enabled "true"
}
EOF!
## later if required ...
sudo pacman -S upmpdcli
sudo systemctl enable upmpdcli
See also:
- tips and tricks from Archphile [http://archphile.org/howto/mpd-configuration]
- list of roll your own software & config [http://krazedkrish.com/blog/2017/01/04/diy-music-server-with-archlinux-raspbery-pi-or-anywhere/]
- Arch wiki on MPD [https://wiki.archlinux.org/index.php/Music_Player_Daemon]
#### mpd errors
# check card name & device
sudo aplay --list-pcms
#### snapclient issues
# check devices
sudo snapclient --list
sudo snapclient -s 1 -h myHostname
#### silence
# devices muted by default
sudo amixer sset PCM unmute
# set output device
sudo amixer cset numid=3 1
# 0 for Auto
# 1 for Analog out
# 2 for HDMI
# set volume level high
sudo amixer cset numid=2 1
# -10000 = MIN, 400 = MAX, 0 = MUTE
# test with pink noise output
sudo speaker-test -c 2
# check current settings
sudo amixer contents
# set manually
sudo alsamixer