isi-music

// Overview

About isi-music

isi-music is a terminal audio player for Spotify streaming and local file playback, built in Rust. It replaces resource-heavy desktop clients with a native TUI that runs in any terminal emulator - fast, lightweight, and keyboard-centric.

Performance Specs

Metric Value
RAM Usage 36 to 44 MB
CPU (no cover art) ~0.3%
CPU (with cover art) ~0.8%
Threads 25 to 27
Test Hardware Ryzen 4600G + WezTerm

Tested on AMD Ryzen 4600G (6C/12T) with WezTerm terminal emulator.

memory

Why RAM scales

The audio buffer runs in memory for speed, much faster than reading from the file protocol. Longer tracks mean a larger buffer, so memory usage grows with track duration.

developer_board

25+ threads? Not a lot.

Tokio runtime, audio decoding, Spotify API calls, UI rendering: everything is async. Each thread is lightweight and idle most of the time. This is normal for a Rust async app.

speed

Sub-1% CPU

Even with cover art rendering, isi-music stays under 1% CPU. Rust + ratatui + async = minimal resource footprint. Your terminal stays responsive.

// Setup

Installation

Prerequisites: Nerd Font

A Nerd Font is required for proper album art and UI rendering.

bash
$ mkdir -p ~/.local/share/fonts
$ unzip NerdFont.zip -d ~/.local/share/fonts
$ fc-cache -fv

Download

bash
$ curl -L https://github.com/glrmrissi/isi_music/releases/latest/download/isi-music-linux-x86_64 -o isi-music
$ chmod +x isi-music
$ sudo mv isi-music /usr/local/bin/
powershell
PS> Invoke-WebRequest -Uri .../isi-music-windows-x86_64.exe
PS> mkdir "$env:LOCALAPPDATA\Programs\isi-music" -Force
PS> move isi-music.exe "$env:LOCALAPPDATA\Programs\isi-music\"

Linux Audio Dependencies

Distro Command
Debian / Ubuntu sudo apt install libasound2t64 libpulse0
Arch Linux sudo pacman -S alsa-lib libpulse
Fedora sudo dnf install alsa-lib pulseaudio-libs

// Customize

Configuration

config.toml

All config lives under ~/.config/isi-music/ on Linux and %APPDATA%\isi-music\ on Windows.

toml
[spotify]
client_id = "your_client_id_here"
enabled = true # false = local-only mode

[local]
music_dir = "~/Music"

[lastfm]
session_key = "obtained_via_setup-lastfm"

[discord]
enabled = true
app_id = "optional_custom_app_id"

[musixmatch]
musixmatch_api_key = "your_musixmatch_api_key"

[ui]
show_cover_images = true
enable_lyrics = true
show_visualizer = false
default_layout = "default"
compact_mode_default = false
show_breadcrumb = true
autoplay = true

[audio]
gapless = true
bitrate = 320 # 96, 160, or 320

[options]
hot_reload = true
smtc_enabled = true # Windows
media_keys_enabled = true # Windows

[cache]
enabled = true
auto_cleanup = true
max_size_mb = 500
cleanup_interval_hours = 24
keep_days = 30

Theme

Create ~/.config/isi-music/theme.toml to customize colors and layout.

toml
border_active = "#00d4ff"
border_inactive = "#ffffff"
highlight_bg = "#004b7a"
text_primary = "#ffffff"
accent_color = "#ffeb3b"
background = "#141414"
text_secondary = "#888888"
status_bar = "#1e1e1e"
Variable Purpose
border_activeFocused panel borders
border_inactiveUnfocused borders
highlight_bgSelected list items
text_primaryTitles, primary text
accent_colorProgress bars, icons
backgroundRoot background fill
text_secondarySubtle text, timestamps
status_barBottom status bar

Run isi-music setup for 8 color presets that preserve your existing layout settings.

// Keyboard

Keybindings

Vim-inspired keybindings with customizable keybinds via keybinds.toml. Keep your hands on the keyboard - no mouse required.

Playback

Key Action
SpacePlay / Pause
n / pNext / Previous track. With shuffle on, previous goes back through actual play history.
= / -Volume up / down
← / →Seek backward / forward 5s (hold for 10s)
5Seek to middle of track
sToggle shuffle
rCycle repeat (off → queue → track)
´Toggle radio mode
Alt+RGet recommendations
lLike current track
aAdd track to queue
DeleteRemove selected item from queue
oSort tracks

Navigation

Key Action
Tab / Shift+TabNext / Previous panel
↑ / ↓ or k / jNavigate within a panel
Ctrl+↑ / Ctrl+↓First / last item
MJump to middle of list
EnterPlay selected / open album or artist
EscBack / Close search / Exit fullscreen
/Search
Ctrl+FQuick search
cJump to playing track
1 / 2 / 3 / 4Focus library / playlists / tracks / queue
PageUp / PageDownScroll up / down

Playlist & Display

Key Action
AAdd to playlist
DRemove from playlist
Alt+DDelete playlist
zToggle fullscreen player
mToggle compact mode
vToggle visualizer
yToggle lyrics
dToggle debug overlay (CPU, memory, logs)
Shift+BToggle breadcrumb
tOpen settings panel
:Command prompt
Ctrl+YCopy track link
?Open help panel
q / Ctrl+CQuit

// Library

Local Files

isi-music can play local audio files without a Spotify account. Point it at your music directory in config.toml:

toml
[local]
music_dir = "~/Music"

Supported formats: MP3, FLAC, OGG, WAV, AIFF. Navigate to Local Files in the library panel and press Enter to scan. The first scan extracts metadata and embedded cover art, cached in SQLite for instant loads. Mix local and Spotify tracks in the same queue: isi-music routes each track to the appropriate player automatically.

Local-only mode

No Spotify account at all? Set enabled = false under [spotify] to skip authentication entirely: no auth prompt, no Spotify sections, and your music_dir subfolders show up as playlists. Search still works across the local library, and Last.fm scrobbling stays available after isi-music setup-lastfm. Daemon mode requires Spotify and refuses to start in local-only mode.

// Client ID Required

Spotify Setup

The February 2026 Spotify Web API changes require a Client ID for all API requests.

  1. Go to the Spotify Developer Dashboard and click "Create app"
  2. Set the Redirect URI to http://127.0.0.1:8888/callback
  3. Copy the Client ID and run isi-music setup-spotify

The setup command performs a single unified authentication that chains the Web API OAuth (PKCE) and the streaming OAuth (librespot) in one flow. You only need to authorize once through the browser. The Web API refresh token is saved immediately after the first step, so it persists even if the streaming connection fails and you can retry the streaming part without re-authorizing the Web API.

// Linux Desktop

MPRIS2 Integration

isi-music registers on D-Bus as org.mpris.MediaPlayer2.isi_music, enabling media keys, Waybar widgets, and playerctl. MPRIS works in both TUI and daemon modes.

Waybar Config

toml
"mpris": {
  "format": "{player_icon} {title} -- {artist}",
  "player-icons": { "isi_music": "" },
  "status-icons": { "playing": ">", "paused": "||" }
}

Hyprland Media Keys

conf
bind = , XF86AudioPlay, exec, playerctl play-pause
bind = , XF86AudioNext, exec, playerctl next
bind = , XF86AudioPrev, exec, playerctl previous

// Windows Desktop

SMTC (Windows)

On Windows, isi-music registers with System Media Transport Controls: the native volume-overlay media widget shows title, artist, and cover art, and global media hotkeys work from anywhere. Toggle via [options] smtc_enabled and media_keys_enabled in config.toml. Both are enabled by default.

// Scrobble

Last.fm

Run isi-music setup-lastfm to configure. It opens your browser for authorization and saves the resulting session key; API credentials are embedded at build time, no manual key entry needed. Works for both Spotify and local tracks.

  • Track starts: track.updateNowPlaying
  • Track reaches 50% or 4 minutes: track.scrobble

// Social

Discord Rich Presence

Enable in config.toml:

toml
[discord]
enabled = true

Optional: use a custom app ID with app_id = "your_custom_app_id". Your status shows "Listening to [Track] by [Artist]".

// Headless

Daemon Mode

Keep playback running in the background, controlled from the command line.

bash
$ isi-music --daemon
$ isi-music --play spotify:playlist:37i9dQZF1DXcBWIGoYBM5M
$ isi-music --liked
$ isi-music --ls
$ isi-music --play-id 2
$ isi-music --toggle
$ isi-music --next
$ isi-music --prev
$ isi-music --vol+
$ isi-music --status
$ isi-music --quit-daemon

Logs at ~/.cache/isi-music/isi-music.log. Clear with isi-music --clear-logs. Daemon mode currently supports Spotify playback only.

// Help

Troubleshooting

Local files showing "Unknown Artist"

Delete the SQLite cache and covers, then restart:

bash
rm ~/.local/share/isi-music/library.db
rm -rf ~/.cache/isi-music/covers/

Album art not showing

  • Ensure your terminal supports true color: echo $COLORTERM
  • Verify a Nerd Font is installed and configured
  • Check that embedded artwork exists in your audio files

MPRIS not working

Ensure D-Bus is running and DBUS_SESSION_BUS_ADDRESS is set.

// Build from Source

Development

Requires Rust 1.88+ (edition 2024).

bash
$ git clone https://github.com/glrmrissi/isi_music.git
$ cd isi_music
$ sudo apt install libasound2-dev libpulse-dev libdbus-1-dev pkg-config
$ cargo build --release
$ cargo test

Run with debug logging: RUST_LOG=isi_music=debug cargo run