Sometimes I want to listen to an album, or two or three, or a genre and an album artist, or a stream and then let mpdq take over, or, or… and I just want to have one simple interface that can be as flexible as my music taste might be.
Hence, this program.

(The very pretty interface on the left is rmpc, the Rusty Music Player Client.)
mpdcontrol.sh (or mpdc) builds an fzf picker from several music and radio sources, then sends the selected result to MPD or mpdq.
It can combine:
mpdq station configs.pls radio entries from simple_listen_to_di (or any other similarly formatted)radiotray-ng bookmarksThere’s icons in the picker to indicate what sort of thing you’re selecting, and then it’ll queue up the appropriate things. Or you can have it instantly change clear whatever’s playing. Or have it change after the currently-playing track (unless that’s a stream, since streams often don’t end).
Also, if you have anything in the “Bumper” genre, like “radio changing static” sounds, it’ll play that to signify the new change. It amuses me.
The additional script, add_soundclip.sh will add a random track from the “Sound Clip” genre to the end of the queue, if there is not already a track from that genre in the queue. It uses the same config files as mpdcontrol, and can be called on demand or on a timer.
mpdq autopopulate the queue afterward.--emit option to get options to pass to a web interface, bot, or home assistantSystem packages installable with apt (I’m using Debian Trixie):
sudo apt update
sudo apt install -y bash mpd mpc fzf jq grep sed coreutils mawk
Notes:
mpd is what we’re playing music through, though if you have it installed as a server elsewhere, this is unneeded.mpc is the MPD client the script uses for querying and queue actions.fzf provides the interactive selector.jq is used for radiotray-ng (and similar) bookmark parsing.grep, sed, coreutils, and mawk cover the shell text-processing used by the script.External tools referenced by this project:
mpdq: https://github.com/uriel1998/mpdqsimple_listen_to_di: https://github.com/uriel1998/simple_listen_to_dimpdq is required for --stations.
simple_listen_to_di is optional, but has a script in it needed if you want the playlists for --listentodi.
Clone this repository and make the script executable:
chmod +x mpdcontrol.sh
If you want station support, install mpdq from: https://github.com/uriel1998/mpdq
If you want your .pls radio stations from Digitally Imported, look at: https://github.com/uriel1998/simple_listen_to_di
The script looks for configuration in this order:
./mpdc.ini$XDG_CONFIG_HOME/mpdc$HOME/.config/mpdcAn example config is provided in mpdc.ini.example.
Common keys:
musicdir=/media/_Music
mpdserver=localhost
mpdport=6600
mpdpass=secret
DI_PLS_DIR=/path/to/pls/files
ADDMODE=2
ADDMODE values:
0: add without clearing1: clear before adding2: crop before adding, with a randomly selected track from the genre “Bumper” played before the newly queued tracks.Show help:
./mpdcontrol.sh --help
Choose from everything:
./mpdcontrol.sh --all
Choose genres and albums, clearing the queue first:
./mpdcontrol.sh --genre --album --clear
Choose items and append them without clearing or cropping first:
./mpdcontrol.sh --genre --artist --append
Limit genre or album-artist additions to a fixed number of entries:
./mpdcontrol.sh --genre --limit 25
Shuffle album, genre, or album-artist tracks before adding them:
./mpdcontrol.sh --artist --shuffle
Choose from mpdq stations:
./mpdcontrol.sh --stations
--station and --stations are equivalent.
If multiple station entries are selected in the same run, the script keeps only one of them and chooses it at random.
Choose from ListenToDI .pls files in a custom directory:
./mpdcontrol.sh --listentodi --playlist-dir /path/to/pls
Emit the list of choices that would be shown in fzf, without opening fzf or changing playback:
./mpdcontrol.sh --emit --stations
Emit the raw internal records, using the unit separator character (0x1f) between fields:
./mpdcontrol.sh --emit-raw --stations
Emit JSON lines for external tooling:
./mpdcontrol.sh --emit-json --stations
Skip source collection and fzf entirely by providing one JSON input record:
./mpdcontrol.sh --input '{"source":"station","payload":"/home/steven/.config/mpdq/General_mix.cfg"}'
The script also accepts the shell-expanded unquoted form:
./mpdcontrol.sh --input {"source":"station","payload":"/home/steven/.config/mpdq/General_mix.cfg"}
For example, to directly add shuffled psytrance tracks with a limit of 10:
./mpdcontrol.sh --shuffle --limit 10 --input '{"source":"genre","payload":"psytrance"}'
--input accepts only one JSON object per run. To directly process multiple items, call mpdcontrol.sh once per item; the --input JSON is case-sensitive.
Enable verbose output:
./mpdcontrol.sh --all --loud
--playlist, --playlists
--station, --stations
--listentodi
--radiotray
--genre
--artist
--album
--all
--append
--clear
--crop
--limit NUMBER
--shuffle
--emit
--input JSON
--emit-raw
--emit-json
--playlist-dir PATH
--loud
-e, --emit
-i, --input
-h, --help
The script dispatches by source:
playlist -> mpc loadgenre -> mpc findadd genreartist -> mpc findadd albumartistalbum -> mpc findadd albumradio -> mpc add <url>station -> mpdq --config <path>Internal record format:
iconsourcetitlepayload--emit-raw returns those fields separated by the ASCII unit separator character (0x1f).
--emit-json returns one JSON object per line, for example:
{"icon":"🎛️","source":"station","title":"Pop","payload":"/home/steven/apps/mpdq/config/Pop.cfg"}
--input accepts JSON with:
sourcepayloadAccepted --input forms:
--input '{"source":"station","payload":"/path/to/file.cfg"}'--input {"source":"station","payload":"/path/to/file.cfg"}--input skips source collection and fzf, then immediately processes the provided item as if it had been selected by the user.
If you choose more than one thing, then:
clearmode runs once before selection processing startsstation selections are processed firststation selections are deferred until the endstation is selected, one station is chosen at random and passed to mpdqIcon derived from sources including Control room icons created by Freepik - Flaticon, Quaver icons created by Freepik - Flaticon, and Terminal icons created by Smashicons - Flaticon