A bridge between Qobuz Connect and DLNA speakers. Also supports local audio playback.
Qobuz has a "Connect" feature (similar to Spotify Connect) that lets you control playback on supported devices from their app. Unfortunately, many popular speakers — most notably Sonos — don't support Qobuz Connect natively. This means you can't pick a Sonos speaker as a playback target in the Qobuz app, even though Sonos fully supports DLNA/UPnP streaming.
QobuzProxy solves this by acting as a virtual Qobuz Connect device on your network. When you open the Qobuz app, QobuzProxy shows up as a selectable speaker. When you play music, it receives the stream from Qobuz and forwards it to your DLNA-compatible speaker (like Sonos), preserving hi-res audio quality.
In short: Run QobuzProxy on a Raspberry Pi (or Docker or any always-on machine) on your local network, and your Sonos speakers become fully controllable Qobuz Connect targets — play, pause, skip, and adjust volume, all from the official Qobuz app.
- Appears as a Qobuz Connect device in the official Qobuz app
- Streams audio to DLNA renderers (Sonos, Denon HEOS, etc.)
- Local audio playback via PortAudio (play directly through your machine's speakers/DAC)
- Auto-detects device capabilities to select optimal audio quality
- Runs on Raspberry Pi, Docker, or any Linux/macOS system
pip install qobuz-proxy
# For local audio playback support (optional)
pip install qobuz-proxy[local]Use the built-in discovery tool to find DLNA devices on your network:
qobuz-proxy --discoverExample output:
Scanning for DLNA renderers (3.0s timeout)...
Found 2 DLNA renderer(s):
Living Room Sonos
IP: 192.168.1.50
Port: 1400
Model: Sonos Play:5
Manufacturer: Sonos, Inc.
Bedroom HEOS
IP: 192.168.1.51
Port: 60006
Model: Denon HEOS 1
Manufacturer: Denon
Config example (add to config.yaml):
backend:
dlna:
ip: "192.168.1.50"
port: 1400
Options:
--timeout 10- Increase discovery timeout (default: 3 seconds)--json- Output as JSON for scripting
qobuz-proxy --email your@email.com --password yourpassword --dlna-ip 192.168.1.50By default (max_quality: auto), QobuzProxy queries your DLNA device's capabilities and automatically selects the best supported quality. You can also set a specific quality level:
| Value | Format |
|---|---|
auto |
Auto-detect from device (recommended) |
5 |
MP3 320 kbps |
6 |
FLAC CD (16-bit/44.1kHz) |
7 |
FLAC Hi-Res (24-bit/96kHz) |
27 |
FLAC Hi-Res (24-bit/192kHz) |
qobuz:
max_quality: auto # or 5, 6, 7, 27Or with a config file:
qobuz-proxy --config config.yamlQobuzProxy can also play audio directly through your machine's speakers or DAC, without needing a DLNA device. This requires the local extra dependencies:
pip install qobuz-proxy[local]Then start with the --backend-type local flag:
qobuz-proxy --email your@email.com --password yourpassword --backend-type localYou can list available audio devices and select a specific one (e.g. a USB DAC):
qobuz-proxy --list-audio-devices
qobuz-proxy --backend-type local --audio-device "USB DAC" --email ...-
Copy
.env.exampleto.envand fill in your credentials:cp .env.example .env nano .env # Edit with your values -
Build and run:
docker-compose up -d
-
View logs:
docker-compose logs -f
Important: QobuzProxy requires network_mode: host for mDNS discovery to work. This allows the Qobuz app to find the device on your local network.
If you cannot use host networking, consider:
- Using a macvlan network with a dedicated IP on your LAN
- Running QobuzProxy directly on the host (not in Docker)
Configuration can be provided via:
-
Environment variables (recommended for Docker): Set variables in
.envfile or directly indocker-compose.yaml -
Config file (mounted volume):
volumes: - ./config.yaml:/app/config.yaml:ro
-
Credentials cache (optional, persists Qobuz app credentials):
volumes: - /path/to/cache:/home/qobuzproxy/.qobuz-proxy
This caches the Qobuz web player credentials so they don't need to be re-scraped on each restart. The container runs as user
qobuzproxy, so the path is/home/qobuzproxy/.qobuz-proxy(not/root/.qobuz-proxy).
| Port | Purpose |
|---|---|
| 8689 | HTTP server for mDNS discovery |
| 7120 | Audio proxy for DLNA streaming |
With network_mode: host, these ports are exposed directly on the host.
The container includes a health check that verifies the HTTP server is responding:
docker inspect --format='{{.State.Health.Status}}' qobuz-proxy# Create virtual environment
python3 -m venv venv
source venv/bin/activate
# Install with dev dependencies
pip install -e ".[dev]"
# Include local audio backend
pip install -e ".[dev,local]"
# Run
qobuz-proxy --help
# Test
pytest
# Code quality
black qobuz_proxy/ tests/
ruff check qobuz_proxy/ tests/
mypy qobuz_proxy/This project is based on the Qobuz Connect reverse-engineering work done by Tobias Guyer in StreamCore32. Thanks to his efforts in figuring out the Qobuz Connect protocol, this project was possible.
This project was built almost entirely through agentic programming using Claude Code. The architecture, implementation, and tests were generated through AI-assisted development with human guidance and review.
MIT