Turns a Raspberry Pi or any Debian-based Linux into a multi-source audio streamer.
Part of the odio project — Full documentation.
Open-source audiophile distribution for Debian/Ubuntu and Raspberry Pi with native Home Assistant integration.
odios turns a €35 Raspberry Pi into what commercial streamers sell for €300–500: Bluetooth A2DP (in & out), AirPlay, Spotify Connect, Qobuz Connect, Snapcast multi-room, UPnP/DLNA, CD playback with metadata — all in one box, controlled from a web app and managed from a settings page, no SSH, account or subscription required. Other PCs running PulseAudio or PipeWire can also stream directly to it over the network, making it a true whole-home audio sink.
Built on modern foundations: everything runs as unprivileged systemd user services (no root daemons), orchestrated through a unified REST API written in Go. Battle-tested on a Raspberry Pi B+ (armv6l) for over 6 years without reinstall.
Full Home Assistant integration included — odios nodes appear as native media players in your HA dashboard.
┌─────────────────────────────────────────────────────┐
│ odio-pwa (remote) │ ← manage multiple nodes from any device
└────────────────────────┬────────────────────────────┘
│ HTTP
┌────────────────────────▼────────────────────────────┐
│ go-odio-api │ ← unified REST API + embedded UI
│ systemd · PulseAudio · MPRIS · Bluetooth │
│ │
└──────┬──────────┬──────────┬──────────┬─────────────┘
│ │ │ │
PulseAudio MPD Shairport Snapcast
(network) Sync client
Bluetooth MPD (AirPlay) upmpdcli
(A2DP) Disc Spotifyd (UPnP/DLNA)
Player qbzd
(Qobuz Connect)
┌─────────────────────────────────────────────────────┐
│ odioctl (settings, :8021) │ ← upgrades, components, DAC, sign-ins
└─────────────────────────────────────────────────────┘
Most service run as systemd user services — no root daemons, full per-user isolation.
| Component | Role | Session |
|---|---|---|
| go-odio-api | REST API + embedded UI, bridges systemd / PulseAudio / MPRIS (incl. TrackList queue) / D-Bus / Bluetooth Speaker | user |
| odioctl | Settings page (port 8021) and CLI: upgrades, optional components, DAC overlay, Tidal / Qobuz Connect sign-in, reboot | user |
| go-mpd-discplayer | Automatic CD/USB playback with metadata via MPD | user |
| PulseAudio | Central audio server, routes all sources to the DAC output — other PCs running PulseAudio or PipeWire can stream to it over the network via TCP/Zeroconf (wired connections only) | user |
| MPD | Music Player Daemon (network, CD/USB) | user |
| mpd2mpris | MPRIS bridge for MPD with CUE and remote cover art support | user |
| myMPD | Web UI for MPD (default port 8080) | user |
| Shairport Sync | AirPlay receiver | user |
| Spotifyd | Spotify Connect receiver | user |
| qbzd | Qobuz Connect endpoint — optional, off by default, experimental | user |
| Snapcast | Multi-room audio client | user |
| Snapclientmpris | MPRIS bridge for snapclient | user |
| upmpdcli | UPnP/DLNA renderer, with Qobuz, Tidal and web-radio plugins | user |
| Bluetooth | A2DP sink with automatic pairing, plus audio output to Bluetooth speakers/headphones | system |
The fastest way to get started on a Raspberry Pi: flash a pre-built image with Raspberry Pi Imager.
- Open Raspberry Pi Imager
- Go to Options app > Content Repository > Use custom URL
- Enter:
https://github.com/b0bbywan/odios/releases/latest/download/odio.rpi-imager-manifest - Select your image, configure hostname/SSH/WiFi/user, and flash
See image-builder/README.md for details and manual flashing options.
curl -fsSL https://github.com/b0bbywan/odios/releases/latest/download/install.sh | bashThe installer works on both fresh and existing systems (idempotent, safe to re-run). It prompts for a target user — if the user doesn't exist it is created automatically. Installing for an existing user is supported: config files are backed up before any modification. Optional components such as Qobuz Connect are offered as prompts, and can still be added or dropped later from the settings page.
See installer/README.md for full installation options, environment variables, and testing.
Every box serves a settings page at http://<your-box>:8021, also linked from the odio dashboard header. No SSH, no config file to edit:
- Upgrades — shows when a new release is available and applies it, then reports when it is done
- Components — add or drop services on a box already in use (e.g. Qobuz Connect); new optional services ship this way
- Tidal & Qobuz Connect sign-in — the page hands you the sign-in link, you open it, and the service is connected
- DAC — pick the sound card overlay on a Raspberry Pi
- Reboot the box
The page updates itself as things happen, no reload. It is served by odioctl web, socket-activated so it only starts on the first connection.
Each install ships odioctl, the tool behind the settings page. Upgrades show up in the settings page, the odio web UI and Home Assistant, and apply from there. odioctl upgrade check runs daily via a systemd user timer and refreshes /var/cache/odio/upgrades.json; odioctl upgrade apply performs the upgrade.
odioctl upgrade apply # upgrade to the latest reported version
odioctl upgrade apply --version 2026.5.0 # target a specific version
odioctl upgrade apply --reinstall # re-run every role in full (repair a broken install)
odioctl upgrade apply --progress # emit structured progress events for odio-apiodioctl reads /var/lib/odio/state.json (or rebuilds from dpkg as a last resort) to preserve the feature selection and role opt-outs across upgrades. Run odioctl upgrade apply --dry-run --force to see what would be invoked without running it. Use --reinstall to force every role through a full first-install pass (bypassing the smart-upgrade skips) when an install needs repairing. Use --progress to emit structured ODIO_PROGRESS JSON lines (one per role and phase) to stdout for odio-api to display, without altering the normal output.
odioctl components and odioctl dac do from the shell what the settings page does for components and the DAC overlay.
Upgrading from 2026.7.0rc2 or earlier: the command on those boxes is still odio-upgrade apply; once 2026.9.0b1 is applied it becomes odioctl upgrade apply.
| Client | Protocol | Platform |
|---|---|---|
| odio-pwa | odio REST API | Any (browser) |
| MALP | MPD | Android |
| BubbleUPnP | UPnP/DLNA | Android / iOS |
| odio | Volumio | |
|---|---|---|
| License | 100% open source | Partially closed source |
| Price | Free | Freemium — Premium at €60/year |
| Account required | No | Yes |
| Cloud dependency | None | Yes (account, Premium, plugins) |
| Minimum hardware | Raspberry Pi B (armv6l, 2012) | Raspberry Pi 3 |
| Music library management | ✅ Via myMPD (web UI) | ✅ Built-in library browser |
| Bluetooth A2DP | ✅ Included | 💰 Premium only |
| Bluetooth output (speakers/headphones) | ✅ Included | |
| AirPlay | ✅ Included | ✅ Free plugin |
| Spotify Connect | ✅ Included | ✅ Free plugin |
| Qobuz | ✅ Included (via upmpdcli), plus optional Qobuz Connect (qbzd, experimental) | 💰 Premium only |
| Tidal / Tidal Connect | ✅ Included (via upmpdcli) | 💰 Premium only |
| UPnP/DLNA | ✅ Included | ✅ Included |
| Web radios | ✅ Included (upmpdcli + myMPD) | ✅ Included |
| Multi-room | ✅ Included (Snapcast) | 💰 Premium only |
| CD playback | ✅ Included with metadata | 💰 Premium only |
| Network audio sink | ✅ PulseAudio/PipeWire TCP (wired) | ❌ Not supported |
| Home Assistant | Native integration | Unofficial community plugin |
| Voice assistant / AI | Via Home Assistant | 💰 CORRD (Premium) |
| Embedded UI | Lightweight HTMX/Tailwind | Node.js/React |
| Multi-node remote | Svelte PWA (install from browser, no store) | Native mobile app (iOS/Android) |
| Architecture | User session, PulseAudio/PipeWire, Golang | System session, ALSA, Node.js |
| System philosophy | Linux-native modular stack | Appliance-style distribution |
| Debian base | Trixie (stable) | Bookworm (oldstable) |
| Installation | Image flash (Pi) or curl | bash (any Debian/Ubuntu) |
Image flash |
| Upgrade | One click from the settings page / HA, odioctl upgrade, or reflash |
OTA updates / Reflash between major versions |
- go-odio-api — REST API and embedded UI
- odioctl — Settings page and CLI for upgrades, components, DAC and streaming sign-ins
- odio-ha — Full Home Assistant integration: odios nodes appear as native HA media players and can be mapped to official integrations to inherit their full capabilities
- odio-pwa — Progressive Web App to control multiple odios nodes (live)
- go-mpd-discplayer — CD/USB player daemon
- mpd2mpris — MPRIS bridge for MPD with CUE and remote cover art support
- Snapclientmpris — MPRIS bridge for snapclient
This project is licensed under the BSD 2-Clause License — see LICENSE.
The installer distribution (odio-*.tar.gz) includes ansible-core, which is licensed under the GNU General Public License v3.0. A copy of that license is included in the archive under licenses/ANSIBLE-LICENSE-GPLv3.
The odios playbooks and scripts are independent works that invoke ansible-core as an external tool and are not subject to the GPL.
Thanks goes to these wonderful people (emoji key):
b0bbywan 🐛 📝 💻 🖋 🔣 📖 🎨 💡 🤔 🚇 🚧 🧑🏫 📦 📆 📣 💬 🔬 👀 🛡️ 🔧 |
Paolo Battino 🐛 📖 💡 🤔 🔬 |
Frankie Bigslave 🤔 🔬 ✅ |
Konrad Kollnig 🐛 💻 💵 |
Matthias Vitt 🐛 |
andrum993 🐛 🤔 |
Thomas-O 🤔 |
voterpublic 📖 |
Pleasant-Mind-7122 🐛 🤔 |
ThisLeedsGuy 🤔 |
Sterkenzz 🔬 |
2wistd 🤔 |
vascoguita 🚇 |
Jarny 🤔 |
Antoine L 📖 |
studioalund 🐛 🔬 |
Fletcher D 🐛 💻 |
Tom 🤔 |
Pete 🐛 💵 |
Mario Lang 🤔 📖 |
This project follows the all-contributors specification. Contributions of any kind welcome!