Skip to content

Instantly share code, notes, and snippets.

@totti2
Last active July 27, 2023 08:41
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save totti2/41ed90feb1eb5838cc6a789d2b2dd5a7 to your computer and use it in GitHub Desktop.
Save totti2/41ed90feb1eb5838cc6a789d2b2dd5a7 to your computer and use it in GitHub Desktop.
Synchronous multi-room sound casting of Bluetooth, Airplay, Line-In and Spotitfy

Synchronous multi-room sound casting of Bluetooth, Airplay, Line-In and Spotitfy

ALL CREDITS TO @badaix AND @BaReinhard

This will setup a raspberry-pi-3 as a snapcast-server and snapcast-client.
Possible music sources for the snapserver-component: Bluetooth, Airplay, Spotify, Line-In (more to come eg. RTP)
Music sinks (snapclients): usb soundcard connected to my stereo, another Pi

To Do:

  • Energy saving by disabling onboard bluetooth, wifi and soundcard

SYSTEM ENVIRONMENT

TIMEZONE, MEMORYSPLIT, EXPAND FILESYSTEM

sudo raspi-config

PREPARE, INSTALL AND CONFIGURE BLUTOOTH AND AIRPLAY FUNCTIONALITY (SSRPARI)

sudo apt update
sudo apt upgrade
sudo apt install git 
git clone https://github.com/BaReinhard/Super-Simple-Raspberry-Pi-Audio-Receiver-Install.git
cd Super-Simple-Raspberry-Pi-Audio-Receiver-Install/
sudo ./install.sh
#   Do you want to install SnapCast? (y/n): n
#   Do you want AirPlay Enabled? (y/n) : y
#   Do you want Bluetooth A2DP Enabled? (y/n) : y
#   Do you want to setup as an Access Point? (Necessary for AirPlay, in location without a Wireless Network) (y/n) : n
#   Do you want Kodi installed? (y/n) : n
#   Do you want to use infrared remotes? (y/n) : n
#   Do you want to use a Sound Card? (y/n) : y
#   Do you want to setup device as a UPnP Renderer? (y/n) : n
#   Do you want all the Devices to use the same name? (y/n) : y
#   Device name: MultiPi
#   Do you want to use an AirPlay password? (y/n) : n
#   (...)
#   9. USB Sound Card
#   (...)
#   Which Sound Card are you using? (0/1/2/3/4/5/6/7/8/9/10/11) :  9

DOWNLOAD, INSTALL SNAPCAST-SERVER AND CORRECT ITS DEPENDENCIES

wget https://github.com/badaix/snapcast/releases/download/v0.15.0/snapserver_0.15.0_armhf.deb
sudo dpkg -i snapserver_0.15.0_armhf.deb
sudo apt-get -f install

DOWNLOAD, INSTALL AND CONFIGURE SNAPCLIENT

wget https://github.com/badaix/snapcast/releases/download/v0.15.0/snapclient_0.15.0_armhf.deb
sudo dpkg -i snapclient_0.15.0_armhf.deb
#   LIST SOUNDCARDS
snapclient --list
#   CONFIGURE SNAPCLIENT
sudo nano /etc/default/snapclient
#   EDIT SNAPCLIENT_OPTS=""
#   -h <HOST> -s <SOUNDCARD> -d <DAEMONIZE>
#   SNAPCLIENT_OPTS="-h localhost -s 25 -d"
sudo systemctl restart snapclient.service

Add Bluetooth

# CREATE SNAPCAST-STREAM = NEW PULSEAUDIO-SINK
sudo nano /etc/default/snapserver	
#   EDIT
#   #SNAPSERVER_OPTS=""
#   SNAPSERVER_OPTS="-d -b 250 --sampleformat 48000:16:2 -s pipe:///tmp/snap_blue?name=Bluetooth&sampleformat=44100:16:2&mode=read"

#   CREATE SYSTEMWIDE PULSEAUDIO-PIPE-SINK
sudo nano /etc/pulse/system.pa
#   APPEND
#   load-module module-pipe-sink file=/tmp/snap_blue sink_name=bluetooth

# ASSIGN SINK TO [Bluetooth-Sources](https://github.com/BaReinhard/Super-Simple-Raspberry-Pi-Audio-Receiver-Install/issues/6#issuecomment-284573272)
sudo nano /usr/local/bin/bluez-udev
# EDIT
# #audio_sink=0
# audio_sink=1
sudo reboot

BUILD, CONFIGURE LIBRESPOT

sudo apt-get install build-essential portaudio19-dev git
curl https://sh.rustup.rs -sSf | sh
sudo reboot
git clone https://github.com/librespot-org/librespot.git
cd librespot/
cargo build --release
$PATH
sudo cp target/release/librespot /usr/bin
#   CREATE SNAPCAST-STREAM
sudo nano /etc/default/snapserver 
#   APPEND
#   SNAPSERVER_OPTS="  ... -s spotify:///librespot?name=Spotify&username=username&password=yourpassword&devicename=SpotiPI&bitrate=320  ...  "
sudo systemctl restart snapserver.service

BUILD, EDIT AND ENABLE CPIPED FOR LINE-IN AUDIO

git clone https://github.com/b-fitzpatrick/cpiped.git
cd cpiped/
make
sudo cp cpiped /usr/local/bin/
#   FIND CAPTURE DEVICE/LINE-IN 
arecord -L
nano scripts/init.d/cpiped
#   EDIT DAEMON-VARIABLES
#   DAEMON=/usr/local/bin/cpiped   # LOCATION OF THE BINARY
#   DAEMON_ARGS="-D -d sysdefault:CARD=Set /tmp/snap_jack"  # LOCATION OF THE PIPE
sudo cp cpiped /etc/init.d/
sudo chmod +x /etc/init.d/cpiped
sudo systemctl enable cpiped
sudo systemctl start cpiped
#   CREATE SNAPCAST-STREAM
sudo nano /etc/default/snapserver 
#   EDIT
#   #SNAPSERVER_OPTS=""
#   SNAPSERVER_OPTS="-d -b 250 --sampleformat 44100:16:2 -s pipe:///tmp/snap_jack?name=Jack&sampleformat=44100:16:2 -s pipe:///tmp/snap_blue?name=Bluetooth&mode=read&sampleformat=44100:16:2 -s spotify:///librespot?name=Spotify&username=username&password=yourpassword&devicename=SpotiPI&bitrate=320"

CONFIGURE AIRPLAY

#   CREATE SNAPCAST-STREAM
sudo nano /etc/default/snapserver 
#   APPEND
#   SNAPSERVER_OPTS="  ...  -s airplay:///shairport-sync?name=Airplay&devicename=MultiPi&port=5000  ...  "
sudo systemctl disable shaiport-sync 
sudo nano /etc/shairport-sync.conf
#   EDIT
#   //output_backend = "alsa"; 
#   output_backend = "stdout"; 
@BaReinhard
Copy link

This is great! I haven't messed much with snapserver or client and I wasn't aware of being able to simply dpkg the snapclient binary. Nor was I aware of the config files.

@BaReinhard
Copy link

I added a good deal of this to the new multi-exec brach of https://github.com/bareinhard/super-simple-raspberry-pi-audio-receiver-install
I have now switched to downloading the .deb files and dpkging them instead of a full compiling (saves a lot of time). Also used some of the configuration for the snapservers.

I found that changing the shairport-sync.service ExecStart to ExecStart=/usr/local/bin/shairport-sync -o pipe -- /tmp/snap_blue, allowed for reliable Shairport-sync streaming to the pipe. For whatever reason the config file just didn't work with pipe output. (Maybe user error). Although I didnt use librespot just because of the extended amount of time it took to configure, I will eventually add it as an option. (Possibly tonight). All in all good work, and thanks for the walkthrough. Ill be putting your name in the contrib file since you provided pretty much all of the work for this.

@totti2
Copy link
Author

totti2 commented Dec 22, 2017

Damn, you're fast!
My pleasure! And thanks for mentioning!

Please see my ideas regarding client-configuration in the snapcast support issue.

I don't know, if the compilation of librespot is absolutely necessary. Maybe there's a prebuilt binary somewhere, I haven't been looking too hard.

@totti2
Copy link
Author

totti2 commented Feb 5, 2018

updated:
Line-In support with cpiped
Airplay with using the shairport-sync binary (NEEDS TESTING, I wanna try the daemon approach)

Disabling onboard-sound in /boot/config.txt brought me issues with the pulseaudio-modules module-udev-detect and module-detect saying no sound-hardware found in sudo systemctl status pulseaudio

@totti2
Copy link
Author

totti2 commented Feb 18, 2018

snapcast launches the shaiport-sync binary itself with the option s airplay:///shairport-sync ... causing troubles with the shairport-sync-daemon that's already running (SSRPARI configured it to run as daemon)
so either choose sticking with the SSRPARI-approach and configure the daemon to pipe into a file and add the airplay-sounds to a -s pipe:///tmp/snap_... with the output_backend=pipe in /etc/shaiport-sync.conf
OR
sudo systemctl disable shairport-sync and choose output_backend=stdout in /etc/shaiport-sync.conf and let snapcast launch it for itself.

@totti2
Copy link
Author

totti2 commented Apr 2, 2018

switched to librespot-org
switched to snapcast_v13

@totti2
Copy link
Author

totti2 commented Jul 19, 2018

switched to snapcast_v15

@dmckminard
Copy link

I followed your tutorial, but I can not run cpiped and a blueototh audio source (via pulseaudio) at the same time. Can we have multiple simultaneous entries with snapcast?

@GMFalka
Copy link

GMFalka commented Mar 17, 2019

Hello! Great write-up!

Can i ask for some assistance with cpiped?

All is working with this cli command (for about a day, then i need to restart):
/usr/local/bin/cpiped -D -d pulse /tmp/snapfifo

The init.d script doesnt work. Heres the error msg:
cpiped: pcm.c:1245: snd_pcm_drain: Assertion 'pcm' failed.

Another thing i tried is:

~$ /usr/local/bin/cpiped -D -d sysdefault:CARD=PCH /tmp/snapfifo
~$ ALSA lib pcm_dsnoop.c:618:(snd_pcm_dsnoop_open) unable to open slave

@rwjack
Copy link

rwjack commented Jul 20, 2023

Before I buy an airplay speaker, I'm trying to figure out if it's possible to stream from snapserver (librespot), to both multiple snapclients and airplay clients, at the same time.

Does anyone know?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment