GitHub - betacar/claude-player: Elevator music for Claude Code · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
betacar
claude-player
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>2 Commits<br>2 Commits
.claude-plugin
.claude-plugin
bin
bin
commands
commands
hooks
hooks
tracks
tracks
.gitignore
.gitignore
LICENSE
LICENSE
README.md
README.md
View all files
Repository files navigation
claude-player
Elevator music for Claude Code. Plays a random lounge-jazz track in the background while Claude is thinking, rotates tracks if work runs long, stops the moment Claude finishes, and never repeats the same track back-to-back.
[Opus 4.7] 📁 claude-player │ ♪ Bossa Nova Background Music Version 60s
Install
As a Claude Code plugin (recommended)
In Claude Code:
/plugin install claude-player@claude-player">/plugin marketplace add<br>/plugin install claude-player@claude-player
Restart Claude Code. From your next prompt, music starts one second after you hit enter and stops when Claude finishes responding.
As a local plugin (for development or one-machine use)
claude --plugin-dir ./claude-player">git clone<br>claude --plugin-dir ./claude-player
Usage
Music plays automatically while Claude is working. Control it with the bundled slash command:
/claude-player:music start # enable the hook<br>/claude-player:music stop # disable the hook (and silence)<br>/claude-player:music skip # jump to the next random track<br>/claude-player:music now # what's playing right now<br>/claude-player:music history # last 10 tracks played<br>/claude-player:music status # full state dump<br>/claude-player:music toggle # flip enabled ↔ disabled
The disabled state persists across sessions until you start again.
Optional: now-playing in the status line
Plugin settings.json can't configure Claude Code's main status line (the format only supports agent and subagentStatusLine), so this is a one-time manual step. Add the following block to your ~/.claude/settings.json:
"statusLine": {<br>"type": "command",<br>"command": "bash \"$HOME/.claude/plugins/cache/claude-player/claude-player/bin/elevator-music-statusline\"",<br>"refreshInterval": 1
After restarting Claude Code, the status bar will show the prettified current track with a rotating music glyph (🎵 ♫ ♬ ♪), 🎼 cueing up… during the 1-second pre-roll, or 🔇 elevator-music off while disabled (toggle via /claude-player:music stop).
Configuration
Env var<br>Default<br>Effect
ELEVATOR_MUSIC_TRACKS_DIR<br>/tracks<br>Directory scanned for audio files
ELEVATOR_MUSIC_STATE_DIR<br>~/.claude/elevator-music<br>Where PID files, history, and the disabled flag live
ELEVATOR_MUSIC_START_DELAY<br>1.0<br>Seconds to wait before starting the first track
To swap in your own music, drop .mp3/.wav/.m4a/.flac/.ogg files into any directory and point ELEVATOR_MUSIC_TRACKS_DIR at it.
Requirements
macOS — uses the built-in afplay. No setup needed.
Linux — needs one of mpg123, ffplay, mpv, or paplay on PATH.
Windows — needs ffplay, mpg123, or mpv on PATH (a PowerShell + MediaPlayer fallback exists but is single-shot, not looped).
python3 (or jq) is recommended for the hook to parse Claude Code's JSON payloads; both are present by default on macOS.
How it works
Three Claude Code hooks drive the behavior:
UserPromptSubmit spawns a detached background bash loop. It sleeps a cancellable second, then picks a random track that isn't the last one played and launches the OS-native audio player. When the player exits (track ends), the loop picks another one.
Stop and SubagentStop send SIGTERM to the loop. A trap inside the loop kills the active player child instantly. If Stop fires inside the 1-second pre-roll, no audio is ever produced — fast Claude responses stay silent.
State lives in ~/.claude/elevator-music/: a PID file for the loop, a separate child-PID file for the active player (this is what the statusline checks), the last-played track filename, a timestamped history.log, and a disabled flag.
Track credits
The bundled tracks...