← Projects
MIT · Open source

qobuz-bridge

Background daemon that bridges Qobuz into macOS Now Playing — Control Center tile, artwork, and working media buttons

Features

  • Control Center tile — Qobuz becomes a first-class macOS Now Playing citizen: track title, artist, album, and artwork appear in Control Center just like any native player.
  • Working media buttons — next, previous, and play/pause from Control Center (or your keyboard's media keys) are routed back to Qobuz via a system-level event tap.
  • Rich artwork — album art is pulled from Qobuz's CDN and pushed live to the Now Playing slot, updating as tracks change.
  • Auto-start on login — a single qobuz-bridge install writes a launchd agent plist so the daemon starts automatically at login and restarts if it crashes.
  • No polling overhead — metadata is read from Qobuz's local player-0.json state file on a 3-second interval; no extra network calls for position tracking.
  • Three-package composition — thin orchestration layer that wires @kud/qobuz, @kud/macos-nowplaying-bridge, and @kud/macos-media-keys together with no duplicated logic.

Install

npm install -g @kud/qobuz-bridge

Requires macOS and Node.js ≥ 20. The Qobuz desktop app must be installed, and a Qobuz token must be present in the macOS Keychain (as set up by @kud/qobuz). The install command's daemon process needs Accessibility permission to intercept media keys.

Usage

$ qobuz-bridge
qobuz-bridge running — open Control Center. Ctrl-C to quit.
now playing → Intro — The xx

$ qobuz-bridge install
installed login item → ~/Library/LaunchAgents/io.kud.qobuz-bridge.plist
logs → ~/Library/Logs/qobuz-bridge.log

$ qobuz-bridge uninstall
removed login item → ~/Library/LaunchAgents/io.kud.qobuz-bridge.plist
CommandEffect
qobuz-bridgeRun the daemon in the foreground (Ctrl-C to quit)
qobuz-bridge installRegister a launchd login item; starts the daemon now
qobuz-bridge uninstallRemove the login item (daemon stops at next reboot)

Logs from the background daemon are written to ~/Library/Logs/qobuz-bridge.log.

Known limitation: player-0.json exposes the playback position but not a discrete play/pause flag, so the bridge reports state as "playing" whenever a track is detected. Pause detection will improve once the underlying state file exposes it.

Development

git clone https://github.com/kud/qobuz-bridge.git
cd qobuz-bridge
npm install
npm run dev
ScriptPurpose
npm run buildCompile TypeScript with tsup
npm run devWatch mode
npm run typecheckType-check without emitting
npm startRun the compiled output

📚 Full documentation → qobuz-bridge/docs

Disclaimer

This is an independent, unofficial project — not affiliated with, endorsed by, or sponsored by Qobuz. "Qobuz", the Qobuz logo, and any icons derived from it are trademarks of Qobuz Music, used here only to indicate compatibility.