Skip to content

Instantly share code, notes, and snippets.

@bmweiner
Last active December 30, 2023 19:30
Show Gist options
  • Star 32 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmweiner/f80e7aaeca5bcee1db46e56914b415fa to your computer and use it in GitHub Desktop.
Save bmweiner/f80e7aaeca5bcee1db46e56914b415fa to your computer and use it in GitHub Desktop.
Stream audio to any Sonos component via AirPlay using a Raspberry Pi.

Sonos Airplay

Stream audio to any Sonos component via AirPlay using a Raspberry Pi (Model B, Raspbian Jessie) and the following software:

  • Shairport Sync: configures the Raspberry Pi as an AirPlay audio player.
  • DarkIce: encodes audio received from AirPlay (system audio) and sends it to Icecast2.
  • Icecast2: serves streaming audio from DarkIce at a network URL.

Raspberry Pi Setup

Alsa Loopback 1

Create a loopback device to capture system audio.

sudo modprobe snd-aloop

Persist by adding the following to /etc/modules:

snd-aloop

Note: use aplay -l to see playback devices.

Shairport Sync

Install:

Note: this method uses stow, to symlink files installed to /usr/local/stow/shairport-sync.

cd /usr/src
git clone https://github.com/mikebrady/shairport-sync.git
cd shairport-sync
sudo apt-get install build-essential autoconf automake libtool \
                     libdaemon-dev libasound2-dev libpopt-dev \
                     libconfig-dev avahi-daemon libavahi-client-dev \
                     libssl-dev libsoxr-dev
autoreconf -i -f
./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata \
            --with-soxr --with-systemd --prefix=/usr/local
make PREFIX=/usr/local
sudo make install prefix=/usr/local/stow/shairport-sync
cd /usr/local/stow
sudo stow shairport-sync

Edit /lib/systemd/system/shairport-sync.service to comment out the User/Group lines (creating this user and group was not needed):

;User=shairport-sync
;Group=shairport-sync

Edit /etc/shairport-sync.conf:

Note: set interpolation to basic to reduce cpu load.

general = {
  name = "Sonos";
  interpolation = "soxr";
};

Start and persist on reboot:

sudo systemctl start shairport-sync.service
sudo systemctl enable shairport-sync.service

Icecast2

Install:

sudo apt-get install icecast2

Edit /etc/icecast2/icecast.xml to reduce latency:

<limits>
    <burst-on-connect>0</burst-on-connect>
    <burst-size>0</burst-size>
</limits>

Start and persist on reboot:

sudo systemctl start icecast2
sudo systemctl enable icecast2

DarkIce

Install:

sudo apt-get install darkice

Create and add the following to /etc/darkice.cfg:

# see the darkice.cfg man page for details

[general]
duration        = 0
bufferSecs      = 1
reconnect       = yes
realtime        = yes
rtprio          = 3

[input]
device          = hw:Loopback,1,0
sampleRate      = 44100
bitsPerSample   = 16
channel         = 2

[icecast2-0]
bitrateMode     = vbr
format          = mp3
quality         = 0.8
server          = localhost
port            = 8000
password        = <pwd>
mountPoint      = sonos
name            = sonos

Create and edit /etc/systemd/system/darkice.service:

[Unit]
Description=DarkIce Live audio streamer
After=icecast2.service

[Service]
ExecStart=/usr/bin/darkice

[Install]
WantedBy=multi-user.target

start, and persist on reboot:

sudo systemctl daemon-reload
sudo systemctl start darkice.service
sudo systemctl enable darkice.service

Sonos Controller

Download the Sonos Desktop Controller

Add the icecast2 streaming URL (http://<ip_addr>:8000/sonos.m3u) via the Sonos Desktop Controller

Play Music

  1. Reboot the Raspberry Pi
  2. Play music to the 'Sonos' AirPlay controller (Raspberry Pi)
  3. Connect the Sonos zone(s) to the stream via My Radio Stations in TuneIn

Sources

[1] https://www.raspberrypi.org/forums/viewtopic.php?t=98987&p=695967

@mikebrady
Copy link

Hi there. Thanks for the interesting use of Shairport Sync.

Reading the whole guide, it seem to me that the instructions for installing Shairport Sync are unnecessarily complicated. Unless I am mistaken, a standard (up-to-date) installation of Shairport Sync, such as described here, would be perfect for this and easier to maintain in future. Moreover, there are a few issues with your guide:

  1. There is no need to keep the source files and build directory around (in /usr/src) after installation – they can safely be deleted. In fact, the whole build process could be done in a regular user's home directory and then deleted after installation.
  2. libdaemon is not needed for a systemd-based system.
  3. By default, Shairport Sync installs four or five files – the executable, a man file, a service description file, a configuration sample file and possibly a configuration file, so I'd have thought that using stow is overkill. It certainly makes ongoing updates of Shairport Sync more complicated.
  4. Changing the service file as suggested has the effect of running the shairport-sync daemon as root user rather than as the more restricted shairport-sync user, which is probably undesirable and certainly unnecessary. The shairport-sync user and group are created anyway at the # make install step.

@michaelkrog
Copy link

If the goal is to use airplay with Sonos, then https://github.com/philippe44/AirConnect is an easier pick.
One binary, start it, go!

@salimhb
Copy link

salimhb commented Aug 20, 2022

Thanks for the guide, I used this to stream to Echo devices using http://mymediaalexa.com/home/multiroom
One extra step that is not mentioned here and I had to do for my setup is to set the output_device in /etc/shairport-sync.conf to use the loopback. This is how my configuration looks like:

general =
{
    interpolation = "basic";
};
alsa =
{
    output_device = "hw:Loopback";
    mixer_control_name = "PCM";
};

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