Skip to content

Repository files navigation

odio

odios

Turns a Raspberry Pi or any Debian-based Linux into a multi-source audio streamer.

Release License Build GitHub Sponsors All Contributors

Bluetooth AirPlay Spotify Connect UPnP / DLNA MPD Multi-room Tidal & Qobuz PulseAudio TCP

Part of the odio project — Full documentation.

Debian Go htmx Tailwind CSS Python Ansible Bash GitHub Actions Svelte Astro Starlight

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.

Home Assistant integration

Architecture

┌─────────────────────────────────────────────────────┐
│                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.

Components

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

Installation

Raspberry Pi (pre-built image)

The fastest way to get started on a Raspberry Pi: flash a pre-built image with Raspberry Pi Imager.

  1. Open Raspberry Pi Imager
  2. Go to Options app > Content Repository > Use custom URL
  3. Enter:
    https://github.com/b0bbywan/odios/releases/latest/download/odio.rpi-imager-manifest
    
  4. Select your image, configure hostname/SSH/WiFi/user, and flash

See image-builder/README.md for details and manual flashing options.

Any Debian/Ubuntu system (installer)

curl -fsSL https://github.com/b0bbywan/odios/releases/latest/download/install.sh | bash

The 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.

Settings page

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.

Upgrading

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-api

odioctl 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.

Recommended clients

Client Protocol Platform
odio-pwa odio REST API Any (browser)
MALP MPD Android
BubbleUPnP UPnP/DLNA Android / iOS

odio vs Volumio

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 ⚠️ Community plugin only
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

Related projects

  • 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

License

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.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

b0bbywan
b0bbywan

🐛 📝 💻 🖋 🔣 📖 🎨 💡 🤔 🚇 🚧 🧑‍🏫 📦 📆 📣 💬 🔬 👀 🛡️ 🔧 ⚠️
Paolo Battino
Paolo Battino

🐛 📖 💡 🤔 🔬
Frankie Bigslave
Frankie Bigslave

🤔 🔬
Konrad Kollnig
Konrad Kollnig

🐛 💻 💵
Matthias Vitt
Matthias Vitt

🐛
andrum993
andrum993

🐛 🤔
Thomas-O
Thomas-O

🤔
voterpublic
voterpublic

📖
Pleasant-Mind-7122
Pleasant-Mind-7122

🐛 🤔
ThisLeedsGuy
ThisLeedsGuy

🤔
Sterkenzz
Sterkenzz

🔬
2wistd
2wistd

🤔
vascoguita
vascoguita

🚇
Jarny
Jarny

🤔
Antoine L
Antoine L
📖
studioalund
studioalund

🐛 🔬
Fletcher D
Fletcher D

🐛 💻 ⚠️
Tom
Tom

🤔
Pete
Pete

🐛 💵
Mario Lang
Mario Lang

🤔 📖

This project follows the all-contributors specification. Contributions of any kind welcome!