Python 3.13 CLI for converting audio rips into a clean tagged library, browsing and playing it via a Textual TUI, and streaming it over Tailscale via a Subsonic-compatible HTTP server.
The lowest-friction way is uvx — it downloads, caches, and runs the latest published musickit in one step. No install step required:
uvx musickit --helpFor daily / persistent use (PATH-installed, no per-run network check):
uv tool install musickit
musickit --helpYou'll also need ffmpeg and ffprobe on $PATH for the convert pipeline:
brew install ffmpeg # macOS
sudo apt install ffmpeg # Debian / Ubuntuuvx musickit convert ./input ./output # convert
uvx musickit library audit ./output # audit
uvx musickit tui ./output # TUI
uvx musickit serve ./output # Subsonic server
uvx musickit playlist gen ./output --seed <track> --minutes 60 # auto-generate a mixThe TUI: artist browser on the left, drilled into an album, 48-band visualizer at the top.
Fullscreen visualizer (f):
More screenshots in the TUI guide.
Full docs are at docs/ — built with MkDocs Material. Run them locally:
make docs-serve # http://127.0.0.1:8000Or jump straight to:
- Architecture — how all the pieces fit together (process model, data flow, audio subprocess, SQLite index, FFT visualizer)
- Quickstart — end-to-end walkthrough including iPhone + Tailscale + Amperfy
- musickit convert — codec / bitrate / enrichment matrix
- musickit library — audit rules + auto-fix + SQLite index
- musickit tui — TUI: local + radio + Subsonic-client + AirPlay
- musickit serve — Subsonic API + Tailscale + clients
- musickit playlist — auto-generated
.m3u8mixes anchored to a seed track - Edge cases — every weirdness encountered on real rips
- Roadmap — what's next
- Development — directory layout + test patterns + commit style
v0.6.2 · ruff + mypy + pyright clean, full pytest suite green. Six top-level commands — convert, library, inspect, tui, serve, playlist — with library carrying the read / mutate / manage subcommands (tree, audit, fix, cover, cover-pick, retag, index) and playlist carrying gen / list / show. The TUI ships local-library playback, internet radio, Subsonic-client mode, AirPlay output (incl. pause + volume routing), mDNS discovery, ReplayGain normalisation, an incremental /-filter, in-place tag editing (e for track / album-wide), a 48-band FFT visualiser, and click-to-seek on the progress bar. Audio decoder + sounddevice callback run in a separate process so UI work in the main interpreter can't stall playback. The server is OpenSubsonic-compatible (multipleGenres, transcodeOffset, songLyrics extensions) and tested against Symfonium / Amperfy / play:Sub / Feishin clients on iOS / Android / desktop. A persistent SQLite library index at <root>/.musickit/index.db makes cold starts skip the filesystem walk + tag read; the filesystem watcher does per-album incremental rescans.
See LICENSE in the repo root.