Navidrome
Navidrome is a self-hosted music server and streamer. It provides a web-based interface for browsing and playing your music library from any browser or Subsonic-compatible app.
Via a client machine on PulseAudio TCP
Section titled “Via a client machine on PulseAudio TCP”The simplest path doesn’t need any Navidrome-side configuration at all. Navidrome streams audio to the browser or Subsonic client on your laptop/desktop as usual, and that machine is routed to the odio node via PulseAudio TCP. The audio plays locally from the client’s perspective, but it lands on the odio node’s HiFiBerry instead of the client’s speakers.
This assumes a Linux client running PulseAudio, or PipeWire with pipewire-pulse, since that’s what lets the machine target a remote PulseAudio sink. The client also needs to be on the same local network as the odio node, PulseAudio TCP is not meant to cross the internet (unencrypted, LAN-only).
This is the Desktop & Laptop use case applied to Navidrome, nothing Navidrome-specific, any application on a machine routed to an odio node behaves the same way.
Jukebox mode
Section titled “Jukebox mode”Navidrome’s jukebox mode plays audio through a local mpv process on the Navidrome host instead of streaming to the browser. Pointed at an odio node via PulseAudio TCP, Navidrome becomes a full-fledged music server that drives the node’s DAC directly, remote-controlled from any Subsonic-compatible client.
How it connects to odio
Section titled “How it connects to odio”odio exposes a network PulseAudio sink. Setting PULSE_SERVER on the Navidrome process (or container) to the odio node’s IP is enough for mpv to route audio there. No odio-side configuration needed beyond having the PulseAudio TCP sink enabled.
Finding the right mpv device name
Section titled “Finding the right mpv device name”mpv enumerates PulseAudio sinks by their PulseAudio name. With PULSE_SERVER pointing at your odio node, run:
PULSE_SERVER=192.168.x.x mpv --audio-device=helpSee mpv’s audio output documentation for the device naming convention. Pick the entry that matches your node’s DAC, it will look something like pulse/alsa_output.platform-soc_sound.stereo-fallback.
Navidrome configuration
Section titled “Navidrome configuration”In navidrome.toml (or config.toml, depending on your setup), declare the jukebox devices and pick a default:
Jukebox.Enabled = trueJukebox.Devices = [ [ "auto", "auto" ], [ "pulse", "pulse/alsa_output.platform-soc_sound.stereo-fallback" ],]Jukebox.Default = "pulse"Docker example
Section titled “Docker example”Running Navidrome in Docker works the same way, PULSE_SERVER is passed as an environment variable. Example docker-compose.yml:
services: navidrome: image: deluan/navidrome:latest container_name: navidrome user: 1000:29 # should own the config/data volumes restart: unless-stopped environment: ND_CONFIGFILE: "/config/config.toml" PULSE_SERVER: "192.168.1.6" volumes: - "./config:/config" - "./data:/data" - "/path/to/Music:/music:ro" networks: - webWith PULSE_SERVER set, the mpv process inside the container streams straight to the odio node, no extra networking plumbing required.