#mpd #music #daemon

bin+lib mpdpopm

Maintain ratings & playcounts for your mpd server

2 releases

new 0.1.13 Nov 20, 2020
0.1.12 Oct 22, 2020

#25 in Multimedia



Table of Contents

  1. Introduction
  2. Prerequisites
  3. Installing
  4. Getting Started
    1. Program Structure
    2. Configuration
    3. Generalized Commands
  5. Status & Roadmap


mpdpopm provides a companion daemon to mpd for maintaining play counts, ratings and last-played timestamps, along with an associated CLI for talking to the daemon. Similar to mpdfav, but written in Rust (which I prefer to Go), it will maintain this information in your sticker database. Along the lines of mpdcron, it will also allow you to keep that information up-to-date in your tags by invoking external (user-provided & -configured) commands.


  • Rust: Rust is a memory- & thread-safe language with no runtime or garbage collector
  • Music Player Daemon: "Music Player Daemon (MPD) is a flexible, powerful, server-side application for playing music. Through plugins and libraries it can play a variety of sound files while being controlled by its network protocol."


mpdpopm is available on crates.io, but you can also get a source tarball & install it through the usual configure && make && make install:

curl -L -O https://github.com/mpdpopm/archive/0.1.13.tar.gz
tar xf mpdpopm-0.1.13.tar.gz && cd mpdpopm-0.1.13
./configure && make all check
sudo make install

Getting Started

Program Structure

mpdpopm provides two programs:

  1. mppopmd is the companion daemon process
  2. mppopm is the associated command-line interface to the daemon

I still haven't provided a systemd service unit, so you'll have to run the daemon process manually (say mppopmd --help for the relevant options; you may want to run it in the foreground while you get it up & running). Once up, it will create an mpd channel for commands ("unwoundstack.com:commands" by default, but this is configurable) and begin monitoring mpd playback. Every time mpd plays a track, it will increment that track's playcount & last-played timestamp in the sticker database. If any mpd client sends the "rating" command to our channel, mpdpopm will also update the corresponding sticker.

Of particular interest is the fact that the user can configure commands to be run when the playcount is updated or the rating is set. You might, for instance, use this feature to update the PCNT and/or POPM tags accordingly.

mppopm is a simple CLI that will let you get & set playcounts & ratings; say mppopm --help to see what it offers.


mppopmd takes an optional configuration file. I haven't documented it fully yet– here is mine:

((log . "/home/mgh/var/log/mppopmd.log")
 (host . "")
 (port . 6600)
 (local_music_dir . "/mnt/Took-Hall/mp3")
 (playcount_sticker . "unwoundstack.com:playcount")
 (lastplayed_sticker . "unwoundstack.com:lastplayed")
 (played_thresh . 0.6)
 (poll_interval_ms . 5000)
 (playcount_command . "/home/mgh/bin/scribbu")
 (playcount_command_args . ("popm" "-a" "-A" "-b" "-o" "sp1ff@pobox.com" "-C" "%playcount" "%full-file"))
 (commands_chan . "unwoundstack.com:commands")
 (rating_sticker . "unwoundstack.com:rating")
 (ratings_command . "/home/mgh/bin/scribbu")
 (ratings_command_args . ("popm" "-a" "-A" "-b" "-o" "sp1ff@pobox.com" "-r" "%rating" "%full-file")))

Generalized Commands

The admin can also configure arbitrary commands to be run server-side in response to messages received on the mpdpopm command channel. As an example, an entry in the configuration file like this:

(gen_cmds .
        (((name . "set-genre")
          (formal_parameters . (Literal Track))
          (default_after . 1)
          (cmd . "/home/mgh/bin/scribbu")
          (args . ("genre" "-a" "-C" "-g" "%1" "%full-file"))
          (update . TrackOnly)))

will define a new command "set-genre", with two parameters, the second of which can be omitted (it will default to the current track). When mpdpopm receives this command (i.e. when a client says something like:

sendmessage unwoundstack.com:commands "set-genre Rock"

mpdpopm will invoke /home/mgh/bin/scribbu like this:

/home/user/bin/mgh/scribbu genre -a -C -g Rock "${music-dir}/${song URI}"

Status & Roadmap

I am currently using mpdpopm day in & day out with my music collection, but it's early days. I have chosen the version number (0.1) in the hopes of indicating that. I'm considering adding another sticker for a tag cloud, and adding a filter feature that would extend the MPD "find" capability to allow queries that include the stickers that mpdpopm manages– so you could, for instance, say:

find (artist =~ foo) and (rating > 175)

MPD would handle the "artist =~" clause & mpdpopm the "rating >" clause, as well as combining the results.

Suggestions, bug repors & PRs welcome!


~163K SLoC