Anything → Everywhere: Bridge DLNA audio streams to AirPlay & Chromecast
Airbridge creates virtual DLNA renderers that forward audio to AirPlay speakers and Chromecast devices. This allows media servers like Music Assistant to stream to these devices through DLNA.
Some AirPlay devices (like Juke Audio multi-zone speakers) have compatibility issues with certain AirPlay implementations. Airbridge works around this by:
- Presenting itself as standard DLNA/UPnP renderers
- Receiving audio streams via HTTP
- Forwarding to AirPlay devices using libraop
- Or sending media URLs to Chromecast devices via CASTV2
- 🎵 Virtual DLNA renderer per AirPlay/Chromecast zone
- 📡 Automatic device discovery (mDNS for both AirPlay and Chromecast)
- 📺 Chromecast support - cast DLNA audio to Chromecast devices
- 🌐 Web admin interface with real-time status updates via WebSocket
- 🎛️ Live playback status (Playing/Idle/Paused) with instant UI updates
- ⚙️ YAML configuration for device filtering and aliases
- 🔊 Volume control support
- 🐳 Docker deployment with Unraid support
- ✅ Comprehensive test suite with CI/CD
- DLNA renderer creation and discovery
- Audio streaming to AirPlay devices
- Chromecast as output target (URL-based media playback)
- Web admin interface with live status updates
- Real-time playback state via WebSocket
- Docker/Unraid/Home Assistant deployment
- Full test suite with CI/CD pipeline
- Chromecast receiver support (casting FROM apps like Spotify TO Airbridge) is blocked by Google's device authentication requirements
docker run -d --network=host -v airbridge-data:/data ghcr.io/kenyonj/airbridge:latestAccess the web admin at http://localhost:8200/admin
Get the pre-built cliraop binary for your platform from libraop releases and place it in the bin/ directory:
mkdir -p bin
# Download appropriate binary for your platform
# Rename to: bin/cliraop-macos-arm64, bin/cliraop-linux-amd64, etc.
chmod +x bin/cliraop-*make buildWeb admin interface (recommended):
./bin/airbridge --webBridge a single device:
./bin/airbridge --serve --target "Guest Bedroom"Test streaming to a device:
./bin/airbridge --test "Guest Bedroom"Usage of ./bin/airbridge:
-db string
Path to SQLite database (default "./airbridge.db")
-port int
HTTP port for DLNA server (default 8200)
-serve
Run as DLNA renderer server (single device)
-target string
Target AirPlay device name (for serve mode)
-test string
Test streaming to device (by name)
-version
Print version
-web
Run with web admin interface
Create a config.yaml file (or place at ~/.config/airbridge/config.yaml):
# HTTP port for the first renderer (subsequent use incremental ports)
http_port: 8200
# Enable automatic discovery of AirPlay devices
auto_discover: true
# Prefix for DLNA friendly names
name_prefix: "Airbridge"
# Optional: Filter to only include specific devices
device_filter:
- "Kitchen"
- "Living Room"
- "Guest Bedroom"
# Optional: Device-specific configuration
devices:
- name: "Kitchen"
alias: "Kitchen Bridge"
port: 8201
- name: "Office"
enabled: false # Exclude this device┌─────────────┐ DLNA/UPnP ┌─────────────────┐ RAOP ┌──────────────┐
│ Media │ ────────────────▶ │ Airbridge │ ────────────▶ │ AirPlay │
│ Server │ │ │ │ Speakers │
│ (MA, Plex) │ │ ┌─────────────┐ │ └──────────────┘
└─────────────┘ │ │ Virtual │ │
│ │ DLNA │ │ CASTV2 ┌──────────────┐
│ │ Renderers │ │ ────────────▶ │ Chromecast │
│ └─────────────┘ │ (URL-based) │ Devices │
└─────────────────┘ └──────────────┘
| Type | Protocol | How it works |
|---|---|---|
| AirPlay | RAOP via cliraop | Airbridge receives audio, transcodes, and pushes to device |
| Chromecast | CASTV2 via go-chromecast | Airbridge sends URL, device pulls media directly |
- Discovery: Airbridge uses mDNS to discover AirPlay (
_raop._tcp) and Chromecast (_googlecast._tcp) devices - SSDP: For each device, it advertises a virtual DLNA MediaRenderer
- SOAP: When a media server (like Music Assistant) connects, it handles AVTransport and RenderingControl SOAP requests
- Streaming:
- AirPlay: Audio is received via HTTP and piped to the
cliraopbinary, which streams to the device - Chromecast: The media URL is sent to the Chromecast, which fetches and plays it directly
- AirPlay: Audio is received via HTTP and piped to the
- Start airbridge:
./bin/airbridge --web - In Music Assistant, go to Settings → Players
- You should see "Airbridge (Device Name)" devices appear as DLNA players
- Select a device and start playing music!
The web admin (--web mode) provides a modern UI for managing renderers:
- Real-time status - See which renderers are Playing, Idle, or Paused (updates via WebSocket)
- Easy renderer creation - Click "New Renderer" to create a virtual DLNA device
- Device discovery - Automatically finds AirPlay and Chromecast devices on your network
- Full control - Start, stop, restart, enable/disable, or delete renderers
# Run with web admin interface
docker run -d --network=host -v airbridge-data:/data ghcr.io/kenyonj/airbridge:latestNote: Host network mode is required for mDNS device discovery and SSDP announcements.
Airbridge is available in the Unraid Community Applications store. Search for "Airbridge" or manually install using the template at unraid/airbridge.xml.
Airbridge is available as a Home Assistant add-on:
- Go to Settings → Add-ons → Add-on Store
- Click the ⋮ menu → Repositories
- Add:
https://github.com/kenyonj/airbridge - Click Close and refresh the page
- Find "Airbridge" in the add-on list and click Install
- Start the add-on and open the Web UI to manage devices
make docker-build
make docker-run- Go 1.22+
- Docker (for building libraop, optional)
- Make
make build # Build airbridge
make clean # Clean build artifactsThe easiest way to run Airbridge locally is with the dev script, which rebuilds and runs in one command:
./scripts/dev.sh --web # Web admin interface (recommended)
./scripts/dev.sh --serve "Device Name" # Single device.
├── cmd/airbridge/ # Main application entry point
├── internal/
│ ├── bridge/ # Unified DLNA bridge with embedded devices
│ ├── database/ # SQLite database for web mode
│ ├── discovery/ # mDNS-based AirPlay and Chromecast discovery
│ ├── httpserver/ # HTTP server for UPnP endpoints
│ ├── player/ # Player implementations (RAOP + Chromecast)
│ ├── renderer/ # Multi-device renderer manager
│ ├── ssdp/ # SSDP announcement/discovery
│ ├── state/ # Playback state management
│ ├── upnp/ # UPnP/DLNA SOAP handlers
│ └── web/ # Web admin interface
├── pkg/
│ ├── config/ # YAML configuration
│ └── raop/ # cliraop subprocess wrapper
└── unraid/ # Unraid Community Apps template
make test # Run all tests
make lint # Run golangci-lint
go test -race ./... # Run with race detection- ✅ Juke Audio 8-zone multi-room speakers (AirPlay)
- ✅ HomePod mini (AirPlay)
- ✅ Apple TV (AirPlay)
- ✅ Sonos (AirPlay mode)
- ✅ Google Chromecast (Chromecast)
- ✅ Google Nest Hub (Chromecast)
- Ensure your device is on the same network
- For AirPlay:
dns-sd -B _raop._tcp - For Chromecast:
dns-sd -B _googlecast._tcp - Check firewall settings allow mDNS (port 5353 UDP)
- Verify cliraop binary is in
bin/directory - Test directly:
./bin/airbridge --test "Device Name" - Check logs for connection errors
- Ensure the media URL is accessible from the Chromecast's network
- Chromecast pulls the media directly - it needs to reach the URL
- Check logs for CASTV2 connection errors
- Ensure port 8200+ is not blocked by firewall
- Try:
curl http://localhost:8200/device.xmlto verify HTTP server
When changing the default port in Unraid:
- Set the
AIRBRIDGE_PORTenvironment variable to your desired port - Expand Advanced View in the container settings
- Update the WebUI field to match the same port (e.g.,
http://[IP]:[PORT:XXXX]/admin)
MIT License - see LICENSE
If you find Airbridge useful, consider supporting development:
- philippe44/libraop - RAOP client library
- vishen/go-chromecast - Chromecast client library
- tr1v3r/rcast - DLNA renderer reference
- grandcat/zeroconf - mDNS library

