[RPi4] AirPlay from PipeWire

  • I run LE 12.0 nightly 2024-11-29 on RPi4B. Streaming audio from my iPad mini using AirPlay to the device works smoothly. But I now found that pipewire can use AirPlay to send audio to a device and wanted to see if I could make my Arch Linux laptop stream audio to the RPi4B. I have /etc/nsswitch.conf and avahi-daemon.service set up and port 5353 UDP open and followed the instructions here: https://docs.pipewire.org/page_module_raop_discover.html using the example configuration as starting point.

    The RPi4B are discovered and I can send audio to it from the laptop and it's seemingly playing from there. But on the LE12 side I get the spinning wheel on screen as soon as the stream hits, but then nothing more happens (nothing playing). I tried to tweak various knobs in the configuration file example from docs.pipewire.org, but to no avail. Anybody got a working configuration for this or some pointers to stuff I could try...?

  • There's nothing to change on the LE side because Kodi provides a working AirPlay target that devices can stream to - You proved that with the iPad mini. Ergo, if nothing happens (or wrong things happen) when you stream from the Arch device; something is wrong with the stream that you send.

    It's not an LE problem but if you want us to guess at the issue I'd start by sharing the Arch discover.conf file so we can see what sink properties are being used. Plus a Kodi debug log that might show the inbound stream details (or not, I'm guessing).

  • There's nothing to change on the LE side because Kodi provides a working AirPlay target that devices can stream to - You proved that with the iPad mini. Ergo, if nothing happens (or wrong things happen) when you stream from the Arch device; something is wrong with the stream that you send.

    It's not an LE problem but if you want us to guess at the issue I'd start by sharing the Arch discover.conf file so we can see what sink properties are being used. Plus a Kodi debug log that might show the inbound stream details (or not, I'm guessing).

    Yes, this is not a bug report, just looking for some pointers in case someone had tried this. :)

    The raop-discover.conf I used are the example from pipewire.org. I tried to toggle various of the commented out settings here, but all of them failed, so I was thinking maybe someone had a working config. However the starting point are this:

    The Kodi debug log after a failed attempt:

    https://paste.libreelec.tv/careful-stork.log

  • This is what Kodi announces over mDNS:

    In theory the discover module should be automagically creating an Airplay sink based on the advertised properties (S16,44100,2-ch,etc.) and nothing more than this should be needed:

    Code
    context.modules = [
       {
           name = libpipewire-module-raop-discover
           args = { }
       }
    ]

    What does the output from pactl list sinks show?

  • What does the output from pactl list sinks show?

    On the Arch laptop, I expect? On the LE12 RPi it shows only the librespot pa sink, unrelated.

    I installed only your barebones config this time, globally. Result the same. Output from pactl on laptop (the second entry, "himinbjorg" are the LE12 RPi AirPlay autodiscovered sink) :

  • I'd be interested in this as well, but could not get it to work. libshairplay on Kodi seems to expect a pretty special format/be picky. Maybe pipewire also only supports streams Apple devices like to see. Airvia on Android also initially did not work though it worked with Apple devices (https://github.com/jazzy1133/airvia/issues/2).

    For the time being, I succeeded in streaming to the Pulseaudio socket of Libreelec, like so.
    Open protocols are better anyway.

    On Libreelec:

    Code
    systemctl stop kodi; pactl load-module module-udev-detect; pactl load-module module-native-protocol-tcp auth-ip-acl=192.168.0.0/16; systemctl start kodi #Adapt IP range
    
    pactl list sinks #shows all sinks
    pactl get-default-sink #should give the ALSA device name you need for the pulse.target later on

    This could be scripted to happen on every boot.
    You should see an open port now with netstat -pant | grep 4713.

    On the Linux box, create ~/.config/pipewire/pipewire.conf.d/kodi-pulse.conf (adapt libreelec IP or probably use DNS?)

    Restart the whole stack.

    openRC based Distros:

    Code
    rc-service --user pipewire start && rc-service --user pipewire-pulse start && rc-service --user wireplumber start 

    systemd based ones (untested; if all else fails, logout and back in):

    Code
    systemctl --user restart pipewire.service && systemctl --user restart pipewire-pulse.service && systemctl --user restart wireplumber.service


    My Enlightenment Pulseaudio widget now shows "LibreELEC HDMI" as a sound card and it works nicely (and pretty latency free).

    Only drawback: If you watch a movie on Kodi (DVD in my case) and pause it, you will get static after resuming instead of normal audio. Only fixable by unloading the PA module loaded above and restarting Kodi it seems.
    That's why it's no real permanent solution yet.
    But it does work and maybe Kodi can be reconfigured to use a different way to interact with pulseaudio so both work concurrently. I did not investigate any further how Kodi actually uses the audio hardware (ALSA? Pulse?)