pmusic

command module
v0.0.0-...-54a41fa Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: GPL-3.0 Imports: 8 Imported by: 0

README

pmusic

A terminal-based (TUI) local music player written in Go.

 ♪ PMUSIC   LIBRARY  4 folders · 38 tracks                 ▂▅█▃ LIVE
┏━━━━━━━━━━━━━━━━━━━━━━━━┓┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃  COLLECTIONS  04      ┃┃  TRACKS  Jazz                /\_/\  ┃
┃  Classic Rock         ┃┃   1. ▶ Kind of Blue          (^.^)  ┃
┃  Electronic           ┃┃   2.   So What                >♪ <  ┃
┃› Jazz                 ┃┃   3.   Freddie Freeloader           ┃
┃  Lo-fi                ┃┃   4.   Blue in Green                ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━┛┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
  ▂▆█▃▇▅▁  ▶ Miles Davis — Kind of Blue ↺              2:14 / 9:22
  Kind of Blue
  ━━━━━━━━━━━━━━━━━━━━━●──────────────────────────────────────────
  j/k:move  h/l:panel  enter:play  spc:pause  n/p:skip  ?:help  q:quit

Features

  • Two-panel interface — folders on the left, tracks on the right
  • Supports MP3, FLAC, and WAV formats
  • ID3 / Vorbis metadata — artist, album, and title read from file tags; falls back to filename
  • Volume control+ / - keys in 10% steps, persists across tracks
  • Song seeking[ / ] for ±5 seconds, { / } for ±30 seconds
  • Mouse support — click to select and play, scroll wheel to navigate
  • Animated ASCII mascot — a cat in the corner of the tracks panel that reacts to play / pause / stop state
  • Help overlay — press ? to show all shortcuts in a centered popup
  • Progress bar with elapsed time / total duration display
  • Loop mode — repeat the current track (r)
  • Automatic track switching — plays the next track when the current one ends
  • Adaptive refresh rate — smooth 4 Hz playback animation with a lower-power 1 Hz idle loop
  • Live directory watching — automatically refreshes when files are added or removed
  • Persistent configuration — music directory is saved to ~/.config/pmusic/config.json
  • Persistent play queue — queue tracks or whole folders, reorder them, and continue across restarts
  • Local library search — find tracks without leaving the player
  • Listening statistics — inspect listening time, starts, completions, skips, artists, and top tracks
  • Vim-style command mode — searchable help, completion, aliases, suggestions, and persistent history
  • Lua scripting — theme, keybindings, and event hooks configurable without recompiling
  • Blackjack mini-game — play from inside the TUI while your music continues

Installation

Quick install (Linux x86-64)

The currently published binary is the automatically updated edge build for 64-bit x86 Linux. Check that uname -m prints x86_64, then run:

curl -fL https://github.com/Padrosum/pmusic/releases/download/edge/pmusic-linux-amd64 \
  -o pmusic-linux-amd64
sudo install -m 0755 pmusic-linux-amd64 /usr/local/bin/pmusic
pmusic --version

edge is rebuilt after every successful commit to main, so it may contain new or unfinished changes. The -f flag makes curl fail instead of saving a GitHub error page as an executable.

To update later, run the same three commands again.

With ppd

If ppd is already installed:

ppd install pmusic

ppd installs the repository-root binary into /usr/local/bin. Use ppd update to update packages managed by ppd.

With Go

This method works on other operating systems and architectures supported by pmusic. It requires the Go version declared in go.mod; Linux source builds also require ALSA development headers. On Debian/Ubuntu:

sudo apt-get update
sudo apt-get install -y libasound2-dev pkg-config
go install github.com/Padrosum/pmusic@latest

Make sure $(go env GOPATH)/bin is in your PATH, then verify the installation with pmusic --version.

Build from source

On Debian/Ubuntu, install the build requirements first:

sudo apt-get update
sudo apt-get install -y git libasound2-dev pkg-config

Install the Go version declared in go.mod or newer, then clone, build, and install pmusic:

git clone https://github.com/Padrosum/pmusic.git
cd pmusic
make release
sudo install -m 0755 dist/pmusic /usr/local/bin/pmusic
pmusic --version

make release creates a stripped binary at dist/pmusic and a ppd-compatible copy at the repository root.

Optional download support

Local playback has no external command dependency. Online search and downloads additionally require yt-dlp and FFmpeg to be available in PATH:

yt-dlp --version
ffmpeg -version

Usage

# On first launch, pmusic asks for your music directory and saves it
pmusic

# Specify a directory directly
pmusic ~/Music

# Download all bundled plugins and themes to ~/.config/pmusic/lua/
pmusic -s

# Print build version and commit information
pmusic --version

On first startup a setup screen appears asking for your music folder path. This is saved to ~/.config/pmusic/config.json and won't be asked again.

Keyboard Shortcuts

Key Action
j / Move down
k / Move up
h / Switch to folders panel
l / Switch to tracks panel
Enter Play selected track
Space Pause / Resume
n Next track
p Previous track
r Toggle loop mode
[ / ] Seek ±5 seconds
{ / } Seek ±30 seconds
+ / = Volume up (+10%)
- Volume down (−10%)
: Open Vim-style command mode
? Show / hide help overlay
Y Open music search and download screen
/ Search the local music library
a Add the selected track or folder to the queue
u Open or close the play queue
g Open plugin / theme store
b Open or close the Blackjack mini-game
Ctrl+R Reload Lua config (hot-reload)
q / Ctrl+C Quit

Command Mode

Press : to open the Vim-style command line. Command execution, completion, aliases, suggestions, and help all use the same central command registry.

Examples:

  • :play
  • :pause
  • :volume 60
  • :seek +30
  • :loop toggle
  • :queue clear
  • :search Metallica
  • :online Metallica
  • :download Duman Seni Kendime Sakladım
  • :reload lua
  • :help seek
  • :stats week
  • :stats artist Metallica
  • :quit

Use Tab and Shift+Tab for completion, / for suggestions or command history, and :help for the complete searchable command reference. Ctrl+U clears the line, Ctrl+W deletes the previous word, and Esc or Ctrl+C returns to normal mode. Command history is kept in $XDG_STATE_HOME/pmusic/command-history (or ~/.local/state/pmusic/command-history).

Listening activity is stored locally in $XDG_STATE_HOME/pmusic/listening-stats.json. Use :stats, :stats week, :stats all, or :stats artist <name> to inspect listening time, started tracks, completions, skips, and top tracks. Statistics are written atomically with user-only file permissions.

Mouse

Input Action
Left click on track Select and play immediately
Left click on folder Select folder
Scroll wheel Navigate up / down

Music Search and Download

Press Y to open the music search screen. Enter a song or artist name to search YouTube and inspect up to 10 results before downloading anything.

╭── ♫ Music Search ─────────────────────────────────────╮
│                                                       │
│  Search: metallica fade to black                      │
│  Source: YouTube (text search)                        │
│                                                       │
│  › Metallica - Fade to Black                          │
│      Metallica · 6:57 · YouTube                       │
│                                                       │
│  j/k:select  Enter:download  /:new search  Esc/q:close│
╰───────────────────────────────────────────────────────╯
  • Search text — lists YouTube results; use j / k or the arrow keys to select one, then press Enter to download it
  • URL (starts with http:// or https://) — previews and downloads that URL directly through yt-dlp
  • New search — press / from the result screen to edit the query again
  • Close — press Esc or q; an active download continues safely in the background

Text search is YouTube-only in this version. Direct URLs may point to YouTube, SoundCloud, or any other source supported by yt-dlp; pMusic does not claim that those sites support text search.

Requires yt-dlp in $PATH (and its normal audio conversion dependencies). Downloads run in the background and are written to the configured local music folder. The filesystem watcher adds the resulting MP3 to the library, and pMusic plays it as a local file—it never streams the remote result.

Plugin Store

pmusic has a built-in plugin manager. Run pmusic -s once to download all bundled plugins and themes, then press g inside pmusic to enable or disable them without editing any files.

Sync downloads are pinned to an immutable repository commit, size-limited, and SHA-256 verified before atomically replacing an installed file. Lua extensions are trusted code rather than a sandbox; review the security model before enabling third-party code.

pmusic -s        # download plugins + themes to ~/.config/pmusic/lua/

Inside pmusic press g to open the store overlay:

╭── Plugin Store ──────────────────────────────────╮
│                                                  │
│  [Plugins]  Themes   pmusic -s ile indir         │
│                                                  │
│  ✓  logger               Log played tracks...    │
│  ✓  listen-time          Session listening...    │
│  ○  stats                Session play-count...   │
│  ✗  notify-send          [kurulu değil]          │
│  ...                                             │
│                                                  │
│  Space:toggle  h/l:sekme  g/q:kapat              │
╰──────────────────────────────────────────────────╯
Icon Meaning
Installed and enabled
Installed but disabled
Not installed — run pmusic -s first

Enable state is saved to ~/.config/pmusic/enabled.json. Enabled plugins and themes are loaded automatically on startup and after every Ctrl+R hot-reload.

Lua Scripting

pmusic is extensible via Lua scripts placed in ~/.config/pmusic/lua/.

For the full API reference, theme color map, plugin authoring guide, and execution model — see lua/info.md (available in English and Turkish).

Quick start
mkdir -p ~/.config/pmusic/lua/themes ~/.config/pmusic/lua/plugins

# copy the example config
cp lua/init.lua ~/.config/pmusic/lua/init.lua

# optionally copy a theme
cp lua/themes/gruvbox.lua ~/.config/pmusic/lua/themes/

Edit ~/.config/pmusic/lua/init.lua, then press Ctrl+R inside pmusic to apply changes without restarting.

Directory layout
~/.config/pmusic/lua/
├── init.lua        ← entry point (loaded on startup and on Ctrl+R)
├── themes/
│   ├── gruvbox.lua
│   ├── catppuccin.lua
│   └── tokyo-night.lua
└── plugins/
    ├── logger.lua
    ├── stats.lua
    ├── keymaps.lua
    ├── listen-time.lua
    ├── notify-send.lua
    ├── statusline.lua
    └── theme-scheduler.lua
API reference
Function Description
pmusic.set_theme(t) Override UI colors — any subset of keys is accepted
pmusic.get_theme() Return the current theme as a Lua table
pmusic.register_keymap(key, action_or_fn) Bind a key to a built-in action string or a Lua function — pmusic.register_keymap("Y", function() … end)
pmusic.on_song_change(fn) Hook called with {name, path, folder} when a track starts
pmusic.on_state_change(fn) Hook called with "playing", "paused", or "stopped"
pmusic.notify(msg) Show a 5-second message in the status bar
pmusic.config_dir() Returns the path to ~/.config/pmusic/lua/
pmusic.music_dir() Returns the configured music directory
pmusic.current_track() Returns {name, path, folder} of the playing (or last-played) track
pmusic.version Current API version string ("0.2.0")

Actions for register_keymap (string form): toggle_pause · next · prev · loop · focus_folders · focus_tracks · reload_lua · quit · vol_up · vol_down · seek_back5 · seek_fwd5 · seek_back30 · seek_fwd30

Function form — bind any Lua logic to a key:

pmusic.register_keymap("Y", function()
    pmusic.notify("custom action!")
    os.execute("some-command &")
end)
Themes

Three themes are included in lua/themes/. Activate one by adding a single line to init.lua:

require("themes/gruvbox")     -- Gruvbox Dark
require("themes/catppuccin")  -- Catppuccin Mocha
require("themes/tokyo-night") -- Tokyo Night Storm

Or define colors inline — any subset of the keys below can be overridden:

pmusic.set_theme({
    accent        = "#89b4fa",  -- active border, progress bar, title
    dim           = "#45475a",  -- inactive text, empty progress track
    selected_bg   = "#313244",  -- cursor row background
    now_playing   = "#a6e3a1",  -- currently playing track name
    border        = "#45475a",  -- inactive panel border
    border_active = "#89b4fa",  -- active panel border
    title         = "#cba6f7",  -- panel title text
    status_bg     = "#181825",  -- status bar background
    panel_bg      = "#1e1e2e",  -- canvas / panel background
    key           = "#fab387",  -- key-hint label color
})
Plugins

logger (lua/plugins/logger.lua) — appends every played track with a timestamp to ~/.local/share/pmusic/plays.log:

require("plugins/logger")

stats (lua/plugins/stats.lua) — tracks how many times each song was played in the current session and notifies on repeat plays:

require("plugins/stats")

keymaps (lua/plugins/keymaps.lua) — a commented preset of extra bindings (MPD-style, media keys, etc.):

require("plugins/keymaps")

listen-time (lua/plugins/listen-time.lua) — tracks total listening time for the session (pause-aware) and notifies on each track change:

require("plugins/listen-time")

notify-send (lua/plugins/notify-send.lua) — sends a desktop notification on every track change (auto-detects dunstify / notify-send / osascript):

require("plugins/notify-send")

statusline (lua/plugins/statusline.lua) — writes current playback state to /tmp/pmusic-status.json for waybar, polybar, eww, or tmux integration:

require("plugins/statusline")

theme-scheduler (lua/plugins/theme-scheduler.lua) — automatically switches theme based on the time of day (light in morning, dark at night):

require("plugins/theme-scheduler")
Example: notify on every song change
pmusic.on_song_change(function(track)
    pmusic.notify("▶  " .. track.folder .. " / " .. track.name)
end)
Example: custom key binding
pmusic.register_keymap("f", "next")      -- f → next track
pmusic.register_keymap("b", "prev")      -- b → previous track
pmusic.register_keymap("u", "vol_up")    -- u → volume up
pmusic.register_keymap("d", "vol_down")  -- d → volume down

Requirements

  • Go 1.26.3+ (for building from source; the minimum follows go.mod)
  • System audio driver (ALSA on Linux, CoreAudio on macOS, DirectSound on Windows)
  • ALSA development headers and pkg-config for Linux source builds
  • yt-dlp and FFmpeg only for online search/download support

Why pmusic?

pmusic is designed for people who want to listen to music without leaving the terminal. It's lightweight, requires no graphical interface, and uses Vim-like keyboard shortcuts for fast navigation. No metadata database or external services required — just a music directory.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
fs
lua
ui

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL