{"id":18878247,"url":"https://github.com/uriel1998/mpdq","last_synced_at":"2026-03-14T09:08:51.016Z","repository":{"id":40288344,"uuid":"110480949","full_name":"uriel1998/mpdq","owner":"uriel1998","description":"Automatic MPD \"smart playlist\" creator with minimal but hackable setup.","archived":false,"fork":false,"pushed_at":"2024-12-13T22:27:47.000Z","size":587,"stargazers_count":24,"open_issues_count":6,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-14T18:58:38.494Z","etag":null,"topics":["bash","genre","linux","mpd","mpd-database","music-library","playlist","playlist-generator"],"latest_commit_sha":null,"homepage":"https://uriel1998.github.io/mpdq/","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/uriel1998.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"roadmap.txt","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-11-13T00:20:31.000Z","updated_at":"2024-12-13T22:27:50.000Z","dependencies_parsed_at":"2024-02-01T05:30:36.349Z","dependency_job_id":"c9628b36-1b76-48f6-a552-dde57dfbe218","html_url":"https://github.com/uriel1998/mpdq","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/uriel1998/mpdq","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uriel1998%2Fmpdq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uriel1998%2Fmpdq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uriel1998%2Fmpdq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uriel1998%2Fmpdq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/uriel1998","download_url":"https://codeload.github.com/uriel1998/mpdq/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/uriel1998%2Fmpdq/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273410451,"owners_count":25100518,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-03T02:00:09.631Z","response_time":76,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","genre","linux","mpd","mpd-database","music-library","playlist","playlist-generator"],"created_at":"2024-11-08T06:25:22.510Z","updated_at":"2026-03-14T09:08:51.009Z","avatar_url":"https://github.com/uriel1998.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mpdq\n\nAutomatic MPD playlist or party mode creator to provide weighted randomness while autoqueuing MPD without relying on external services.\n\n![mpdq logo](https://raw.githubusercontent.com/uriel1998/mpdq/master/mpdq-open-graph.png \"logo\")\n\n![mpdq in action](https://raw.githubusercontent.com/uriel1998/mpdq/master/mpdq.gif \"mpdq in action\")\n\n### Change from prior versions!\n\nThe program has been rewritten for simplicity and to avoid subprocesses; each run will add a configurable number of tracks to the queue. Adding a self-contained idle loop is in the roadmap.\n\nDependency on ffmpeg/exiftool/etc is removed, because I somehow didn't think to just query `mpc`. Sigh.\n\n## Contents\n\n1. [About](#1-about)\n2. [License](#2-license)\n3. [Prerequisites](#3-prerequisites)\n4. [Installation](#4-installation)\n5. [Setup](#5-setup)\n6. [Usage](#6-usage)\n7. [TODO](#7-todo)\n\n---\n\n## 1. About\n\n`mpdq` is an auto-queuing system for MPD to create a flexible and configurable \"party mode\" effect with randomization and (re)discovery of your own music. It is inspired by the eclectic soundtracks of *Letterkenny*, *High Fidelity*, *Doom Patrol*, and many more. In-depth explanation: [my blog](https://ideatrash.net/?p=121759).\n\n`mpdq` will autoqueue random tracks from your existing music library, with per-genre weighting and simple defaults.\n\nBecause it uses `mpd`'s own data, new tracks and changes to your music library will be incorporated when `mpd` is updated.\n\n`mpdq` also now has a \"radio station\" toggle to let you easily switch between presets with an optional station-tuning effect.\n\n## 2. License\n\nThis project is licensed under the MIT License. For the full license, see `LICENSE`.\n\n## 3. Prerequisites\n\nRequired (non-basic Linux packages):\n\n- [mpd](https://www.musicpd.org/)\n- [mpc](http://git.musicpd.org/cgit/master/mpc.git/)\n\nOptional:\n\n- [fzf](https://github.com/junegunn/fzf) for interactive station selection when using `mpdq -s` without a station name.\n\nEverything else used by `mpdq` is part of a standard Linux userland (`bash`, GNU coreutils, `grep`, `sed`, `awk`, `findutils`, `procps`).\n\n## 4. Installation\n\nPlace `mpdq.ini` in `$XDG_CONFIG_HOME/mpdq`:\n\n```ini\n[SERVER]\nmusicdir=/directory/to/music\nmpdserver=localhost\nmpdport=6600\nmpdpass=hackme\nsonglength=15\nqueuesize=10\n# in hours\nrotate_time=1\n# in minutes\nalbum_mins=30\nartist_mins=30\n# Genres to exclude from the above two checks\ngenres_exclude_album_check=Sound Clip,Classical\n```\n\n## 5. Setup\n\n### From the INI file\n\n`rotate_time` in the ini file defines how long `mpdq` keeps a log, in hours, and helps define how often each genre will be played.\n\n`no_replay_rotate` in the ini file defines how long you will *not* hear a particular track again, in hours, like how radio stations used to promise you wouldn't hear the same song twice in a workday. This checks the *track filename*, not the *title*.\n\n`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`.\n\n`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.\n\n### Instruction files\n\nThe 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 must be specified on the command line. Without an instruction file, `mpdq` will shuffle through your entire library with an equal weight to each genre.\n\nEach instruction file is a series of lines in the format `genre=weight`, like this:\n\n```txt\nDefault=1\nRock=3\nClassical=0\n```\n\nThat \"weight\" is the *maximum* number of times that genre will be played in the interval you set for `rotate_time` in the ini file. The `Default` line is applied to all genres that are not explicitly named in the instruction file.\n\nIn 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`, and Classical, which will *never* be played per `rotate_time`.\n\nAdditionally, the weight will *increase* the chances of that genre being selected. It increases the number of chances of that genre being *selected* as well as the maximum number of times per `rotate_time`. Without that, playlists are *very* eclectic at first, then slowly get more and more homogenous, which isn't what we want here.\n\nThis allows both very eclectic selections (as with the example above) and very focused selections, such as:\n\n```txt\nDefault=0\nIndustrial=1\nGothic=1\n```\n\n**Capitalization Matters**\n\n`mpdq` can also create an example instruction file with *all* genres listed so that you can check your genre names properly. It won't *hurt* to have all genres listed, but it is totally unnecessary.\n\nThe instruction file should end in a newline. If it does not, `mpdq` will add one automatically.\n\nIf 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.\n\n**`mpdq` now ignores the genres `Bumper` and `Sound Clip` entirely.**\n\n## 6. Usage\n\n`mpdq [-d #][-c /path/to/file][-khe]`\n\n`mpdq` has the following command-line switches:\n\n- `-c`: Which instruction file to use.\n- `-d`: Override the default priority in the instruction file.\n- `-k`: Kill a currently running `mpdq` process.\n- `-e`: Create an example instruction file at `$XDG_CONFIG_HOME/mpdq/example_instruction`.\n- `-f`: Force MPD to have the right playback settings (see `Pausing the program` below).\n- `-s`: Choose a \"station\" (config file), automatically crop the queue, and switch to it.\n- `-h`: Show a short help message.\n- `--loud`: Give more terminal feedback (the default is quiet mode).\n\nIt should be run as a single-run process or using the `watch` command (for example, `watch -n 60 mpdq`).\n\nWith each run, `mpdq` will add `queuesize` (from the ini file) tracks to the MPD queue and then exit.\n\n- If `mpdq.ini` is set up properly, you can do \"random mode\" by running `mpdq` by itself and setting the frequency with `-d`.\n- If you've got `default.cfg` set up as well, you can run `mpdq` with no switches.\n\nBecause you define the hostname, it does *not* have to be on the same machine running MPD. If it is not on the same machine, set REMOTE=1 in the ini file so it does not doublecheck the file path.\n\n`mpdq` logs what songs it has played and will not repeat the same song during the time specified in `mpdq.ini`. It does *not* log songs played or added in any other way.\n\n### Changing the station\n\nIf you run `mpdq -s [name of configuration file]`, it will trim the queue to just the currently playing song, load that configuration, and follow those instructions to fill up the queue. For example, `mpdq -s rock` will load the instructions in `$HOME/.config/mpdq/rock.cfg`. That lets it finish playing the current song before switching. If you leave off which station to use and have `fzf` installed, it'll let you choose interactively.\n\nYou can put genre-based instruction files in `$XDG_CONFIG_HOME/mpdq/stations` to allow selecting those as well. There is also a helper script to prune down some of the many genre names and eliminate instruction sets that have no valid genres in them. While they'll work as-is, they're meant to be templates you quickly adapt yourself.\n\n**If you have any tracks with the genre `Bumper`, `mpdq` will add one before queuing more tracks when changing stations.** You can use this for your own \"station tuning\" effects; there are some from Freesound in the repository.\n\n### Pausing the program\n\nWhether running in single-run mode or the (upcoming) ongoing loop mode, `mpdq` will keep checking the queue and adding tracks, which isn't always what you want.\n\n`mpdq` will *not* add *any* tracks to the queue unless:\n\n- random is **off**\n- repeat is **off**\n- consume is **on**\n\nIf you toggle any of those, `mpdq` will do nothing (not even rotate the song log).\n\n### Advanced Usage\n\nWith single-run mode, `mpdq` reads from the instruction file with each run. This means 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.\n\n## 7. TODO\n\n- Add loop back in and utilize relay mechanism to change instruction file.\n- Switch between loop mode and single-run mode.\n- Add in what to do when all genres run through in logrotate time period.\n- Add a lighterweight way to handle log rotation, since it's called frequently.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Furiel1998%2Fmpdq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Furiel1998%2Fmpdq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Furiel1998%2Fmpdq/lists"}