Build your own headless Raspberry Pi audio player

For a hassle-free solution, have a look at HiFiBerryOS, Volumio, pimusicbox, piCorePlayer, RoPieee or similiar solutions.
This tutorial describes how you can build your own headless player step by step by installing all the software yourself and configure it via the command line.

Raspberry Pi Zero W with Allo MiniBoss
Raspberry Pi Zero W with Raspiaudio Audio +

1. Hardware

If you want the most low budget solution, use a Raspberry Pi 3 with the onboard audio. Or you can use a Raspberry Pi Zero, with a cheap USB audio adapter, or use audio over HDMI if you connect directly to a soundbar or your TV or something like that. I won't cover those use cases here, but you can find out how to play audio on your own and then jump to 4. headless Spotify Connect player

I'm using a Raspberry Pi Zero W because it is the smallest of the Raspberry Pis, it's cheap and powerful enough.

There are a lot of audio hats you can use:

I used the Allo MiniBoss, the Pimoroni pHAT DAC, the Adafruit I2S Audio Bonnet and the Raspiaudio Audio+. All work without problems.

2. Get the Raspberry Pi Running

3. Get the Audio Output Running

you can use sudo aplay /usr/share/sounds/alsa/Front_Center.wav to test the audio output and sudo alsamixer to set the volume level

4. Headless Spotify Connect Player

We use raspotify as a spotify connect client. To install it, we use the script provided on the webpage: curl -sL https://dtcooper.github.io/raspotify/install.sh | sh (you can see what the script does by typing wget -qO- https://dtcooper.github.io/raspotify/install.sh or opening the URL in a browser; this is generally a good idea before executing some script downloaded from the internet).

After installing, open the config file /etc/default/raspotify in an editor of your choice, for example in nano by running sudo nano /etc/default/raspotify (in nano, you can press [CTRL] + [X] and then [Y] to close and save the changes you made).

Change the line #DEVICE_NAME="raspotify" to DEVICE_NAME="{name}" (removed the # at the beginning and change the name; this is what the device will be called in Spotify)
You can also remove the # in front of OPTIONS and add your username and password. This is not required, your device will be visible to all devices in your wifi running Spotify by default, but if you add your username and password you can also access your device over the internet.

After changing and saving the options file, restart raspotify by typing sudo systemctl restart raspotify

If you use a firewall on your pi, you may want to open some ports for Spotify Connect to work correctly; see this post for details.

Now you should be able to open Spotify on another device and connect to this new Spotify Connect client. If you have problems, have a look at the raspotify GitHub page.

5. Headless AirPlay Player

We use shairport-sync as a AirPlay client. To install it, run sudo apt install shairport-sync -y; this will install an older version, which is good enough, but if you want to run the newest version you can follow these instructions.

After installing, open the config file /etc/shairport-sync.conf in an editor of your choice, for example in nano by running sudo nano /etc/shairport-sync.conf (in nano, you can press [CTRL] + [X] and then [Y] to close and save the changes you made).

In the general area, remove the // in front of name = "%H"; and change %H to a name of your choice; this is the name that will appear in the AirPlay client select screen of your iOS device.

In the sessioncontrol area, remove the // in front of allow_session_interruption = "no"; and change the no to yes, if you want to be able to allow another device to interrupt playing.

Run sudo systemctl enable shairport-sync to start shairport-sync automatically when booting, and then sudo systemctl start shairport-sync to start the AirPlay client.

Now you should be able to see the client in the AirPlay device selection dialog on an iOS device. If you have problems, have a look at the shairport-sync GitHub page.

There may be a small bug that prevents shairport-sync from starting automatically; run shairport-sync -V and check the output. If it says 3.3.5 or higher, the bug is already fixed, if you are running an older version you can either compile shairport-sync for yourself or change the way shairport-sync starts (see this issue on GitHub for details): open /lib/systemd/system/shairport-sync.service in an editor and change the following lines:

6. Headless Plexamp Player

NOTE: I don't seem to get this to run reliably; as soon as you listen to something over Plex, the Spotify and AirPlay client stop working and you need to reboot the system. I stopped using the headless plexamp player and just use plexamp on my phone or tablet, with AirPlay. I might revisit this problem in the future, in the meantime the old solution is still here, but you have been warned. Here be dragons:

When running a Plex Media Server for your music and have a Plex Pass you can use Plexamp to listen to your music collection in high quality.

We use this tutorial which is based on this forum post:

Now you should be able to select the pi plexamp client in the plexamp player.

7. Overlay Filesystem

We can protect the SD-card by using an overlay filesystem. As long as the overlay filesystem is active, the SD-card is read-only and nothing gets written to it, and after a reboot every change you made is gone.
You can use raspi-config to enable/disable the overlay filesystem: start raspi-config with sudo raspi-config and then go to Performance Options - Overlay File System (you do not need to make the boot partition write-protected). After enabling it, the pi needs to reboot.
Don't forget to disable the overlay filesystem before making any changes to the config files or installing new software.