orators turns a Linux desktop into a Bluetooth speaker. The primary interface is now a Ratatui dashboard that manages pairing, trusted/allowed devices, setup, and backend health. oratorsctl remains available for advanced and scriptable control.
- Linux-first implementation
- Rust workspace with a long-lived daemon, a Ratatui app, and an advanced CLI client
- D-Bus control API on the user session bus
- BlueZ pairing and trusted-device control
- Media-only MVP: A2DP sink playback, no call or mic support
- Managed host install: one BlueALSA system service plus one Bluetooth-only WirePlumber fragment
crates/orators-core: domain types, config, diagnostics, state machinecrates/orators-linux: Linux integrations for BlueZ, BlueALSA, local audio inspection, and systemdcrates/orators: publishable crate with:oratorsfor the TUIoratorsdfor the daemonoratorsctlfor advanced/compat CLI usage
cargo fmt
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspacenix develop
nix flake checkoratorsopens the TUIoratorsdruns undersystemd --useroratorsctltalks to the daemon over the session bus for pairing and device controloratorsctl install-user-serviceinstalls only the user daemon unitoratorsctl install-system-backendinstalls the supported media backend:- root
orators-bluealsad.service - user
~/.config/wireplumber/wireplumber.conf.d/90-orators-disable-bluez.conf
- root
oratorsctl uninstall-system-backendremoves that backend and restores stock WirePlumber Bluetooth ownership
- The system must provide trusted BlueALSA binaries in the expected system locations:
bluealsadbluealsa-aplaybluealsactl
- The host must have a usable local playback output
- WirePlumber stays responsible for the rest of the desktop audio graph, but not Bluetooth media ownership
Example ~/.config/orators/config.toml:
pairing_timeout_secs = 120
auto_reconnect = true
single_active_device = true
adapter = "hci1"
allowed_devices = []
[device_aliases]
"5C:DC:49:92:D0:D8" = "Fold 7"adapteris optional. If omitted, Orators auto-selects the only powered adapter. If multiple powered adapters exist, the managed backend install requires--adapter hciX.device_aliasesare local-only display names. Orators never writes them back into BlueZ.- Legacy Bluetooth-mode fields are still ignored on load so existing configs remain readable.
Run:
oratorsKey workflows:
Tab/Shift-Tab: switch viewsq: quit- Dashboard:
ptoggle pairingiinstall/repair backenduuninstall backend
- Devices:
j/kmoveaallow/disallowttrust/untrustcconnect/disconnectfforgetxreset on hostnset local aliasNclear local alias
- Settings:
Enteredits pairing timeout or adapterEnter/Spacetoggles boolean settings
Examples:
oratorsctl doctor
oratorsctl pair start --timeout 120
oratorsctl devices list
oratorsctl devices allow 5C:DC:49:92:D0:D8
oratorsctl devices alias 5C:DC:49:92:D0:D8 "Fold 7"
oratorsctl config show
oratorsctl config set pairing-timeout 180- Install the daemon unit once with
oratorsctl install-user-service. - Install the managed media backend once with
oratorsctl install-system-backend [--adapter hciX]. - Run
oratorsfor the normal control flow. - Pair a new phone from the Pairing view, then allow it from the Devices view if you want stable reconnect behavior.
- Disconnect Bluetooth audio devices before uninstalling or changing the managed backend.
MIT. See LICENSE.