Automatic MPD "smart playlist" creator with minimal but hackable setup.
Automatic MPD playlist or party mode creator to provide weighted randomness while autoqueuing MPD without relying on external services.


mpdq is a auto-queing system for MPD to create a flexible and configurable
“party mode” effect with randomization and (re)discovery of your own music.
Inspired by the eclectic soundtracks of Letterkenny, High Fidelity,
Doom Patrol, and many more.
(In-depth explanation at my blog).
mpdq will autoqueue random tracks from your existing music library,
with per-genre weighting and simple defaults.
Because it uses mpd’s own data, new tracks and changes to your music library
will be incorporated when mpd is updated.
The program has been rewritten for simplicity and to avoid subprocesses; each run
will fill the queue up to the configured queuesize. Adding a self-contained idle
loop is still in the roadmap.
Station switching is also supported, including an interactive chooser when fzf
is available.
This project is licensed under the MIT License. For the full license, see LICENSE.
These are probably already installed or are easily available from your distro on linux-like distros:
Optional:
mpdq now gets song length, album, and artist information directly from mpd
through mpc, so ffmpeg, exiftool, and mp3info are no longer required.
mpdq looks for its configuration in this order:
./mpdq.ini in the script directory./config/mpdq.ini if ./config exists and is writable$XDG_CONFIG_HOME/mpdq/mpdq.ini~/.config/mpdq/mpdq.iniAn example config:
musicdir=/directory/to/music
mpdserver=localhost
mpdport=6600
mpdpass=
songlength=900
queuesize=10
# in hours
rotate_time=8
no_replay_rotate=8
# in minutes
album_mins=15
artist_mins=15
# Genres to exclude from the below two checks
genres_exclude_album_check=Sound Clip,Classical
# set to 1 if mpdq cannot stat the same files MPD sees
remote=0
If ./local/state or ./cache exist and are writable in the script directory,
mpdq will prefer those for runtime files; otherwise it falls back to the XDG
state/cache locations.
rotate_time in the config file defines how long mpdq keeps the per-genre log
in hours – and helps define how often each genre will be played.
no_replay_rotate defines how long you will not hear a particular track again
in hours, like how radio stations used to promise you would not hear the same
song twice in a workday. This checks the track filename not the title.
album_mins and artist_mins will separately define the minimum interval
in minutes before a specific album or artist will be played again. These should
be shorter than no_replay_rotate.
genres_exclude_album_check is a list of genres where the album_mins and
artist_mins checks will be disabled, for example, if you have a genre with
only one or two artists or albums in it.
If remote=1, mpdq will skip checking the local filesystem for the candidate
track. This is useful when mpd is remote or sees the library through a
different path than the machine running mpdq.
The behavior of mpdq is governed by simple instruction files, as many (or
few) as you desire. The location of the instruction file does not matter, and
may be specified on the command line with -c or --config. When used that
way with an explicit file path, mpdq copies it to default.cfg. Without an
instruction file, mpdq will just shuffle through your entire library with an
equal weight to each genre.
Each instruction file is a series of lines in the format selector=weight like so:
Default=1
Genre:Default=1
Album:Default=0
AlbumArtist:Default=0
Rock=3
Genre:Alternative=3
Album:1984=1
AlbumArtist:Van Halen=2
Classical=0
Bare entries like Rock=3 are shorthand for Genre:Rock=3.
That “weight” is the maximum number of times that selector will be played in
the interval you put for rotate_time in the config file. Default is the
fallback weight for all selector types unless a type-specific default is
provided. Genre:Default overrides that fallback for genres, Album:Default
overrides it for albums, and AlbumArtist:Default overrides it for album
artists.
In the example above, all genres will be played a maximum of 1 time per rotate_time,
except Rock, which may be played up to three times per rotate_time,
Genre:Alternative, which may be played up to three times per rotate_time,
Album:1984, which may be played up to one time per rotate_time,
AlbumArtist:Van Halen, which may be played up to two times per rotate_time,
and Classical, which will never be played per rotate_time.
Additionally, the weight also increases the chance of that selector being selected at all, so the configured “station” character is felt sooner instead of only after the log has built up.
Instruction files may also optionally include setting overrides in the form:
Setting:ROTATE_TIME=60
Setting:NOREPLAY_ROTATE_TIME=90
Setting:ALBUM_MINS=20
Setting:ARTIST_MINS=10
If present, those values override the corresponding base config values for that
instruction file. example_configs/example_mixed.cfg shows a mixed instruction
file using selector entries together with Setting: overrides.
If an explicit non-default selector is given a weight of 0, it acts as an
exclusion even when a track is found through another selector type. Default
weights of 0 only suppress selection for selectors that are not explicitly
included later.
This allows for both very eclectic selections (as with the example above) or very focused selections, such as with the example below:
Default=0
Industrial=1
Gothic=1
Capitalization Does Not Matter
mpdq can also create an example instruction file with all genres listed so
that you can check your genre names properly. It will not hurt to have all the
genres listed, but it is totally unneeded. The example file uses the bare
genre shorthand form. -e will enumerate the station configs visible to
mpdq, and -x will create the example default config as
default_example.cfg.
If the instruction default.cfg exists in the configuration directory, it will
automatically be used. If that file does not exist, the default value (1) will
be applied to all genres.
Station files are just instruction files kept in the config directory as
named presets, for example General_mix.cfg.
-c station_name or --config station_name copies that station file to
default.cfg, nothing more.
-s station_name or --station station_name changes to that station, copies it
to default.cfg, clears the current song logs, optionally adds a random track
from the Bumper genre, and then fills the queue.
If fzf is installed, both -s / --station and station-style -c /
--config can also open an interactive chooser when the requested station is
not matched directly, or when they are given without an argument.
mpdq [-c /path/to/file|--config /path/to/file|-c station_name|--config station_name][-s station_name|--station station_name][--album-mins MINUTES][--artist-mins MINUTES][-e|--enumerate][-f|--force][-h|--help][-l|--loud][--noreplay HOURS][-r|--reset][--rotate HOURS][-v|--version][-x|--example]
mpdq has the following command line switches:
-c FILE, --config FILE : Copy an explicit instruction file from any path to default.cfg-c STATION, --config STATION : Change to a station config by name, or choose interactively-s STATION, --station STATION : Change to a station config by name, or choose interactively--album-mins MINUTES : Override album_mins from the config file for the current run--artist-mins MINUTES : Override artist_mins from the config file for the current run-e, --enumerate : Enumerate the station configs visible to mpdq, one per line, excluding default.cfg and default_example.cfg-f, --force : Force MPD to have the right playback settings-h, --help : Show a short help message-l, --loud : Give more feedback to terminal (yes, this means the default is quiet mode)--noreplay HOURS : Override no_replay_rotate from the config file for the current run-r, --reset : Clear both played-song logs immediately--rotate HOURS : Override rotate_time from the config file for the current run-v, --version : Show the current mpdq version-x, --example : Create default_example.cfg in the config directory with all visible genres listedIt should be run as a single-run process or using watch (e.g. watch -n 60 mpdq).
The --album-mins, --artist-mins, --noreplay, and --rotate switches
change only the current run; they do not rewrite mpdq.ini.
With each run, mpdq will add tracks to the MPD queue until the queue reaches
queuesize, and then exit.
mpdq.ini is set up properly, you can do “random mode” by running mpdq by itself.default.cfg set up as well, you can just run mpdq with no switches.-c /full/path/to/file.cfg.Because you define the hostname, it does not have to be on the same machine
running MPD. If remote=0, mpdq will still check file existence locally, so
you will need an identical music library structure. For example, I use a shared
NFS mount. If that does not apply, set remote=1.
mpdq logs what songs it has played, and will not repeat the same song, album,
or artist during the time periods specified in the config file. It does not
log songs played or added in any other way.
If mpdq exhausts all available options, it will do an emergency rotation of
both logs and tighten the effective lookback window further each time that
happens, resetting that emergency behavior once a valid song is selected.
mpdq will not add any tracks to the queue unless:
If you toggle any of those, then mpdq will do nothing.
With single-run mode, mpdq reads from the instruction file with each run. This
means that you can create different instruction files and either copy them to
default.cfg or use the -c switch to change your upcoming (random-ish) music.
Steven Saus injects people with radioactivity for his day job, but only to serve the forces of good.
Mostly.