Bill Vinson

Using UXplay as an AirPlay server

What is the issue and the solution?

I have a pantry with an A/V receiver with 2 zones - 5.1 in my living room and a stereo setup on my Back screened-in porch. It really only has 2 devices as inputs (why can't they build smaller receivers for simple setups?) - AppleTV 4k and a Mac mini M1 that I have wall-mounted. My receiver doesn't like using just any source as input for Zone 2. Also, Airplay receivers built into consumer grade audio usually aren't all that great, so I came up with this setup.

The Mac mini is running software to act as an AirPlay server. When a client connects, a script I wrote will detect the client (with name resolution), reach out to Home Assistant to power on Zone 2 on the receiver. When the client disconnects from AirPlay, there will be a request to power down Zone 2. If you have any way in which to use rest calls to control your Home Receiver, this could be adapted, but it will be fairly specific to your home setup.

I use the Yamaha legacy integration for Home Assistant to control my receiver.

One additionl inclusion that if not configured, should just be ignored is the use of Pushover for notifications. Each time a client connects and the audio is turned it, I get a notification saying that has happened and if resolvable, what the client's hostname is. Upon disconnect, I get just get a message that it was turned back off. This was largely added as a troubleshooting mechanism as a previous method of detecting audio was much more prone to trigger inadvertantly, I wanted to know when it happened. Still, I find is useful today, so it remains.

Setup Steps

Disable the AirPlay Receiver in System Settings

This may work with the default implementation, but this was originally built out on an older macOS where that wasn't available and I've stuck with what works.

Install HomeBrew

Run the following terminal command to install some necessary components:

brew install cmake libplist openssl@3 pkg-config

Install both the runtime and development installers for GStreamer

Clone the UxPlay git repo

git clone https://github.com/FDH2/UxPlay

Run the following terminal command to build UxPlay:

cd UxPlay; cmake . && make && sudo make install

Setup uxplay to run as a Launch Agent. This is possible to do manually, but I prefer to use Lingon. My config is as follows:

Utilize my automation script that can be found in my scripts repo. There are 4 necessary files as written, but it would be very easy to strip out some of the extraneous behavior if it isn't relevant to your use.

Setup the script to run, again, as a Launch Agent [1]. My config is as follows:


  1. Launch agents and daemons are mostly interchangable terms, but within the system, a daemon runs at the system level whereas the agent runs within the user's context. In the case of the detect_audio_stream.py, it could likely run as either, but given that it's looking at a process (uxplay) that is run by my user, no elevated permissions are necessary. ↩︎