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 directorySend SIGINT or SIGTERM to stop the daemon. cliamp saves the resume position on a graceful shutdown.
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
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.
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 -3Use 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.targetsystemctl --user enable --now cliamp.servicePoll cliamp status --json at an interval. Render the fields that you need.
Waybar (~/.config/waybar/config):
Polybar:
[module/cliamp]
type = custom/script
exec = cliamp status --json | jq -r '.track.title // ""'
interval = 2
click-left = cliamp toggle
click-right = cliamp nextA 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'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 -3sxhkd:
XF86AudioPlay
cliamp toggle
XF86AudioNext
cliamp next
# 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'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"
doneThe 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 --jsonRun 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- 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.