tmux-player-ctl

April 6, 2026 · View on GitHub

A minimal tmux popup controller for MPRIS media players via playerctl.

screenshot

Features

  • Real-time metadata - background follower process watches for player changes instantly
  • Full playback controls - play/pause, previous, next, seek ±10s, volume ±5%, mute
  • Loop & shuffle - cycle loop mode (none → track → playlist), toggle shuffle
  • Progress bar - live position indicator with elapsed/total time
  • Volume bar - color-coded volume level (muted/low/med/high)
  • Multi-player - switch between MPRIS players with Tab
  • Optimistic UI - instant feedback on keypresses, rolls back if player rejects
  • 24-bit ANSI colors - theming via environment variables
  • Signal-safe - clean exit on SIGINT/SIGTERM

Requirements

  • tmux 3.2+
  • playerctl
  • python 3.0+

Quick Start

# Ensure playerctl works
playerctl status

# Run in a tmux popup
tmux display-popup -B -w72 -h12 -E "tmux-player-ctl.py"

Keybindings

KeyAction
SpaceToggle play/pause
pPrevious track
nNext track
/ Seek back/forward 10s
/ Volume up/down 5%
sToggle shuffle
lCycle loop (none → track → playlist)
mMute/unmute (remembers previous volume)
TabSwitch between players
q / EscExit

Configure tmux

``$\text{bash}

\text{Compact} \text{popup} (72 \times 12, \text{centered})

\text{bind}-\text{key} -\text{n} \text{M}-\text{p} \text{display}-\text{popup} -\text{B} -\text{w72} -\text{h12} -\text{E} "\text{tmux}-\text{player}-\text{ctl}" $``

Theming

Colors are specified as RGB triplets (r;g;b format). Override via environment variables:

# Example: Override playing color and background
TPCTL_PLAYING="255;100;100" TPCTL_BG="20;20;30" tmux-player-ctl.py
VariableDefaultDescription
TPCTL_PLAYING166;227;161 (green)Playing status
TPCTL_PAUSED249;226;175 (yellow)Paused status
TPCTL_STOPPED108;112;134 (gray)Stopped / no player
TPCTL_RECORDING243;139;168 (red)Recording status
TPCTL_KEY_HINT137;180;250 (blue)Key hints in toolbar
TPCTL_BORDER108;112;134 (gray)Box borders
TPCTL_DIM108;112;134 (gray)Label text
TPCTL_PROGRESS_FILL137;180;250 (blue)Progress bar filled
TPCTL_PROGRESS_EMPTY108;112;134 (gray)Progress bar empty
TPCTL_VOL_MUTED243;139;168 (red)Volume muted
TPCTL_VOL_LOW166;227;161 (green)Volume low (0-50%)
TPCTL_VOL_MED249;226;175 (yellow)Volume medium (50-80%)
TPCTL_VOL_HIGH243;139;168 (red)Volume high (80-100%)
TPCTL_VOL_EMPTY17;17;27 (dark)Volume bar empty
TPCTL_BG(none)Background RGB (e.g., "0;0;0")

Architecture

  • Config - UI constants (width, seek seconds, volume step, ANSI colors)
  • PlayerState - single track's metadata (status, title, artist, album, position, length, volume, loop, shuffle)
  • PlayerTracker - all live state: current player, player list, index, state, last command time
  • metadata.follower - background playerctl metadata subprocess
  • run_playerctl - synchronous playerctl calls
  • run_playerctl_async - fire-and-forget playerctl calls (no blocking)
  • handle_key - maps keypresses to playerctl commands with optimistic UI updates