qobuz-bridge

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.

On this page