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.
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
mpdpopm provides two programs:
mppopmd
is the companion daemon processmppopm
is the associated command-line interface to the daemonI 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 . "192.168.1.6")
(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")))
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}"
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!