Headless Daemon Mode
Run cliamp without a TUI. The daemon listens on the same Unix socket as the interactive player. Playback, library, and V2 remote commands work, but cliamp does not render a terminal UI. Use this mode to control playback through IPC from a status bar, script, hotkey daemon, or cron job.
cliamp --daemon # no TUI, IPC only
cliamp -d # short form
cliamp --daemon --auto-play --playlist Lofi # start playing on launch
cliamp --daemon ~/Music --auto-play # auto-play a directory
Send SIGINT or SIGTERM to stop the daemon. cliamp saves the resume position on a graceful shutdown.
What works
The daemon exposes the same runtime, library, job, and event IPC interface as the TUI. See Remote Control for the list:
- Playback:
play,pause,toggle,stop,next,prev - Position:
seek,volume,speed - Playback modes:
shuffle,repeat,mono - Library:
load "Name",queue /path/to.mp3 - Audio:
eq <preset>,eq --band N <dB>,device <name|list> - Status:
status,status --json
What doesn't
UI-only commands return an error in headless mode:
theme: no UI is available for themesvis: no visualizer is running
The daemon still enables MPRIS on Linux and NowPlaying on macOS when the platform service is available. You can also bind media keys directly to cliamp subcommands. See Hyprland.
Use cases
Background music daemon
Start cliamp once at login, for example with ~/.config/systemd/user/cliamp.service or desktop-environment autostart. Keep it running. Control it from any terminal:
cliamp toggle # play/pause from anywhere
cliamp next
cliamp volume -3
Use this minimal systemd user unit:
[Unit]
Description=cliamp headless music player
[Service]
ExecStart=%h/.local/bin/cliamp --daemon --auto-play --playlist "Lofi"
Restart=on-failure
[Install]
WantedBy=default.target
systemctl --user enable --now cliamp.service
Waybar / Polybar / i3blocks status modules
Poll cliamp status --json at an interval. Render the fields that you need.
Waybar (~/.config/waybar/config):
"custom/cliamp": {
"exec": "cliamp status --json | jq -r 'if .state == \"playing\" then \" \" + (.track.title // \"\") else \"\" end'",
"interval": 2,
"on-click": "cliamp toggle",
"on-click-right": "cliamp next",
"on-scroll-up": "cliamp volume +3",
"on-scroll-down": "cliamp volume -3"
}
Polybar:
[module/cliamp]
type = custom/script
exec = cliamp status --json | jq -r '.track.title // ""'
interval = 2
click-left = cliamp toggle
click-right = cliamp next
Radio stream metadata
A radio station playlist entry only has the station name. During playback,
.track reports the station now-playing metadata. The station sends this data
inline as SHOUTcast/Icecast ICY metadata:
| Field | Description |
|---|---|
title |
Current song from the ICY tag. Before it arrives, this is the station name. |
artist |
Current artist when the ICY tag uses "Artist - Title" |
station |
Station name. Present only after a song replaces title. |
stream_title |
Raw, unsplit ICY value |
A status bar can show the station and song together:
cliamp status --json | jq -r '(.track // {}) | if .station then (if .artist then "\(.station): \(.artist) - \(.title)" else "\(.station): \(.title)" end) else (.title // "") end'
Hotkeys (window manager / sxhkd / Hyprland)
Bind media keys directly to IPC subcommands.
Hyprland (~/.config/hypr/hyprland.conf):
bind = , XF86AudioPlay, exec, cliamp toggle
bind = , XF86AudioNext, exec, cliamp next
bind = , XF86AudioPrev, exec, cliamp prev
bind = , XF86AudioRaiseVolume, exec, cliamp volume +3
bind = , XF86AudioLowerVolume, exec, cliamp volume -3
sxhkd:
XF86AudioPlay
cliamp toggle
XF86AudioNext
cliamp next
Sleep / wake timers via cron
# Start lofi playback at 8am on weekdays
0 8 * * 1-5 /home/me/.local/bin/cliamp --daemon --auto-play --playlist Lofi >/dev/null 2>&1 &
# Stop at 6pm
0 18 * * * pkill -TERM -f 'cliamp --daemon'
Scripted playlists
Build a queue from a script:
cliamp --daemon --auto-play &
sleep 1 # let the socket bind
for f in $(find ~/Music/Albums/Daft\ Punk -name '*.flac' | sort); do
cliamp queue "$f"
done
Remote control over SSH
The socket is at ~/.config/cliamp/cliamp.sock, and the CLI accesses it locally. Get a shell on the host with SSH or tmux session attach to control playback:
ssh kitchen-pi cliamp toggle
ssh kitchen-pi cliamp status --json
Embedded / kiosk audio
Run this mode on a Pi or small Linux computer without a display. The daemon needs no terminal allocation. It needs working ALSA, PipeWire, or PulseAudio output.
cliamp --daemon --auto-play http://radio.cliamp.stream/lofi/stream
Notes
- The daemon and TUI share one Unix socket. Only one cliamp instance can run for a user. A second instance cannot bind to the socket.
- This version of headless mode does not load Lua plugins. They need UI hooks that this mode does not enable.
- Headless mode does not preload the next track for gapless playback. Small gaps between tracks are expected.