mikebrady / shairport-sync

AirPlay and AirPlay 2 audio player
Other
7.2k stars 571 forks source link

Pipe output failing - Looking for default config. #1066

Closed cdlenfert closed 4 years ago

cdlenfert commented 4 years ago

I'm unable to get shairport-sync to start when configured to output to a pipe. I've tried adjusting permissions so the pipes are owned by shairport-sync user and group, and also changed mod permissions to 777. Nothing's working for me. My system is Debian 10 (buster). My pipes are in /root/fd-pipes/ but for whatever reason it just won't run.

I'm looking for the default config file, but can't seem to find it. I want to make sure there's not some syntax error. I'll gladly share more troubleshooting info, but wanted to try this once more before I take anyone else's time. How can I regenerate the default config file? apt remove shairport-sync and removing the /etc/shairport-sync.conf file doesn't generate a new one when I apt install shairport-sync. Thanks for any tips.

mikebrady commented 4 years ago

Thanks for the post. A couple of things. It would be useful to know the version of the Shairport Sync -- see REPORTING ISSUES.md. That would give us an idea, among other things, of whether there have been many bug fixes since it was released and would also tell us where the configuration file is to be found. It would also be good to know the system you're on.

Given that this is installed from a package, it is probably pretty old, so a good move to consider would be to remove it and build Shairport Sync from sources. It's pretty easy -- see INSTALL.md -- and you can be assured of the latest version. There has been some work on the pipe output in recent updates, so maybe they will help.

There is no default pipe name, so unless you specify a pipe name to Shairport Sync, it will not run. It may leave a message in the system log. Let us know how you do!

([Edit]: in the latest development version, there is a default pipe -- /tmp/shairport-sync-audio.)

cdlenfert commented 4 years ago

@mikebrady Thanks for the response. I'll do the manual install and see where that gets me and then share more info about the setup if I'm still stuck. I'm looking for clues in the journalctl log. Please let me know if that's not the right spot.

Gadgetoid commented 4 years ago

I've just configured shairport-sync on a Raspberry Pi and ran into this same issue.

Build & version:

pi@raspberrypi:~ $ shairport-sync -V
3.3.7rc2-OpenSSL-Avahi-ALSA-soxr-metadata-sysconfdir:/etc

Startup:

pi@raspberrypi:~ $ ./shairport-sync -vvvvu
         0.000255384 "shairport.c:459" looking for configuration file at full path "/etc/shairport-sync.conf"
         0.002061088 "shairport.c:1710" Started!
         0.000089461 "shairport.c:1737" software version: "3.3.7rc2-OpenSSL-Avahi-ALSA-soxr-metadata-sysconfdir:/etc"
         0.000039425 "shairport.c:1743" log verbosity is 4.
         0.000085406 "audio_alsa.c:998" alsa: init() -- alsa_backend_state => abm_disconnected.
         0.000041388 "audio_alsa.c:1015" alsa: alsa_maximum_stall_time of 0.200000 sec.
         0.000066091 "audio_alsa.c:1302" alsa: disable_standby_mode is "never".
         0.000029815 "audio_alsa.c:1304" alsa: disable_standby_mode_silence_threshold is 0.040000 seconds.
         0.000033666 "audio_alsa.c:1306" alsa: disable_standby_mode_silence_scan_interval is 0.004000 seconds.
         0.000088572 "audio_alsa.c:1345" alsa: output device name is "default".
         0.000273180 "shairport.c:1758" The processor is running little-endian.
         0.000048295 "shairport.c:1791" disable resend requests is off.
         0.000020093 "shairport.c:1795" diagnostic_drop_packet_fraction is 0.000000. A value of 0.0 means no packets will be dropped deliberately.
         0.000015203 "audio_alsa.c:1943" keep_dac_busy is now "no"
         0.000037962 "shairport.c:1796" statistics_requester status is 0.
         0.000105350 "shairport.c:1801" rtsp listening port is 5000.
         0.000037480 "shairport.c:1802" udp base port is 6001.
         0.000034777 "shairport.c:1803" udp port range is 10.
         0.000031574 "shairport.c:1804" player name is "Raspberrypi".
         0.000033444 "shairport.c:1805" backend is "(null)".
         0.000031351 "shairport.c:1806" run_this_before_play_begins action is "(null)".
         0.000031129 "shairport.c:1807" run_this_after_play_ends action is "(null)".
         0.000031166 "shairport.c:1808" wait-cmd status is 0.
         0.000034407 "shairport.c:1809" run_this_before_play_begins may return output is 0.
         0.000032832 "shairport.c:1810" run_this_if_an_unfixable_error_is_detected action is "(null)".
         0.000032185 "shairport.c:1811" run_this_before_entering_active_state action is  "(null)".
         0.000031499 "shairport.c:1812" run_this_after_exiting_active_state action is  "(null)".
         0.000033388 "shairport.c:1813" active_state_timeout is  10.000000 seconds.
         0.000036129 "shairport.c:1814" mdns backend "(null)".
         0.000033666 "shairport.c:1815" userSuppliedLatency is 0.
         0.000031240 "shairport.c:1818" interpolation setting is "auto".
         0.000030629 "shairport.c:1819" interpolation soxr_delay_threshold is 30.
         0.000031204 "shairport.c:1820" resync time is 0.050000 seconds.
         0.000033129 "shairport.c:1821" allow a session to be interrupted: 0.
         0.000031740 "shairport.c:1822" busy timeout time is 120.
         0.000030277 "shairport.c:1823" drift tolerance is 0.001995 seconds.
         0.000032351 "shairport.c:1824" password is "(null)".
         0.000034110 "shairport.c:1825" ignore_volume_control is 0.
         0.000031555 "shairport.c:1829" volume_max_db is not set
         0.000029370 "shairport.c:1831" volume range in dB (zero means use the range specified by the mixer): 0.
         0.000033648 "shairport.c:1835" volume_range_combined_hardware_priority (1 means hardware mixer attenuation is used first) is 0.
         0.000033295 "shairport.c:1837" playback_mode is 0 (0-stereo, 1-mono, 1-reverse_stereo, 2-both_left, 3-both_right).
         0.000033426 "shairport.c:1838" disable_synchronization is 0.
         0.000031240 "shairport.c:1839" use_mmap_if_available is 1.
         0.000031166 "shairport.c:1841" output_format automatic selection is enabled.
         0.000033925 "shairport.c:1845" output_rate automatic selection is enabled.
         0.000032166 "shairport.c:1849" audio backend desired buffer length is 0.200000 seconds.
         0.000035833 "shairport.c:1851" audio_backend_buffer_interpolation_threshold_in_seconds is 0.120000 seconds.
         0.000034536 "shairport.c:1852" audio backend latency offset is 0.000000 seconds.
         0.000033796 "shairport.c:1854" audio backend silence lead-in time is "auto".
         0.000031666 "shairport.c:1858" zeroconf regtype is "_raop._tcp".
         0.000030351 "shairport.c:1859" decoders_supported field is 1.
         0.000031592 "shairport.c:1860" use_apple_decoder is 0.
         0.000033184 "shairport.c:1861" alsa_use_hardware_mute is 0.
         0.000031370 "shairport.c:1865" no special mdns service interface was requested.
         0.000070925 "shairport.c:1869" configuration file name "/etc/shairport-sync.conf" resolves to "/etc/shairport-sync.conf".
         0.000038480 "shairport.c:1875" metadata enabled is 1.
         0.000032240 "shairport.c:1876" metadata pipename is "/tmp/shairport-sync-metadata".
         0.000032352 "shairport.c:1878" metadata socket address is "(null)" port 0.
         0.000032629 "shairport.c:1879" metadata socket packet size is "500".
         0.000031943 "shairport.c:1880" get-coverart is 1.
         0.000034352 "shairport.c:1898" loudness is 0.
         0.000031129 "shairport.c:1899" loudness reference level is -20.000000
         0.000158922 "rtsp.c:157" Creating metadata queue "multicast".
         0.000491953 "rtsp.c:157" Creating metadata queue "pipe".
         0.012652322 "mdns_avahi.c:209" avahi: service 'AF31192A3A11@Raspberrypi' group is not yet committed.
         0.002661336 "mdns_avahi.c:244" avahi: request to add "_raop._tcp" service with metadata
         0.001611801 "mdns_avahi.c:375" avahi_dacp_monitor_start Avahi DACP monitor successfully started
         0.000404973 "mdns_avahi.c:213" avahi: service 'AF31192A3A11@Raspberrypi' group is registering.
         0.754579891 "mdns_avahi.c:180" avahi: service 'AF31192A3A11@Raspberrypi' successfully added.
         0.728692221 "shairport.c:192" soxr_delay_index: 3.
         0.000045314 "shairport.c:199" "soxr" interpolation has been chosen.

Perms on /tmp

pi@raspberrypi:~ $ ls -hal /
drwxrwxrwt  12 root root 4.0K Sep 10 22:03 tmp

If I create /tmp/shairport-sync-metadata manually and chmod 777 then I end up with what appears to be Shairport continually appending metadata to a regular file, rather than a pipe.

It would appear that Shairport-sync is not creating a pipe, but in this case it should bail out with a "Could not create matadata pipe" error:

  if (mkfifo(path, 0666) && errno != EEXIST)
    die("Could not create metadata pipe \"%s\".", path);

Source: https://github.com/mikebrady/shairport-sync/blob/27faeaf69667e9625e3e7c8ac67fb1f88f3368cb/rtsp.c#L1575-L1576

But - presumably because this part is threaded or happens on-demand? - I don't see any of this in the debug information. Even if I connect, play/pause/switch tracks.

Is there a way to debug this thread and see what might be going awry?

mikebrady commented 4 years ago

Thanks for this. I’ll take a look.

Gadgetoid commented 4 years ago

The following ugly hack makes the fifo magically appear by bruteforce creating it before any attempt to write:

diff --git a/rtsp.c b/rtsp.c
index 1f1cb9f..3366987 100644
--- a/rtsp.c
+++ b/rtsp.c
@@ -1342,6 +1342,7 @@ void metadata_open(void) {
   char *path = malloc(pl + 1);
   snprintf(path, pl + 1, "%s", config.metadata_pipename);

+  mkfifo(path, 0666);
   fd = try_to_open_pipe_for_writing(path);
   free(path);
 }

Now the metadata-reader works as expected:

pi@raspberrypi:~/shairport-sync $ shairport-sync-metadata-reader < /tmp/shairport-sync-metadata
"ssnc" "snua": "AirPlay/420.45".
"ssnc" "acre": "988380828".
"ssnc" "daid": "FF0CF15D960FFF1A".
Client's IP: "fe80::c18:5ada:fada:1ab0".
"ssnc" "svip": "fe80::266:e608:3782:a25".
"ssnc" "abeg": "".
"ssnc" "pbeg": "".
"ssnc" "pvol": "-18.00,-37.56,-96.30,0.00".
"ssnc" "pvol": "-0.28,-0.45,-96.30,0.00".
"ssnc" "pvol": "-0.28,-0.45,-96.30,0.00".
"ssnc" "pfls": "373259480".
"ssnc" "pffr": "".
"ssnc" "pcst": "373164500".
Picture received, length 78605 bytes.
"ssnc" "pcen": "373164500".
"ssnc" "prgr": "372755777/373185131/381577541".
"ssnc" "mdst": "373186187".
Persistent ID: "7d5489f8096cf6e1".
Album Name: "After Hours".
Artist: "The Weeknd".
Composer: "".
Genre: "".
Title: "Blinding Lights".
"ssnc" "mden": "373186187".
"ssnc" "dapo": "54981".
"ssnc" "dapo": "54981".
"ssnc" "prsm": "".

My guess would be that metadata_hub_thread_function is never executed.

Edit: may be that CONFIG_METADATA_HUB is never set.

mikebrady commented 4 years ago

Yikes. Have to check this!

mikebrady commented 4 years ago

It’s going to be tomorrow though, I’m afraid.

mikebrady commented 4 years ago

Good detective work!

Gadgetoid commented 4 years ago

You're welcome- I fired it up to try and get album art running on our Pirate Audio boards... failed at the first hurdle. D'oh!

Some cases with an additional "unrelated" config options that enable the extended metadata support would probably fix this metadata bug.

autoconf is totally alien to me, but I managed to fix it with the following tweak:

diff --git a/configure.ac b/configure.ac
index 7f25369..0b25b90 100644
--- a/configure.ac
+++ b/configure.ac
@@ -362,6 +362,10 @@ if test "x$REQUESTED_MPRIS" = "x1" || test "x$REQUESTED_DBUS" = "x1" || test "x$
   AC_DEFINE([CONFIG_METADATA_HUB], 1, [Needed by the compiler.])
   AC_DEFINE([CONFIG_DACP_CLIENT], 1, [Needed by the compiler.])
 fi
+if test "x$REQUESTED_METADATA" = "x1"; then
+  REQUESTED_EXTENDED_METADATA_SUPPORT=1
+  AC_DEFINE([CONFIG_METADATA_HUB], 1, [Needed by the compiler.])
+fi
 AM_CONDITIONAL([USE_METADATA_HUB], [test "x$REQUESTED_EXTENDED_METADATA_SUPPORT" = "x1"])
 AM_CONDITIONAL([USE_DACP_CLIENT], [test "x$REQUESTED_EXTENDED_METADATA_SUPPORT" = "x1"])

I have only a surface level knowledge of the codebase, but I guess CONFIG_METADATA is pretty much == CONFIG_METADATA_HUB at this point and the two defines could become one.

mikebrady commented 4 years ago

Hi there. Thanks to your work, @Gadgetoid, I found -- and hopefully fixed -- the error. Your hunch was right, in that the conditional compilation flags incorrectly omitted the code needed to create the metadata pipe in a situation where the --with-metadata configuration flag was chosen without any of the dbus, MPRIS or MQTT options.

My bad -- I left the code in the wrong place!

If you got a chance to check it -- it's in the development branch -- that would be great.

mikebrady commented 4 years ago

I'm unable to get shairport-sync to start when configured to output to a pipe. I've tried adjusting permissions so the pipes are owned by shairport-sync user and group, and also changed mod permissions to 777. Nothing's working for me. My system is Debian 10 (buster). My pipes are in /root/fd-pipes/ but for whatever reason it just won't run.

I'm looking for the default config file, but can't seem to find it. I want to make sure there's not some syntax error. I'll gladly share more troubleshooting info, but wanted to try this once more before I take anyone else's time. How can I regenerate the default config file? apt remove shairport-sync and removing the /etc/shairport-sync.conf file doesn't generate a new one when I apt install shairport-sync. Thanks for any tips.

@cdlenfert, I've just pushed an update to the development branch that fixes the bug referred to by @Gadgetoid, which affects the metadata pipe but not the audio pipe. But also, it includes code to give the audio pipe a default value: /tmp/shairport-sync-audio, so if you would be kind enough to build from the development branch, that would be great.

mikebrady commented 4 years ago

@cdlenfert, I hope you don't mind me suggesting this, but check in the configuration file that you have chosen the output_backend to be "pipe" and have given a pipe name in the pipe section further down the file.

Alternatively, use the command line option -o pipe -- /your/pipe/name.

With the changes in the development version, you can omit the pipe name from the configuration file and from the command line -- it will default to /tmp/shairport-sync-audio.

mikebrady commented 4 years ago

@Gadgetoid, I'd be interested in how you get on the the Pirate Audio boards. I got one to drive headphones, but I never got around to trying to get cover art onto it or to use the controls, both of which should be possible.

cdlenfert commented 4 years ago

Thanks again @mikebrady. I've not been able to do more troubleshooting yet. Will shaiport-sync create the pipe if the config designates a name and path? I've always created my pipes independently and adjusted permissions so SS can write to them.

My config:

// General Settings
general =
{
    name = "HivePlay"; // 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 = "pipe"; // 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.
//  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
//  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 = 60 ; // 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.
//  volume_control_profile = "standard" ; // use this advanced setting to specify how the airplay volume is transferred to the mixer volume.
//      "standard" makes the volume change more quickly at lower volumes and slower at higher volumes.
//      "flat" makes the volume change at the same rate at all volumes.
//  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.
//  dbus_service_bus = "system"; // The Shairport Sync dbus interface, if selected at compilation, will appear
//      as "org.gnome.ShairportSync" on the whichever bus you specify here: "system" (default) or "session".
//  mpris_service_bus = "system"; // The Shairport Sync mpris interface, if selected at compilation, will appear
//      as "org.gnome.ShairportSync" on the whichever bus you specify here: "system" (default) or "session".
};

// Advanced parameters for controlling how Shairport Sync runs a play session
sessioncontrol =
{
//  run_this_before_play_begins = "/full/path/to/application and args"; // make sure the application has executable permission. If it's a script, include the shebang (#!/bin/...) on the first line
//  run_this_after_play_ends = "/full/path/to/application and args"; // make sure the application has executable permission. If it's a script, include the shebang (#!/bin/...) 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 = "default"; // 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"
//  use_hardware_mute_if_available = "no"; // Use this optional advanced setting to control whether the hardware in the DAC is used for muting. Default is "no", for compatibility with other audio players.
};

// 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 = "/root/fd-pipes/airpipe"; // 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.

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 = "yes"; // 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 = "yes"; // 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 = "/root/fd-pipes/airpipe.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.
};

// Diagnostic settings. These are for diagnostic and debugging only. Normally you sould leave them commented out
diagnostics =
{
//  disable_resend_requests = "no"; // set this to yes to stop Shairport Sync from requesting the retransmission of missing packets. Default is "no".
//  statistics = "no"; // set to "yes" to print statistics in the log
//  log_verbosity = 0; // "0" means no debug verbosity, "3" is most verbose.
//  log_show_time_since_startup = "no"; // set this to yes if you want the time since startup in the debug message -- seconds down to nanoseconds
//  log_show_time_since_last_message = "no"; // set this to yes if you want the time since the last debug message in the debug message -- seconds down to nanoseconds
//  drop_this_fraction_of_audio_packets = 0.0; // use this to simulate a noisy network where this fraction of UDP packets are lost in transmission. E.g. a value of 0.001 would mean an average of 0.1% of packets are lost, which is actually quite a high figure.
};

And permissions on pipes:

root@debian:~/fd-pipes# ls -lah
total 12K
drwxrwxrwx 3 shairport-sync shairport-sync 4.0K Sep  8 07:28 .
drwx------ 7 root           root           4.0K Sep  8 15:05 ..
prwxrwxrwx 1 root           root              0 Sep  7 20:55 airpipe
prwxrwxrwx 1 root           root              0 Sep  7 20:55 airpipe.metadata
drwxrwxrwx 2 root           root           4.0K Sep  7 12:50 playlists
-rw-r--r-- 1 root           root              0 Sep  8 07:28 trigger.init-rescan
mikebrady commented 4 years ago

Yes indeed -- that looks plausible. What version of Shairport Sync? (Do $ shairport-sync -V and post the response.)

cdlenfert commented 4 years ago
root@debian:~/fd-pipes# shairport-sync -V
3.2.2-OpenSSL-Avahi-ALSA-pa-dummy-stdout-pipe-soxr-convolution-metadata-sysconfdir:/etc

Again, apt-installed this from the Buster repo and haven't had a chance to build from source yet.

mikebrady commented 4 years ago

Thanks. Definitely worth building from source — there have been many fixes in the intervening period.

Gadgetoid commented 4 years ago

@mikebrady I have cover art working on Pirate Audio, I didn't know controls were possible! I'll have to look into it. It's only slightly on topic but if you're interested in trying experimental cover art you can see here: https://github.com/pimoroni/pidi/pull/3

I'm keen to build a better, multi-in-multi-out solution for getting album info onto screens, though, since I have got album art working with a bunch of music providers that people use in various permutations. Needs unifying!

I'll check the development branch ASAP. Went down a bit of a rabbit hole with something else tonight.

P.S. glad my sleuthing got you up and running, the existing reports of this bug were... not very helpful... and your frustration was palpable. And- to be sure- I owe you a dozen and one for Shairport Sync in the first place 🥇

mikebrady commented 4 years ago

Yeah, Shairport Sync has a native D-Bus interface (also MPRIS and MQTT interfaces) that gives access to some controls. It relays commands and status information to and from the remote source. This works where the source is iTunes or iOS. Unfortunately the newer MacOS Music app doesn't work at present -- the situation keeps changing, so maybe it'll work in a future version. (BTW, the Linux GUI app called D-Feet is very handy for exploring D-Bus facilities.)

cdlenfert commented 4 years ago

@mikebrady I installed from the new development branch, set up my config again, restarted SS and it still fails with pipe output for me. My config is linked below.

root@debian:~/shairport-sync# systemctl status shairport-sync
* shairport-sync.service - Shairport Sync - AirPlay Audio Receiver
   Loaded: loaded (/lib/systemd/system/shairport-sync.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sat 2020-09-12 13:43:47 PDT; 8s ago
  Process: 3846 ExecStart=/usr/local/bin/shairport-sync (code=exited, status=1/FAILURE)
 Main PID: 3846 (code=exited, status=1/FAILURE)

Sep 12 13:43:47 debian systemd[1]: Started Shairport Sync - AirPlay Audio Receiver.
Sep 12 13:43:47 debian systemd[1]: shairport-sync.service: Main process exited, code
=exited, status=1/FAILURE
Sep 12 13:43:47 debian systemd[1]: shairport-sync.service: Failed with result 'exit-
code'.
root@debian:~/shairport-sync# journalctl -u shairport-sync --since "2 minutes ago"
-- Logs begin at Thu 2019-02-14 02:12:00 PST, end at Sat 2020-09-12 13:45:04 PDT. --
Sep 12 13:43:47 debian systemd[1]: Stopping Shairport Sync - AirPlay Audio Receiver...
Sep 12 13:43:47 debian systemd[1]: shairport-sync.service: Main process exited, code=killed, status=15/TERM
Sep 12 13:43:47 debian systemd[1]: shairport-sync.service: Succeeded.
Sep 12 13:43:47 debian systemd[1]: Stopped Shairport Sync - AirPlay Audio Receiver.
Sep 12 13:43:47 debian systemd[1]: Started Shairport Sync - AirPlay Audio Receiver.
Sep 12 13:43:47 debian systemd[1]: shairport-sync.service: Main process exited, code=exited, status=1/FAILURE
Sep 12 13:43:47 debian systemd[1]: shairport-sync.service: Failed with result 'exit-code'.
Sep 12 13:45:03 debian systemd[1]: Started Shairport Sync - AirPlay Audio Receiver.
Sep 12 13:45:04 debian systemd[1]: shairport-sync.service: Main process exited, code=exited, status=1/FAILURE
Sep 12 13:45:04 debian systemd[1]: shairport-sync.service: Failed with result 'exit-code'.

My Config

cdlenfert commented 4 years ago

I removed the reference to my airpipe pipes and set the config file to the defaults. I also disabled metadata for testing. Shairport-sync starts now.

root@debian:~/shairport-sync# systemctl status shairport-sync
* shairport-sync.service - Shairport Sync - AirPlay Audio Receiver
   Loaded: loaded (/lib/systemd/system/shairport-sync.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2020-09-12 13:53:03 PDT; 6s ago
 Main PID: 3870 (shairport-sync)
   CGroup: /system.slice/shairport-sync.service
           `-3870 /usr/local/bin/shairport-sync

Sep 12 13:53:03 debian systemd[1]: Started Shairport Sync - AirPlay Audio Receiver.

Am I missing something in my understanding of permissions. The pipes I made are 777. Shouldn't all users be able to write to these files?

Edit: Oh, and can you tell me the defaults for the metadata pipe location?

mikebrady commented 4 years ago

Thanks for the updates. The default for the metadata pipe is /tmp/shairport-sync-metadata.

It would be very useful if you could increase the log verbosity by setting the log_verbosity to 1 or 2 (not 3). It may result in further clues.

mikebrady commented 4 years ago

The permissions are good, I think.

[Edit]: It turns out the the location -- inside the /root directory -- is the problem.

cdlenfert commented 4 years ago

Before reading your suggestion to change the log_verbosity I tried moving the pipes, and keeping the same permissions. Putting them in the /home directory worked! What is it about /root that breaks it?

mikebrady commented 4 years ago

Hmm, don’t know. I’ll have to try it!

mikebrady commented 4 years ago

So, I had a look at this. It's definitely a permissions issue.

First, the log indicates the following:

...
Sep 13 12:29:35 raspberryPi4B shairport-sync[5528]: fatal error: Could not create audio pipe "/root/fd-pipes/airpipe"
...

A fatal error causes Shairport Sync to exit immediately.

Upon investigation, a regular user can't even cd into/root and I guess can not traverse it to reach a subdirectory. Here is the situation:

root@raspberryPi4B:~# ls -al
total 28
drwx------  4 root root 4096 Sep 13 12:09 .
drwxr-xr-x 21 root root 4096 Sep  2 18:22 ..
-rw-------  1 root root 1854 Sep 13 12:14 .bash_history
-rw-r--r--  1 root root  603 Sep 11 12:20 .bashrc
drwx------  3 root root 4096 Sep 11 19:13 .config
drwxrwxrwx  2 pi   pi   4096 Sep 13 12:09 fd-pipes
-rw-r--r--  1 root root  148 May 10 21:59 .profile
root@raspberryPi4B:~# exit

...and this is what happens to user pi:

pi@raspberryPi4B:/home $ cd /root/fd-pipes
-bash: cd: /root/fd-pipes: Permission denied

Looking at the permissions of /root and /home:

root@raspberryPi4B:~# stat /root
  File: /root
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: b302h/45826d    Inode: 40002       Links: 4
Access: (0700/drwx------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-08-20 11:47:14.665346009 +0100
Modify: 2020-09-13 12:09:27.903332641 +0100
Change: 2020-09-13 12:09:27.903332641 +0100
 Birth: -
root@raspberryPi4B:~# stat /home
  File: /home
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: b302h/45826d    Inode: 16002       Links: 4
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2020-08-20 11:47:10.513273671 +0100
Modify: 2020-09-11 12:35:43.278720358 +0100
Change: 2020-09-11 12:35:43.278720358 +0100
 Birth: -

The differences are group and world read and execute permissions. IIRC the x bit gives permission to traverse a directory.

BTW, I'd question the wisdom of putting these things in any part of /root in the first place. It seems to me that it would be preferable to run Shairport Sync at the lowest level of user and group privilege that you can possibly get -- hence the definition of the shairport-sync user and group.

cdlenfert commented 4 years ago

@mikebrady Thanks for looking into and clarifying all of that. I'll steer clear of /root for future use. I misunderstood its permissions and thought of it as a typical user folder, but it clearly has more strict permissions than this.