Features
- Audio-only AirPlay receiver - Stream music from iPhone without screen mirroring
- Seamless output switching - Switch between audio output devices (headset, speakers, etc.) without disconnecting iPhone
- Menu bar app - Minimal, unobtrusive interface lives in your menu bar
- Auto-discovery - iPhone automatically discovers "MacBook AirPlay" via Bonjour/mDNS
- Native Swift - Lightweight, native macOS application
How It Works
┌─────────────┐ AirPlay ┌──────────────────┐ Audio ┌─────────────────┐ │ iPhone │ ───────────────► │ shairport-sync │ ─────────────► │ Output Device │ │ (Music) │ (via WiFi) │ (AirPlay recv) │ (via libao) │ (Headset/Spkrs) │ └─────────────┘ └──────────────────┘ └─────────────────┘ ▲ │ manages │ ┌───────┴──────────────┐ │ AirPlayAudioReceiver │ │ (Menu Bar App) │ └──────────────────────┘
The app is a Swift wrapper around shairport-sync, an open-source AirPlay audio receiver. The menu bar app:
- Starts/stops the shairport-sync daemon
- Advertises "MacBook AirPlay" on the local network
- Allows switching the system default audio output device
- Audio automatically routes to whatever device is set as system default
Requirements
- macOS 12.0 or later
- Homebrew
- shairport-sync (
brew install shairport-sync)
Installation
1. Install shairport-sync
brew install shairport-sync
2. Build the app
cd /path/to/airplay-audio-receiver ./build.sh
This creates AirPlay Audio Receiver.app - a proper macOS application bundle.
3. Install the app
Option A: Automated installer (Recommended)
./install.sh
This script will:
- Copy the app to
/Applications - Optionally add it to Login Items (auto-start on login)
- Offer to launch the app immediately
Option B: Manual installation
Drag AirPlay Audio Receiver.app to your /Applications folder, or run it directly:
open AirPlay Audio Receiver.app
The app will appear in your menu bar with an AirPlay icon (no Dock icon - it's a menu bar app).
Usage
- Start the app:
- Open from Applications folder (search "AirPlay Audio Receiver" in Spotlight)
- Or if added to Login Items during install, it starts automatically on login
- Connect from iPhone:
- Open Control Center on iPhone
- Tap the AirPlay icon
- Select "MacBook AirPlay"
- Switch output devices - Click the menu bar icon and select your preferred output (Logi USB Headset, MacBook Pro Speakers, etc.)
- Play music - Audio from iPhone will play through your selected Mac output device
Menu Options
| Option | Description |
|---|---|
| Output: [Device] | Shows current audio output device |
| Switch Output To: | Lists available output devices to switch to |
| Stop/Start AirPlay Receiver | Toggle the shairport-sync daemon |
| Quit | Stop receiver and exit app |
Architecture
Files
| File | Description |
|---|---|
AirPlayAudioReceiver.swift | Main application source code |
build.sh | Build script that creates the .app bundle |
install.sh | Installation script (copies to /Applications, optionally adds to Login Items) |
AirPlay Audio Receiver.app/ | Compiled app bundle (not tracked in git) |
Components
AudioDeviceManager
Handles CoreAudio interactions:
- Lists available output devices
- Gets/sets the system default output device
- Filters out virtual devices (BlackHole, Multi-Output, etc.)
ShairportManager
Manages the shairport-sync process:
- Starts shairport-sync with proper arguments
- Stops and cleans up processes on exit
- Outputs to system default device via libao's macosx driver
AppDelegate
Main application logic:
- Creates and manages the menu bar interface
- Handles device selection (changes system default output)
- Listens for audio device changes to update menu
Technical Details
Why shairport-sync?
Apple's AirPlay protocol is proprietary. shairport-sync is a mature, open-source implementation that:
- Supports AirPlay 1 (RAOP protocol)
- Works reliably with iOS devices
- Outputs audio via multiple backends (libao, ALSA, PulseAudio, etc.)
Audio Routing
The app uses libao's macosx driver which outputs to the system default audio device. When you switch outputs via the menu:
- The app calls CoreAudio APIs to change the system default output
- shairport-sync (via libao) automatically uses the new default
- No restart required - audio switches seamlessly
Port Usage
- Port 5000 - RTSP control (AirPlay handshake)
- Ports 6001-6010 - UDP audio data
Note: Disable macOS's built-in AirPlay Receiver (System Settings → General → AirDrop & Handoff → AirPlay Receiver) to avoid port conflicts.
Troubleshooting
"App is damaged or incomplete" error
This is a macOS Gatekeeper security feature. The build script now automatically fixes this by:
- Adding an ad-hoc code signature to the app
- Removing quarantine attributes
If you still see this error:
# Remove quarantine and re-sign xattr -cr "AirPlay Audio Receiver.app" codesign --force --deep --sign - "AirPlay Audio Receiver.app"
iPhone can't find "MacBook AirPlay"
- Ensure shairport-sync is running (
ps aux | grep shairport) - Check Bonjour advertisement:
dns-sd -B _raop._tcp - Verify both devices are on the same WiFi network
"Unable to connect" error
- Check if port 5000 is in use:
lsof -i :5000 - Kill any conflicting processes:
pkill -9 shairport-sync - Disable built-in AirPlay Receiver in System Settings
No audio output
- Verify system output device is correct in Sound settings
- Check shairport-sync is using macosx driver: should see
-o ao -- -d macosxin process args - Test audio output:
say "test"
Audio plays but switching devices doesn't work
- Ensure you're selecting devices from the menu bar app (not System Settings)
- The app changes the system default, which should route audio immediately
Building from Source
Requirements
- Xcode Command Line Tools (
xcode-select --install)
Build and Install
# Build the app ./build.sh # Install to /Applications ./install.sh
build.sh creates the app bundle:
- Creates the app bundle structure
- Generates the app icon (blue/purple gradient with AirPlay symbol)
- Compiles the Swift code into the bundle
- Signs the app with ad-hoc signature (fixes macOS Gatekeeper)
- Removes quarantine attributes
install.sh installs the app:
- Copies
AirPlay Audio Receiver.appto/Applications - Optionally adds to Login Items for auto-start
- Offers to launch immediately
Manual Run (without installing)
open AirPlay Audio Receiver.app
License
MIT License - See LICENSE file for details.
Acknowledgments
- shairport-sync - The AirPlay receiver that makes this possible
- libao - Cross-platform audio output library