A terminal-based music player with Spotify-inspired UI, audio visualization, and multi-platform support. Built with Go and Bubble Tea.
English · Türkçe
- 🎨 Spotify-Inspired UI — Clean, modern terminal interface with album art, song list, and player bar
- 📊 Audio Visualization — Real-time volume bars using CP437 characters (░▒▓█) — works in every terminal
- 📋 Playlist Management — Create, edit, delete playlists; reorder songs
- 🎵 Multiple Sources — Add music from Spotify, YouTube Music, or local files
- 🖼️ Album Art — ANSI half-block rendering of cover images
- 🌐 Bilingual — Full English and Turkish interface support
- 🎨 Themes — Light, Dark, and custom color themes
- ⚡ Blazing Fast — Written in Go, launches in milliseconds
- 🔊 Audio Engine — Embedded yt-dlp + FFmpeg downloads MP3 320k with album art, auto-advances on completion
- 🔄 Auto-Advance — Automatic next track with configurable delay
- 🔍 Search — Quick filtering across your library
- 🎛️ Equalizer-like Bars — Real-time audio spectrum visualization in the player bar
| Archive (zip) | Install Steps | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
No dependencies required. |
| Archive (tar.gz) | Install Steps | ||||||
|---|---|---|---|---|---|---|---|
|
No dependencies required. |
| Format | Install Steps |
|---|---|
|
tar.gz deb (Debian/Ubuntu) rpm (Fedora/RHEL) |
tar.gz: tar xzf muscle-cli_Linux_x86_64.tar.gz
cd muscle-cli_Linux_x86_64
./musicle-clideb: sudo dpkg -i muscle-cli_Linux_x86_64.deb
musicle-clirpm: sudo rpm -ivh muscle-cli_Linux_x86_64.rpm
musicle-cliNo dependencies required. |
The download engine (standalone yt-dlp + a static FFmpeg) is embedded
into the binary via go:embed (-tags engine_assets), so the released binary
is fully self-contained — end users never download anything extra and no
Python is required. The engine assets themselves are not committed to the
repo; they are fetched at build time by scripts/prepare-engine.sh.
git clone https://github.com/alperencolgecen/musicle-cli.git
cd musicle-cli
# Recommended: downloads the embedded engine, then bakes it into the binary
make build
# …or manually:
make engine # downloads yt-dlp + ffmpeg into internal/engine/engine_bin
CGO_ENABLED=1 go build -tags engine_assets -o musicle-cli .Note: the audio player backend (oto) needs CGO + ALSA dev headers, so the build is
CGO_ENABLED=1by default. On Fedora:sudo dnf install gcc alsa-lib-devel. A plaingo build(without-tags engine_assets) still compiles, but the embedded engine is omitted and the downloader falls back to the legacy method at runtime.scripts/prepare-engine.shcompresses FFmpeg with UPX when available (77 MB → ~25 MB) to keep the final binary small. To re-fetch the engine (e.g. after bumping versions inassets/engine/manifest.yaml), runmake engineagain before building.
- Launch:
./musicle-cli(or double-click the binary) - First Run Wizard: Choose music directory, language, create a profile and playlist
- Add Music:
- Paste a Spotify or YouTube Music URL in the sidebar
- Or use
+ Add Local Musicto browse local files
- Play: Select a song and press
Spaceor click▶ Play
| Key | Action | Description |
|---|---|---|
Space |
⏯ Play/Pause | Toggle playback |
→ / ← |
⏩⏪ Seek | 5 seconds forward/back |
↑ / ↓ |
🔊🔉 Volume | Increase/decrease volume |
Tab |
🔄 Cycle Focus | Switch between sidebar, songs, editor, console |
F1 |
🔁 Cycle Sections | Cycle focus through all sections including console |
F3 |
⚙️ Switch Settings Tab | Cycle through the General page tabs (Theme, Language, …) |
Ctrl+U |
📋 Update Playlist | Save the current playlist |
n |
⏭ Next Song | Skip to next track |
Ctrl+C / Esc |
❌ Quit | Exit the application |
Enter |
✏️ Edit Song | Open edit modal for selected song |
┌─────────────────────────────────────────────────────────────────┐
│ MusicLe [Home] [Settings] │ ← Header
├──────────────┬──────────────────────────────────────────────────┤
│ │ [Playlist ▼] │
│ MUSIC │ ┌──────┐ Playlist Name │
│ DOWNLOAD │ │ Art │ Description / Bio │
│ │ └──────┘ │
│ [Spotify…] │ [🔒 Lock] [🔀 Shuffle] [▶ Play] [⬇ Download] │
│ [YouTube…] │ ──────────────────────────────────────────── │
│ [+Local] │ # Title Artist Album Dur │
│ [Playlist▼] │ ──────────────────────────────────────────── │
│ │ 1 Bohemian Rhapsody Queen A Night 05:55 │
│ (~25%) │ 2 Stairway to Heaven Led Zepp IV 08:02 │
│ │ 3 … │
├──────────────┴──────────────────────────────────────────────────┤
│ ░▒▓███████ Bohemian Rhapsody — Queen ░▒▓███░ 01:23/05:55 │ ← Player Bar
└─────────────────────────────────────────────────────────────────┘
| Section | Description |
|---|---|
| Sidebar | Music download (Spotify/YouTube/local) + playlist selector |
| Playlist Info | Album art, name, description, action buttons |
| Songs Table | Song list with title, artist, album, duration columns |
| Player Bar | Volume visualization, now-playing info, progress, metadata |
| Console | Log output and debug information |
| Edit Modal | Inline editing of song title, artist, album, and date |
Config file: %APPDATA%/musicle/config.json (Windows) or ~/.config/musicle/config.json (Linux/macOS)
{
"language": "en",
"theme": "dark",
"musicDir": "~/Music",
"player": {
"volume": 80,
"autoAdvance": true,
"autoAdvanceDelay": 2
}
}- dark — Dark background with vibrant accents (default)
- light — Light background
- custom — User-defined color scheme
musicle-cli/
├── main.go # Application entry point
├── model.go # Main TUI model
├── home.go # Home screen logic (player, songs, sidebar)
├── settings.go # Settings screen
├── state/
│ ├── state.go # Global application state
│ ├── config.go # Configuration management
│ └── profile.go # Profile data structures
├── ui/
│ ├── styles.go # Lipgloss styles, theme system
│ ├── keys.go # Keybinding definitions
│ └── help.go # Help view
├── bridge/
│ ├── bridge.go # Main dispatcher (player, playlist, metadata, download)
│ ├── player.go # Audio playback engine (oto + beep + gonum FFT)
│ ├── metadata.go # Metadata extraction (dhowden/tag)
│ ├── playlist.go # Playlist CRUD + local file import
│ ├── download.go # YouTube/Spotify download via embedded engine dispatcher
├── internal/engine/ # Embedded download engine (go:embed yt-dlp + ffmpeg)
│ ├── ytwrap.go # yt-dlp/ffmpeg orchestration -> MP3 320k + APIC cover
│ ├── spotify.go # API-free Spotify resolution (embed scrape -> ytsearch1)
│ ├── extract.go # Extract embedded tools to the user cache
│ └── engine_bin/ # (not committed) prepared by scripts/prepare-engine.sh
├── maximize_windows.go # Terminal maximize (Windows)
├── maximize_unix.go # Terminal maximize (Linux/macOS)
├── .goreleaser.yaml # Release build config
- Go powers everything: TUI (Bubble Tea + Lipgloss), audio playback (oto + beep), metadata (dhowden/tag), and FFT spectrum (gonum)
- No Python required — single binary, zero runtime dependencies
- Audio decoding supports MP3, FLAC, and WAV
- Real-time 16-band FFT spectrum computed with gonum/dsp/fourier
- Rendered as CP437 block characters (
░▒▓█) — guaranteed in every terminal - 40-character bar width for consistent rendering in the player bar
| Platform | Arch | Format |
|---|---|---|
| Windows | x86_64 | zip |
| Windows | x86 | zip |
| Windows | arm64 | zip |
| Linux | x86_64 | tar.gz, deb, rpm |
| Linux | arm64 | tar.gz, deb, rpm |
| Linux | x86 | tar.gz, deb, rpm |
| macOS | x86_64 | tar.gz |
| macOS | arm64 | tar.gz |
- ✨ Pure Go rewrite — no Python, no venv, single self-contained binary
- 🔽 Embedded download engine — standalone yt-dlp + static FFmpeg baked in
via
go:embed; YouTube & Spotify (API-free) → MP3 320k with embedded cover - 📦 Self-contained — download, extract, run. Zero runtime dependencies
- 🔊 Audio engine — oto + beep for playback, gonum FFT for spectrum
- 🏷️ Native metadata — dhowden/tag for ID3/FLAC/MP4/AAC
- 🐧 Linux arm64 + 386 — added alongside x86_64
- 📊 16-band real-time FFT spectrum visualization
- 🎨 Album art ANSI rendering
- 🎵 Initial release (Python engine)
- Spotify and YouTube Music integration
- Playlist management
- Modern terminal UI
- Windows, macOS, Linux support
Contributions are welcome! Please see our contributing guidelines.
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes
- Push and open a Pull Request
- Developer: Alperen Çölgeçen — alperencolgecen@gmail.com
- GitHub: @alperencolgecen
- Issues: github.com/alperencolgecen/musicle-cli/issues
This project is licensed under the Apache License 2.0. See LICENSE for details.
The binary also bundles third-party components that are extracted at runtime into the user cache directory and invoked directly (no Python):
It additionally depends on the Go libraries listed in go.mod
(bubbletea, lipgloss, oto, gopxl/beep, ncruces/zenity, and their
transitive dependencies).
Full license texts and disclaimers are in THIRD_PARTY_NOTICES.md.
🎵 The most elegant way to enjoy music from your terminal.