Party mode audio with snapcast
I recently moved house and hosted a NYE party. It’s a small townhouse so I wanted to make the most of the available room by hosting both inside and outside. Naturally, I wanted to play music - both inside and outside - and without blasting music incredibly loud from inside.
The solution is ‘multiroom audio’ - placing speakers in both spaces and playing from a single source. This is easily done ‘analog’, by running a bunch of speaker wires to speakers from a central amp, but that’s a little too permanent and it’s much cooler and more flexible to do it wirelessly with some clever software.
Enter snapcast, a client-server multiroom audio solution. The server acts as the central audio source and it streams audio over TCP to any number of snapcast clients, of which there are a few implementations. The snapcast protocol involves the client and server continuously exchanging timing information and the client will subtly speed or slow audio playback to remain in sync with the server and, by extension, the other clients. Of course, there are differing latencies downstream of the clients that can’t be automatically accounted for, so there is additionally a manual fixed-latency offset you can configure per-client to get the perfect sync between them all.
The hardware
I use an Nvidia Shield for playing media on my TV, so it was simple enough to install and use the snapdroid android client in the living area. For outside, I wanted a portable solution I could store inside when not in use. I bought a well-reviewed portable bluetooth speaker, importantly this one has aux-in. The snapcast client for this speaker was hosted on a Raspberry Pi Zero 2 W, which has WiFi and is very easy to deploy to, but notably doesn’t have aux-out. Pimoroni produce a cool low-profile DAC hat, which adds a 3.5mm aux-out. Finally, to make the whole thing wireless, I bought the PiSugar 3 battery to power the Pi. I strongly considered taking apart the bluetooth speaker and trying to piggy-back off of its battery, but decided it was too much hassle in the end. Here are the 3 boards laid out:

The DAC hat pushes on top of the GPIO pins and the battery charging board gets screwed in and presses on their underside. The two add-on boards don’t interfere at all and there’s no soldering required! It’s a pretty neat design from PiSugar - they’re very deliberately leaving the top of the GPIO pins free for other hats. The board has little spring-loaded sockets that press against the back of the GPIO pins protruding through the underside of the Pi. Here’s a close-up of said sockets:
and how they push onto the back of the Pi:
and the whole assembly:
Not quite the IPX7 rating of the speaker it’s connected to… but I was surprised at how plug-and-play all these little boards were.
The software
On my server I’m running the sweisgerber/docker-snapcast image, which bundles librespot for Spotify playback. librespot acts as a ‘Spotify Connect’ receiver, so it broadcasts itself on the local network and appears as an available receiver in the Spotify app.
The Raspberry Pi just runs Raspberry Pi OS (debian) and so I simply install the latest snapclient
.deb release, which installs a systemd
service that automatically starts the client on boot. Finally, as written on the DAC’s product page,
it is set as the Pi’s default ALSA device by specifying: dtoverlay=hifiberry-dac in
/boot/config.txt.
That’s pretty much all there is - it’s a very neat solution - I can play music from Spotify, in sync, to both clients and it’s no harder than casting to any TV or bluetooth speaker. Of course, none of this was actually prepared in time for my party… maybe the next one.
Here’s the speaker with the player connected:

The only remaining thing was for me to spend an evening shuffling myself between the TV and bluetooth speaker while playing metronome tracks to calibrate the perfect sync. Artist’s rendition:
| __ __
| o/o/ O o/o/ (o_
D) <-- /|\ --> | |
| | | ,---' |
|_| / \ |______|
-Nath