Skip to content

Instantly share code, notes, and snippets.

@connorjan
Last active August 6, 2024 06:55
Show Gist options
  • Save connorjan/984e6285d6c96abc807e6b0eb5724b82 to your computer and use it in GitHub Desktop.
Save connorjan/984e6285d6c96abc807e6b0eb5724b82 to your computer and use it in GitHub Desktop.
shairport-sync installation for a Raspberry Pi

shairport-sync installation for a Raspberry Pi

1. Update the Pi (part 1)

sudo rpi-update
sudo reboot

Note: this may enable the Predictable Network Interface Names settings.

2. Update the Pi (part 2)

sudo apt-get update && sudo apt-get upgrade

3. Enable the newer audio driver

printf "\n# Set audio output to headphone jack\naudio_pwm_mode=2\n" | sudo tee -a /boot/config.txt

4. Install the dependencies

sudo apt install build-essential git xmltoman autoconf automake libtool libdaemon-dev libpopt-dev libconfig-dev libasound2-dev libpulse-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev

5. Clone the shairport-sync repo

git clone https://github.com/mikebrady/shairport-sync.git

6. Configure shairport-sync

cd shairport-sync
autoreconf -i -f
./configure --sysconfdir=/etc --with-alsa --with-pa --with-pipe --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemd

7. Build and install shairport-sync

make
sudo make install

8. Enable and start the service

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

9. Configure shairport with the configuration file below

/etc/shairport-sync.conf

See the example configuration file here

// Sample Configuration File for Shairport Sync
// Commented out settings are generally the defaults, except where noted.
// General Settings
general =
{
name = "%h"; // This means "Hostname" -- see below. This is the name the service will advertise to iTunes.
// The default is "Hostname" -- i.e. the machine's hostname with the first letter capitalised (ASCII only.)
// You can use the following substitutions:
// %h for the hostname,
// %H for the Hostname (i.e. with first letter capitalised (ASCII only)),
// %v for the version number, e.g. 3.0 and
// %V for the full version string, e.g. 3.0-OpenSSL-Avahi-ALSA-soxr-metadata-sysconfdir:/etc
// Overall length can not exceed 50 characters. Example: "Shairport Sync %v on %H".
// password = "secret"; // leave this commented out if you don't want to require a password
// interpolation = "basic"; // aka "stuffing". Default is "basic", alternative is "soxr". Use "soxr" only if you have a reasonably fast processor.
output_backend = "alsa"; // Run "shairport-sync -h" to get a list of all output_backends, e.g. "alsa", "pipe", "stdout". The default is the first one.
// mdns_backend = "avahi"; // Run "shairport-sync -h" to get a list of all mdns_backends. The default is the first one.
// port = 5000; // Listen for service requests on this port
// udp_port_base = 6001; // start allocating UDP ports from this port number when needed
// udp_port_range = 100; // look for free ports in this number of places, starting at the UDP port base. Allow at least 10, though only three are needed in a steady state.
// statistics = "no"; // set to "yes" to print statistics in the log
// drift_tolerance_in_seconds = 0.002; // allow a timing error of this number of seconds of drift away from exact synchronisation before attempting to correct it
// resync_threshold_in_seconds = 0.050; // a synchronisation error greater than this number of seconds will cause resynchronisation; 0 disables it
// log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
// ignore_volume_control = "no"; // set this to "yes" if you want the volume to be at 100% no matter what the source's volume control is set to.
volume_range_db = 30 ; // use this advanced setting to set the range, in dB, you want between the maximum volume and the minimum volume. Range is 30 to 150 dB. Leave it commented out to use mixer's native range.
// volume_max_db = 0.0 ; // use this advanced setting, which must have a decimal point in it, to set the maximum volume, in dB, you wish to use.
// The setting is for the hardware mixer, if chosen, or the software mixer otherwise. The value must be in the mixer's range (0.0 to -96.2 for the software mixer).
// Leave it commented out to use mixer's maximum volume.
// run_this_when_volume_is_set = "/full/path/to/application/and/args"; // Run the specified application whenever the volume control is set or changed.
// The desired AirPlay volume is appended to the end of the command line – leave a space if you want it treated as an extra argument.
// AirPlay volume goes from 0 to -30 and -144 means "mute".
// regtype = "_raop._tcp"; // Use this advanced setting to set the service type and transport to be advertised by Zeroconf/Bonjour. Default is "_raop._tcp".
// playback_mode = "stereo"; // This can be "stereo", "mono", "reverse stereo", "both left" or "both right". Default is "stereo".
// alac_decoder = "hammerton"; // This can be "hammerton" or "apple". This advanced setting allows you to choose
// the original Shairport decoder by David Hammerton or the Apple Lossless Audio Codec (ALAC) decoder written by Apple.
// interface = "name"; // Use this advanced setting to specify the interface on which Shairport Sync should provide its service. Leave it commented out to get the default, which is to select the interface(s) automatically.
// audio_backend_latency_offset_in_seconds = 0.0; // Set this offset to compensate for a fixed delay in the audio back end. E.g. if the output device delays by 100 ms, set this to -0.1.
// audio_backend_buffer_desired_length_in_seconds = 0.15; // If set too small, buffer underflow occurs on low-powered machines. Too long and the response time to volume changes becomes annoying. Default is 0.15 seconds in the alsa backend, 0.35 seconds in the pa backend and 1.0 seconds otherwise.
// audio_backend_silent_lead_in_time = 2.0; // This optional advanced setting, from 0.0 and 4.0 seconds, sets the length of the period of silence that precedes the start of the audio. The default is the latency, usually 2.0 seconds. Values greater than the latency are ignored. Values that are too low will affect initial synchronisation.
};
dsp =
{
//////////////////////////////////////////
// This convolution filter can be used to apply almost any correction to the audio signal, like frequency and phase correction.
// For example you could measure (with a good microphone and a sweep-sine) the frequency response of your speakers + room,
// and apply a correction to get a flat response curve.
//////////////////////////////////////////
//
// convolution = "yes"; // Activate the convolution filter.
// convolution_ir_file = "impulse.wav"; // Impulse Response file to be convolved to the audio stream
// convolution_gain = -4.0; // Static gain applied to prevent clipping during the convolution process
// convolution_max_length = 44100; // Truncate the input file to this length in order to save CPU.
//////////////////////////////////////////
// This loudness filter is used to compensate for human ear non linearity.
// When the volume decreases, our ears loose more sentisitivity in the low range frequencies than in the mid range ones.
// This filter aims at compensating for this loss, applying a variable gain to low frequencies depending on the volume.
// More info can be found here: https://en.wikipedia.org/wiki/Equal-loudness_contour
// For this filter to work properly, you should disable (or set to a fix value) all other volume control and only let shairport-sync control your volume.
// The setting "loudness_reference_volume_db" should be set at the volume reported by shairport-sync when listening to music at a normal listening volume.
//////////////////////////////////////////
//
// loudness = "yes"; // Activate the filter
// loudness_reference_volume_db = -20.0; // Above this level the filter will have no effect anymore. Below this level it will gradually boost the low frequencies.
};
// How to deal with metadata, including artwork
metadata =
{
// enabled = "no"; // set this to yes to get Shairport Sync to solicit metadata from the source and to pass it on via a pipe
// include_cover_art = "no"; // set to "yes" to get Shairport Sync to solicit cover art from the source and pass it via the pipe. You must also set "enabled" to "yes".
// pipe_name = "/tmp/shairport-sync-metadata";
// pipe_timeout = 5000; // wait for this number of milliseconds for a blocked pipe to unblock before giving up
// socket_address = "226.0.0.1"; // if set to a host name or IP address, UDP packets containing metadata will be sent to this address. May be a multicast address. "socket-port" must be non-zero and "enabled" must be set to yes"
// socket_port = 5555; // if socket_address is set, the port to send UDP packets to
// socket_msglength = 65000; // the maximum packet size for any UDP metadata. This will be clipped to be between 500 or 65000. The default is 500.
};
// Advanced parameters for controlling how a Shairport Sync runs
sessioncontrol =
{
// run_this_before_play_begins = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
// run_this_after_play_ends = "/full/path/to/application and args"; // make sure the application has executable permission. It it's a script, include the #!... stuff on the first line
// wait_for_completion = "no"; // set to "yes" to get Shairport Sync to wait until the "run_this..." applications have terminated before continuing
// allow_session_interruption = "no"; // set to "yes" to allow another device to interrupt Shairport Sync while it's playing from an existing audio source
// session_timeout = 120; // wait for this number of seconds after a source disappears before terminating the session and becoming available again.
};
// Back End Settings
// These are parameters for the "alsa" audio back end.
alsa =
{
output_device = "hw:0"; // the name of the alsa output device. Use "alsamixer" or "aplay" to find out the names of devices, mixers, etc.
mixer_control_name = "PCM"; // the name of the mixer to use to adjust output volume. If not specified, volume in adjusted in software.
// mixer_device = "default"; // the mixer_device default is whatever the output_device is. Normally you wouldn't have to use this.
// output_rate = 44100; // can be 44100, 88200, 176400 or 352800, but the device must have the capability.
// output_format = "S16"; // can be "U8", "S8", "S16", "S24", "S24_3LE", "S24_3BE" or "S32", but the device must have the capability. Except where stated using (*LE or *BE), endianness matches that of the processor.
// disable_synchronization = "no"; // Set to "yes" to disable synchronization. Default is "no".
// period_size = <number>; // Use this optional advanced setting to set the alsa period size near to this value
// buffer_size = <number>; // Use this optional advanced setting to set the alsa buffer size near to this value
// use_mmap_if_available = "yes"; // Use this optional advanced setting to control whether MMAP-based output is used to communicate with the DAC. Default is "yes"
// mute_using_playback_switch = "yes"; // Use this optional advanced setting to control whether the snd_mixer_selem_set_playback_switch_all call can be used for muting. Default is yes.
};
// Parameters for the "sndio" audio back end. All are optional.
sndio =
{
// device = "snd/0"; // optional setting to set the name of the output device. Default is the sndio system default.
// rate = 44100; // optional setting which can be 44100, 88200, 176400 or 352800, but the device must have the capability. Default is 44100.
// format = "S16"; // optional setting which can be "U8", "S8", "S16", "S24", "S24_3LE", "S24_3BE" or "S32", but the device must have the capability. Except where stated using (*LE or *BE), endianness matches that of the processor.
// round = <number>; // advanced optional setting to set the period size near to this value
// bufsz = <number>; // advanced optional setting to set the buffer size near to this value
};
// Parameters for the "pa" PulseAudio backend.
pa =
{
// application_name = "Shairport Sync"; //Set this to the name that should appear in the Sounds "Applications" tab when Shairport Sync is active.
};
// Parameters for the "pipe" audio back end, a back end that directs raw CD-style audio output to a pipe. No interpolation is done.
pipe =
{
// name = "/path/to/pipe"; // there is no default pipe name for the output
};
// These are no configuration file parameters for the "stdout" audio back end. No interpolation is done.
// These are no configuration file parameters for the "ao" audio back end. No interpolation is done.
// Static latency settings are deprecated and the settings have been removed.
@gburkell
Copy link

Hi @MattL0 thanks for the response. I've fixed the issue, I redid my installation based on Matt's guide.

@MattL0
Copy link

MattL0 commented Aug 3, 2020

Hi @MattL0 thanks for the response. I've fixed the issue, I redid my installation based on Matt's guide.
Glad it worked for you :)

@dudetinker
Copy link

Any idea why it's showing up on my mac under sound, but not on my iPhone? Has anyone experienced that?

The newest iOS update inhibits shairport-sync usage because it forces Airplay 2 protocol. I think someone is working on a fix (Fingers crossed).

@petcol
Copy link

petcol commented May 2, 2021

I had shairport working fine on my Raspberry Pi 4 B but had to move it down to a Rapsberry Pi 3 B+ for other reasons, anyway, now I can not get it working. Media devices such as iTune IPhone etc can see and connect to the device even when the name is changed name = "%h"; hostname to something more meaningful. But no audio plays through the speakers. The speaker test worked fine audio plays, If I use desktop and open a media file that has audio it plays fine.

I'm a bit confused what to check or look for, and assistance is appreciated?

@1nutty1
Copy link

1nutty1 commented Jul 9, 2021

I had shairport working fine on my Raspberry Pi 4 B but had to move it down to a Rapsberry Pi 3 B+ for other reasons, anyway, now I can not get it working. Media devices such as iTune IPhone etc can see and connect to the device even when the name is changed name = "%h"; hostname to something more meaningful. But no audio plays through the speakers. The speaker test worked fine audio plays, If I use desktop and open a media file that has audio it plays fine.

I'm a bit confused what to check or look for, and assistance is appreciated?

Try using output_device = "hw:Headphones"; under the alsa section

@carbocation
Copy link

Try using output_device = "hw:Headphones"; under the alsa section

This worked for me on an RPi 4 with raspbian OS.

@petcol
Copy link

petcol commented Jul 10, 2021

Thanks all for your replies;
I had already stumbled across this and yes it does work consistently on all my pi platforms. Just wish I’d found it earlier, but then I wouldn’t be doing other fun things 😂
output_device = "hw:Headphones"; under the alsa section

@1nutty1
Copy link

1nutty1 commented Jul 10, 2021

Anyone know how to pull the 'cover' picture that is passed over MQTT?

@rolandovoces
Copy link

How can I pass the signal to a MiniDLNA server which is on the same raspberry? How I have to config the output device in der shairport-sync.conf file?

@petcol
Copy link

petcol commented Jun 20, 2023

Server by nature means giving, serving or sending information. So a DLNA Server sends data dont think it’ll receive
Shareport Sync works against AirPlay as a receiver
I might be wrong if I am let me know

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