termusic: a terminal music player written in Rust as four cooperating crates
Music Player TUI written in Rust
At a glance
- What is it?
- A TUI audio player that downloads from YouTube and NetEase and writes lyrics and cover art back into the files, split across a client, a server and two libraries.
- Who is it for?
- termusic is a good fit for someone who already lives in a terminal, wants a local library rather than a streaming subscription, and is comfortable compiling a Rust project that pulls in ALSA, D-Bus and protobuf headers. The playback layer is genuinely useful on its own, since the same tracks and codecs work across a pure Rust backend, mpv and Gstreamer, so you pick the backend when you build rather than when you configure it at runtime.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 16 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why the author rewrote a Go player in Rust
The README is unusually direct about the origin. The author contributed to GOMU, an earlier Go terminal music player, and describes the problem that pushed him to start over: a data race condition. His conclusion is that Rust would fix it, and the project description in the crate metadata reflects the same reasoning by naming Rust as the language.
That origin story matters for judging the codebase, because the repository tree is shaped like a rewrite rather than a single binary. There are four top-level crate directories: `lib/`, `playback/`, `server/` and `tui/`. The `Cargo.toml` workspace makes the split explicit:
[workspace]
members = ["lib", "playback", "server", "tui"]The dependency comments give you the intent for two of them. `termusic-lib` is listed as a crate reference for shared code, and `termusic-playback` is pulled in with `default-features = false` so that a consumer can choose its backend instead of inheriting one. A protobuf dependency, plus `protobuf-compiler` in the build dependency table, is what carries messages between the server and the TUI.
One player, three playback backends chosen at compile time
The most interesting decision is that playback is a compile-time feature rather than a runtime setting. The format tables in the README cover MP4, MP3, OGG, FLAC, ADTS, WAV, AIFF, CAF and MKV, and each row is scored against three columns named Rusty, MPV and Gstreamer. Metadata support is a separate column, and CAF and MKV are marked as playable but not metadata-readable.
The codec table is where the gaps show. HE-AAC is unsupported by the Rusty backend, and Opus is marked unsupported there too unless you enable the `rusty-libopus` feature. Everything else lines up. So the Rust backend is the default and the least capable, MPV and Gstreamer are the complete ones, and the README is candid about which codec costs you an extra dependency.
Because the choice happens at build time, the Makefile has a target per backend:
cargo build --no-default-features --features cover,mpv --release --all
cargo build --no-default-features --features cover,gst --release --allBoth commands comment that they disable the Rusty default. If you plan to play Opus or HE-AAC, you are choosing mpv or Gstreamer at compile time, which is the main decision the project asks you to make up front.
Building from source and getting the binary onto your PATH
The minimum supported Rust version is 1.90.0 according to the README badge, and `Cargo.toml` sets `rust-version = "1.90"` to match. The README warns that turning on non-default features can push the requirement higher, and the dependency table flags `libopus` as needing 1.89.0 specifically.
The Linux build dependencies are heavier than a typical Rust program: `clang` for general build tools and the SQLite compile, `protobuf-compiler` for the server to TUI protocol, `libdbus-1-dev` for MPRIS media control and `libasound2-dev` for ALSA headers. The Windows table lists the `winget` equivalents, including `Microsoft.VisualStudio.BuildTools` and `Google.Protobuf`.
Running and installing both go through the Makefile:
cargo run
make all-backends
make install`make all-backends` exports `CARGO_PROFILE_RELEASE_LTO=off` before building with `cover,all-backends`, which suggests link-time optimisation and the full feature set conflict. The `install` target chains `release` and `post`, and `post` copies two binaries into the Cargo bin directory, not one: `termusic` and `termusic-server`. Having both on your PATH is a prerequisite, since the TUI is a client talking to a separate process.
Downloading from YouTube and embedding metadata back into files
This is the part that distinguishes termusic from a plain local player. The crate description says it can download music from YouTube, NetEase, Migu and KuGou, then embed lyrics and album photos into MP3, M4A, FLAC, WAV and OGG Vorbis files. The README frames this as two separate arguments, freedom from provider lock-in and no monthly membership.
The toolchain doing the downloading is external. The dependency table lists `yt-dlp` as the downloader and `ffmpeg` as its post-processor, and neither is marked as a Rust build-time dependency. The MPV and Gstreamer packages also appear in that same table under their feature columns, so `make all-backends` is only meaningful on a machine where those libraries are already installed.
The file list gives a hint about what else the project does. `lib/` handles tags, since the dependency list pulls in `lofty` for audio metadata, `id3` for ID3 tags, `opml` for podcast subscription lists and `quick-xml`. There is a `screenshots/` directory with a `main.png` and a `tageditor.png`, so tag editing is a first-class screen in the TUI rather than a side effect of downloading.
A client and a server, with MPRIS on the side
The `server/` directory and the separate `termusic-server` binary are the structural difference from a conventional TUI. The dependency table describes `protobuf-compiler` as the communication protocol between server and client, which tells you the TUI is a thin front end and the playback and library logic sit behind an RPC boundary.
The practical question is whether that separation helps you. For a single user on one machine it adds a process to supervise and a protobuf schema to keep consistent. For anyone who wants the library indexed once and driven from more than one place, it is the reason the project is split this way.
`libdbus-1-dev` is listed for MPRIS media control, so the player exposes itself on the desktop session bus. That means hardware media keys and desktop widgets can control it, which is a real advantage over a TUI that only answers to its own keybindings. The tree also holds a `CHANGELOG.md`, a `cliff.toml` for generated commit logs and a `BuildForArmv7.md`, so cross-compilation to armv7 has been attempted and documented.
The last push was on 2026-09-22, and the most recent release, v0.13.2, went out on 2026-05-06. Version numbers in `Cargo.toml` read 0.13.2 throughout, so the released crate and the source tree agree.
The license question the repository does not resolve
Two license signals disagree here, and it is worth naming both. The repository is tagged GPL-3.0, while the workspace metadata in `Cargo.toml` declares `license = "MIT"`. The root directory carries both `LICENSE_GPLv3` and `LICENSE_MIT`, so neither file has been deleted.
A common pattern explains it without settling it: a GPL-3.0 project can relicense individual crates to MIT while keeping the aggregate under GPL. If that is what happened, the per-crate licenses in `lib/Cargo.toml`, `playback/Cargo.toml`, `server/Cargo.toml` and `tui/Cargo.toml` would tell you which is which, and reading those files is the only way to know. The workspace-level `license` field is not a substitute for that.
Practical impact depends on what you do with the code. Vendoring the whole binary into a proprietary product is a different question from depending on the `termusic-lib` crate from a permissively licensed internal service. Nobody should take a legal conclusion from a single metadata field, and this article does not give one. Read both license files and, if it matters commercially, ask upstream.
There is also a `CONTRIBUTING.md` and a `committed.toml`, which usually governs commit message format. Development and CI expectations are documented in those rather than in the README, so a contributor reading only the README will miss them.
Editorial conclusion
termusic is a good fit for someone who already lives in a terminal, wants a local library rather than a streaming subscription, and is comfortable compiling a Rust project that pulls in ALSA, D-Bus and protobuf headers. The playback layer is genuinely useful on its own, since the same tracks and codecs work across a pure Rust backend, mpv and Gstreamer, so you pick the backend when you build rather than when you configure it at runtime. What the project does not settle is the licensing question, because the repository is tagged GPL-3.0 while the workspace package metadata says MIT and both license files sit in the root. Before you vendor any of this into a closed-source product, read LICENSE_GPLv3 and LICENSE_MIT yourself. Start with make all-backends to see every codec path compile, then cut back to a single backend once you know which one you actually need.
Frequently asked questions
What is a good music player for the terminal?
It depends on whether you want a local library or a streaming front end. termusic is built for the first case: it downloads tracks with yt-dlp and ffmpeg, then writes lyrics and cover art into the files themselves, and it plays a wide format range through a Rust, mpv or Gstreamer backend chosen when you compile it.
Do I need mpv or Gstreamer to build termusic?
No, not for the default build. The Makefile builds a Rusty backend with cargo build --release --all, and mpv and Gstreamer appear only in the feature sets for their own targets. You need them if you want HE-AAC or Opus, since the README marks both as unsupported in the Rusty backend.
Is termusic licensed under GPL or MIT?
The repository carries a GPL-3.0 tag while the Cargo.toml workspace declares license = "MIT", and both LICENSE_GPLv3 and LICENSE_MIT sit in the root. The workspace field probably describes the shared crate rather than the whole project, but the per-crate manifests are what actually settle it, so read those before you depend on it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tramhao-termusic)