A lightweight terminal (TUI) client for Subsonic servers — Navidrome, Airsonic, Subsonic, Gonic, etc. Minimal, fast, low resource usage.
- Tabs: Artists, Albums, Playlists
- Playback via rodio (flac / mp3 / vorbis), gapless preloading of the next track
- MPRIS integration (D-Bus): metadata, position, controls, TrackList — works with quickshell widgets and other media controllers
- Loop / shuffle / volume / seek controls
- Local cache: SQLite with manual refresh (
r) — no polling - Single instance, state restore (queue, position, volume) on restart
- Pagination of the album library (never loads the whole collection into memory)
- Streaming to disk, not memory
cargo build --releaseBinary: target/release/selfsonic
cargo run --releaseOn the first run a template config is created at ~/.config/SELFsonic/config.toml (permissions 0600):
[server]
url = "http://127.0.0.1:4533"
username = "user"
password = "password"
[audio]
volume = 0.8
seek_step = 10If the server is a sleeping homelab box, the client retries transport errors with exponential backoff instead of hanging silently.
| Key | Action |
|---|---|
j / k |
move down / up |
g / G |
top / bottom |
Ctrl+d / Ctrl+u |
page down / up |
Tab / Shift+Tab |
next / previous tab |
Enter |
open / play |
Esc |
back |
space |
play / pause |
n / p |
next / previous |
l |
cycle repeat (off → track → all) |
s |
toggle shuffle |
+ / - |
volume |
[ / ] |
seek ±10s |
r |
refresh library from server |
q / Ctrl+q |
quit |
Bus name: org.mpris.MediaPlayer2.SELFsonic. Exposes:
org.mpris.MediaPlayer2(Root)org.mpris.MediaPlayer2.Playerorg.mpris.MediaPlayer2.TrackList(queue as a playlist, withTrackListReplacedsignals)
| What | Path |
|---|---|
| Config | ~/.config/SELFsonic/config.toml |
| Cache DB | ~/.cache/SELFsonic/library.db |
| State (queue/position) | ~/.local/state/SELFsonic/state.json |
| Log | ~/.local/state/SELFsonic/SELFsonic.log |
- TUI: ratatui + crossterm
- HTTP: ureq (sync)
- Audio: rodio
- MPRIS: mpris-server
- Cache: rusqlite, WAL mode
MIT