A Rust-based Linux TUI music player with spectrum visualization.
This is a Linux terminal (TUI) music player built with Rust. It supports local playback and system monitoring, and includes spectrum visualization.
- Local audio playback
- Local Audio Playback Mode Changes (Playlist Loop / Single Track Loop / Sequential Playback / Shuffle)
- Local Audio Equalizer Support
- System playback monitoring (MPRIS)
- Playlist panel
- Album cover rendering: ASCII art (default) or Kitty graphics (optional, if supported)
- Settings modal (theme, transparent background, album border, visualization mode, Bar settings, Kitty graphics toggle, cover quality, Local audio settings for lyrics/cover fetch & download, audio fingerprinting, AcoustID API key, resume last position, About)
- Lyrics display
- Lyrics fetch: prefers embedded/local LRC (same-name .lrc and lrc/ folder), otherwise async LRCLIB
- Cover fetch: prefers embedded/local cover (including cover/ folder), otherwise async MusicBrainz + Cover Art Archive
- When metadata is missing, optional Chromaprint fingerprint + AcoustID lookup
- Visualization: spectrum bars / oscilloscope (Braille overlay from stereo
cavabars)
- Rust 2021
- TUI: ratatui + crossterm
- Playback: rodio (local), MPRIS (system)
- Visualization:
cava(external bars)
The control buttons and playback mode indicators use Nerd Font icon glyphs. If your terminal font is not a Nerd Font (patched), you may see missing-glyph boxes.
Recommended fonts: JetBrainsMono Nerd Font, FiraCode Nerd Font, Hack Nerd Font (any Nerd Font works).
Icon mapping:
- Play:
- Pause:
- Previous:
- Next:
- Shuffle:
- Repeat one:
- Repeat all:
- Sequential:
Oops, GitHub doesn't seem to support displaying Nerd Font. You can check the icons at https://www.nerdfonts.com/cheat-sheet.
Install build dependencies (names may vary by distro):
sudo apt update
sudo apt install -y pkg-config libasound2-dev libdbus-1-dev libchromaprint-devYou can install it from the AUR:
# Using an AUR helper (e.g., yay)
yay -S tmplayer
# Or manually
git clone https://github.com/professor-lee/TMPlayer.git
cd TMPlayer/AUR
makepkg -siIf installed via AUR, simply run:
tmplayerFor development:
cargo runcargo build --release
./target/release/tmplayerOn first run, the app will create (if missing) its config + theme files under your OS config directory.
- Linux:
$XDG_CONFIG_HOME/tmplayer(usually~/.config/tmplayer)
You can override the root directory with TMPLAYER_ASSET_DIR (it will still use config/ and themes/ under that root).
The app prefers cava for system-wide visualization bars (this project renders the style; cava only provides numeric bars).
If cava is not available, it will fall back to the internal FFT pipeline.
cava executable resolution order:
TMPLAYER_CAVAenvironment variable (absolute/relative path)- Next to the app executable:
./cava - Next to the app executable:
./third_party/cava/cava cavainPATH
If none of the above are available and the app was built with --features bundle-cava, it will extract the embedded cava to a temporary directory for the current session.
Install cava (optional but recommended):
# Debian/Ubuntu
sudo apt install -y cava
# Arch
sudo pacman -S cavaIf you want the project to build its own cava binary automatically (instead of relying on a system package), build with:
cargo build --release --features bundle-cavaThis will download and build upstream cava from source during the Cargo build, then embed the resulting cava binary into the app. At runtime, if no system cava is found, the app will extract it into a temporary directory and use it for the current session (it is deleted when the app exits).
Notes:
- Requires network access during the build.
- To work around autotools macro differences on some distros, the build script injects a minimal
AX_CHECK_GLoverride viaACLOCAL_PATHto avoidautogen.shfailing with_AX_CHECK_GL_MANUAL_LIBS_GENERIC: argument must not be empty. This only affects the optional SDL/OpenGL output path and does not impact the raw bars output used by this project. - Requires system build dependencies for
cava(Ubuntu/Debian example):
sudo apt update
sudo apt install -y \
build-essential autoconf automake libtool pkgconf \
libfftw3-dev libiniparser-dev \
libasound2-dev libpulse-dev libpipewire-0.3-devYou can override the source/version used by the build script:
# override tag
TMPLAYER_CAVA_BUNDLE_VERSION=0.10.6 cargo build --release --features bundle-cava
# override URL (tar.gz)
TMPLAYER_CAVA_BUNDLE_URL=https://github.com/karlstav/cava/archive/refs/tags/0.10.6.tar.gz \
cargo build --release --features bundle-cavaIf you want to enable the feature but skip bundling (e.g. distro packaging / CI), you can:
TMPLAYER_CAVA_BUNDLE_SKIP=1 cargo build --release --features bundle-cavaThis project primarily targets Linux. On native Windows you can try “build/local playback”, but these features are not available or not guaranteed:
- System playback monitoring (MPRIS)
- System volume control (
Up/Down) bundle-cava(autotools-heavy; upstreamcavacapture backends may not be available on Windows)
Recommended: use WSL2 and follow the Linux instructions.
Native Windows (MSVC) build outline:
- Install Rust via
rustup - Install Visual Studio Build Tools (C++ toolchain)
- From the repo root:
cargo build --releaseconfig/default.toml: UI/spectrum/MPRIS + EQ settings (spectrum rate is kept in sync withui_fps)themes/*.toml: theme definitions
Kitty-related settings (in config/default.toml):
kitty_graphics: enable Kitty graphics protocol rendering (default:false)kitty_cover_scale_percent: cover quality in percent (default:100;100means no downscale)
Bars settings (in config/default.toml, bars mode only):
super_smooth_bar: finer height glyphs (default:false)bars_gap: insert gaps between bars (default:false)bar_number: number of bars per side (auto,16,32,48,64,80,96)bar_channels:stereo(mirrored from center using mono data) ormono(low-to-high left→right)bar_channel_reverse: reverse channel mapping (mono flips left↔right; stereo shows high at center, low at edges)
Bar layout notes:
- When gaps are on, each gap is at least half a bar width and the bar count is clamped to fit.
- When gaps are off, bars use at least 2 columns per bar (max bars ≈ half the available width).
- Bar heights use a nonlinear curve to avoid saturating the display too quickly.
Startup settings (in config/default.toml):
default-opening-folder: auto-open a local folder on launch (default:""; if missing/invalid, it will be cleared)
Lyrics/cover and fingerprint settings (in config/default.toml):
lyrics_cover_fetch: enable async lyrics/cover fetch (default:false)lyrics_cover_download: save fetched lyrics/cover locally (default:false)audio_fingerprint: enable audio fingerprinting (default:false, requires AcoustID API key)acoustid_api_key: AcoustID API key (set via Settings modal)resume_last_position: resume last local track position on launch (default:false; stored per folder in.order.toml, seconds precision)
Downloaded storage paths (when enabled):
- Lyrics: lrc/ folder next to the audio file, same filename (.lrc)
- Cover: cover/ folder next to the audio file, same filename (.jpg/.png)
Default locations (Linux):
~/.config/tmplayer/config/default.toml~/.config/tmplayer/themes/*.toml
Open the in-app help at any time with Ctrl+K.
| Key | Action |
|---|---|
Ctrl+F |
Open folder input |
P |
Toggle playlist |
Space |
Play/Pause |
Left / Right |
Prev / Next |
Up / Down |
Volume up / down |
E |
Open the equalizer (local) |
Alt+R |
Reset equalizer to default (in EQ modal) |
M |
Toggle repeat mode (local) |
T |
Open Settings |
Ctrl+K |
Open Keys (help) |
Enter |
Confirm (folder input / playlist) |
Q |
Quit |
Esc |
Close overlays/modals |
When the playlist is open:
| Key | Action |
|---|---|
Ctrl+Up / Ctrl+Down |
Move selected item up / down |
Ctrl+Left / Ctrl+Right |
Prev / Next album (MultiAlbum) |
Third-party notices: THIRD_PARTY_NOTICES.md
