If you’re like me, you have tons of music on your computer but usually end up listening to it on headphones. If you want to use real speakers, you either run an audio cable to your stereo (tripping hazard, low-quality sound) or drag out an audio interface ($$, lots of cables). Bluetooth is an option, but the sound quality is ok at best. Apple’s Airplay goes over wifi and gives much higher-quality audio, but you’ll need some way to get that signal to your receiver or amplifier. There are lots of options on the market, but if you have a Raspberry Pi lying around, it makes a great and very cheap solution!
I decided to use the HDMI out for audio, which gives way better quality, and to include a power button and LED inside a nice laser-cut case. So far, it’s worked great for music as well as movies and podcasts!
Note: This tutorial assumes you have some experience setting up Raspberry Pi boards and working with the terminal. Some of the basic setup is covered below but if it’s confusing, I’d suggest starting with some intro tutorials first.
WHAT YOU’LL NEED
At a minimum, you’ll need the following:
- Raspberry Pi (pretty much any model with wifi will work)
- Power supply
- SD card (a small one is fine, since we’ll be installing the “light” version of Raspbian and little else)
- HDMI cable (preferably) or 3.5mm (1/8″) audio cable
- Stereo receiver and speaker
To make your Airplay receiver work even better, you’ll probably also want to add:
- A case for your RPi, such as this lasercut one I’ve designed (which is based on this one from DIY Electronics) that includes a hole for a power button
- Momentary switch for a power button
- LED power indicator and 330ohm resistor
- Some rubber feet for the bottom
WHY NOT USE THE 3.5MM AUDIO OUT?
While it seems like the easiest thing to do would be to just use the 3.5mm (or 1/8″, if you’re in the US) audio output built into the RPi, for whatever reason the audio quality is notably poopy. Since Airplay is already giving us much higher fidelity audio than Bluetooth, why kill that quality boost before it even gets to the speakers?
The HDMI audio output, on the other hand, is super great on the RPi. If you have a receiver that can take HDMI, even if you’re like me and don’t have a TV, by all means use that!
Another option is an add-on DAC for your RPi, which skips both audio outputs. If you’re interested in that, I’d suggest reading this article.
DOWNLOAD AND INSTALL THE OPERATING SYSTEM
Go to the Raspberry Pi website and download the Raspbian Lite image (the version as of writing this is Buster). Copy the OS image to your SD card using a program like Etcher.
Then do your basic configurations using raspi-config :
1 |
sudo raspi-config |
- Change your password!
- Network options:
- Change your hostname to something you’ll remember (this is what shows up when you connect your computer or phone) – I named mine StereoSystem
- Connect to your wifi network
- Boot options:
- Change to Desktop/CLI to Console Autologin so we can run headless (without a monitor or keyboard)
- Change any localization settings you need, like keyboard and timezone
- Interfacing options:
- Turn on SSH (so you can remotely change things from your computer)
- Advanced options:
- Run Expand Filesystem to make extra room on the SD card – not necessary but helpful if you wanted to add other stuff later
- Change the audio to force HDMI (recommended) or 3.5mm, depending on which you plan to use
You’ll likely need to reboot your RPi at least once during this process!
INSTALL SHAIRPORT-SYNC
The core tool that we’ll be using is shairport-sync , which turns your RPi into an Airplay server. It’s maintained by Mike Brady, whose Github page for the project includes tons of info on Airplay and advanced settings.
First, we have to install some dependencies:
1 2 |
sudo apt-get update sudo apt-get install autoconf automake avahi-daemon build-essential git libasound2-dev libavahi-client-dev libconfig-dev libdaemon-dev libpopt-dev libssl-dev libtool xmltoman |
Then we download and install shairport-sync from Github:
1 |
git clone https://github.com/mikebrady/shairport-sync.git |
1 2 3 |
cd shairport-sync autoreconf -i -f ./configure --with-alsa --with-avahi --with-ssl=openssl --with-systemd --with-metadata |
1 2 |
make sudo make install |
With that done, we can activate the Airplay server:
1 |
sudo service shairport-sync start |
Check your computer or phone and see if StereoSystem (or whatever you named your device) is showing up as an audio output device. Nice!
CHANGE THE SYSTEM VOLUME
The default audio level on the RPi is super low, so you’ll probably want to set it to the max:
1 |
amixer sset PCM,0 100% |
You can read more about amixer and it’s settings in this article.
HOOK UP AND TEST!
Now we’re ready to hear some audio! Connect your RPi’s output (HDMI or 3.5mm) to your receiver or amplifier. Then connect your computer or phone to the RPi and play something. If the audio is super quiet, make sure you changed the RPi audio level in the previous step.
MAKE EVERYTHING RUN AUTOMATICALLY
To make sure we have shairport-sync running automatically every time the RPi boots:
1 |
sudo systemctl enable shairport-sync |
Reboot the RPi and run this command to verify it’s working:
1 |
sudo systemctl status shairport-sync.service |
ENABLE HDMI BEFORE SOURCE IS TURNED ON
Your RPi will automatically look for an HDMI connection on boot and, if you forget and turn on your receiver second), it won’t connect. Luckily, we can easily fix this:
Open this file:
1 |
sudo nano /boot/config.txt |
Delete the # from the following lines (they should already be in the file, but if you’re lazy you can just type these in at the top instead):
1 2 3 |
hdmi_force_hotplug=1 config_hdmi_boost=4 hdmi_drive=2 |
These allow you RPi to find an HDMI source even if it’s attached later!
A FEW MORE TWEAKS
This great tutorial (which I used to get my Airplay receiver set up) suggests adding this command to help prevent wifi dropouts which may mess up your audio streaming.
Open this file:
1 |
sudo nano /etc/network/interfaces |
And add these two lines:
1 2 |
# disable wifi power management (to prevent Airplay streaming glitches) wireless-power off |
Reboot to have this change take effect.
ADDING A POWER BUTTON AND LED
Having a bare RPi sitting on your shelf is a recipe for disaster: loose connections, dust, short circuits, or worse (ask me how I know). But after you’ve cased up your RPi, it’s still a pain to have to SSH in every time you want to turn it off! Adding a dedicated power button, with LED indicator, is super easy and is totally worth the effort.
First, wire up your switch:
- Solder two wires to a momentary switch. It’s kinda pricey but I really like this one from Mouser. It’s panel-mount, which makes it easy to install in a case.
- Solder one of the two wires to pin #6 (ground) and the other to GPIO3 (pin #5).
To make this work, we need to install Shiva Siddharth’s pi-shut script:
1 2 |
git clone https://github.com/shivasiddarth/pi-shut.git cd pi-shut |
Then run the installer:
1 2 |
sudo chmod +x /home/pi/pi-shut/installer.sh sudo /home/pi/pi-shut/installer.sh |
Finally, start the script as a service, which will always run in the background:
1 |
sudo systemctl start on-off-pushbutton.service |
To add a power indicator, solder a wire from one leg of an LED to a 330ohm resistor, then to a ground GPIO pin (such as pin #9). Wire the other leg to GPIO14 (pin #8).
There’s lots of fancy ways to get this working in software, but by connecting to this particular pin, we’ll don’t have to do anything except turn on the GPIO serial port:
1 |
sudo nano /boot/config.txt |
And add this line:
1 |
enable_uart=1 |
Shut down your RPi and try turning it on by pushing the button! It should take just a few seconds before the LED comes on. You can turn it off by pressing the button again.
THAT’S IT!
Hope this was helpful – if you have any great ideas to make this work better, please let me know!
Great tutorial but I get stuck
./configure –with-alsa –with-avahi –with-ssl=openssl –with-systemd –with-metadata
…
hecking pkg-config is at least version 0.9.0… yes
checking for clock_gettime in -lrt… yes
checking for pthread_create in -lpthread… yes
checking for exp in -lm… yes
>>Including libpopt
checking for POPT… no
configure: error: Package requirements (popt) were not met:
No package ‘popt’ found
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Alternatively, you may set the environment variables POPT_CFLAGS
and POPT_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
root@applepi:/home/pi/shairport-sync#
Any ideas?
@Michael: yeah, I tried re-installing everything on my RPi recently and had a similar error. Haven’t found a workaround yet but please let me know if you do!
I ran through your tutorial and the software seems to working fine, but no audio from the 3.5mm jack. It will come through the HDMI if connected, but not the 3.5mm jack.
I’ve set the pi to force 3.5mm, but I cannot get sound through the jack. I have ordered a hat for the pi that can hopefully solve the problem, but I was wondering if this is something you noticed. Thanks!
@Nicholas – glad it’s working (mostly)! I remember trying the 3.5mm jack audio but it sounds terrible, so I went straight to HDMI. The issues with the audio out of the headphone jack are well documented but no one seems to know why or how to fix it. A hat might help be a good workaround for sure, if you don’t have an amplifier that can decode HDMI.
Man this is amazing! THANKS! I got it working but not through HDMI or 3.5 jack, I brought my Bose companion 5 into airplay with a pi zero through USB. No additional hardware or software required. Really really THANKS!
Thanks for the easy recipe, needed to repurpose an unused Raspberry Pi for an airplay server. Planning to connect a USB DAC to drive external speakers. Your instructions made it super easy, thanks again.
Could take it a step further and mount the Pi to the back of the TV repurposing the VESA wall mount holes. Then instead of a power button and LED, simply use HDMI-CEC. The mounting kit I includes a provision for a 30mm fan and suits 100mm x 100mm VESA mounting holes.
@Tim – oh dang, nice idea! I didn’t know about HDMI-CEC but that would be super fun
Did you bump into any issues running shairport-sync as a service? I get a few errors when running sshairport-sync -d. I’m suspecting it’s got something to do with the user account it adds so I’ll investigate that later.
Something else I’m looking at though is a screen saver showing what’s playing, album art, track info etc.
I was trying out a package (rpiplay) yesterday. Mirroring from macOS Big Sur worked fine but no audio. Worthwhile checking out: https://github.com/FD-/RPiPlay
Thank you for this excellent tutorial!
We first installed this on an ancient Raspberry Pi Model B Rev 2. We also managed to get this running on a Raspberry Pi 3 Model B Rev 1.2 with the IQaudio DAC+. In both cases, we’re running the audio out of the headphone jack. We set the audio output in raspi-config. We are running the Raspberry Pi through an old amplifier (with no HDMI input) with some $30 thrift store speakers and a decent subwoofer.
Configuring the IQAudio DAC+ was a bit of an adventure. Here’s the process that seemed to work, after I followed all the instructions from the regular Airplay installation.
Next, we edited Raspberry Pi config file
>> sudo nano /boot/config.txt
The final edited audio section of the file should look like this:
# Enable audio (loads snd_bcm2835)
#dtparam=audio=on
dtoverlay=iqaudio-dacplus
I then had to use the alsamixer program to turn the DAC headphone jack volume to max.
>> sudo alsamixer
I pressed the right arrow twice to select the second audio soundbar from the left, then the up arrow to choose maximum gain. I hit escape to quit alsamixer, then rebooted the Raspberry Pi just for the heck of it.
>> sudo reboot
The DAC sound is a little better than the standard
This works like a charm, thanks! Could it be possible to do it via bluetooth with a dongle attached to the Pi?
Thanks for a great guide.
You should add “–sysconfdir=/etc” to the ./configure command to make sure the config file is generated. (I didn’t get a config file in the supposed default location /usr/local/etc. Don’t know why.)
Thanks for the description. I simply used
sudo apt install shairport-sync
For installing shairport-sync. Works like a charm.
using a raspberry pi 4 8GB with bullseye, I can start up shairport and see it on my iPhone 12, and can connect to it but no audio output. I’ve run some sound test in terminal and even played youtube videos in the gui on the pi and it plays audio fine. Using HDMI port 0. Any ideas?