I have a pretty extensive music library that I manage with MPD, the Music
Player Daemon. For the longest time now I have also
been aware of beets
, another
management system for music libraries. I played around with it a few times but
never took the plunge to have it organize my entire collection.
A few days ago, whilst looking up a particularly obscure recording, I ended up finding it on MusicBrainz and decided to give beets, which integrates very tightly with that service, another serious try.
Yesterday I finally completed a first rough import of my entire library (which
encompasses about 20,000 songs in 1400 albums). Given the integration with
MusicBrainz, I now try to map every album to a release in their database. If I
can’t find it there, I instead fall back to an old favourite of mine,
Discogs. beets
will automatically update and
correct any tags once I select the right release.
Whilst importing I decided that I should make more use of the “Grouping” tag as a way to organize albums into an arbitrary group. This is useful if a series of media features music that was composed by multiple artists. By matching on the Haibane Renmei grouping, for example, I can find all music that was made for that show, without having to keep artist names in mind.
“Grouping” seemed well-supported in MPD, but whilst updating some albums that I (sadly) only have in MP3 format, I found that MPD would not add the grouping information to its database.
As per the ID3v2.4 standard, the TIT1
frame is used for this kind of information in MP3 files. Sure enough, that tag
was set correctly by beets
, and both mutagen-inspect
and ffprobe
found it.
MPD, however, even though
this PR had been merged almost
3 years ago, refused to pick it up.
After having the #mpd
IRC channel sanity-check my configuration, I
investigated some more. Perhaps my version of libid3tag
was outdated. It
wasn’t. Perhaps there were some encoding issues, but then why would other tags
from the same file work fine? Couldn’t be that either. I hooked up GDB and found
that
this line from the PR
was never actually reached at all!
I decided to look a bit closer at how exactly MPD reads tags. The specific
scan_id3_tag
function that the PR modified is only called in two places,
plugins/DsdLib.cxx
and (indirectly) in plugins/MadDecoderPlugin.cxx
. I had
neither of these decoders installed, so… MPD just never got to read anything.
Yet how was I getting any tags, then?
After some spelunking in the decoder plugin folders and with the fact on my mind that the only decoder I had actually compiled in was FFmpeg, something dawned on me. Perhaps it was FFmpeg that was reading the tags.
Indeed it was. Turns out that FFmpeg does all of the heavy lifting here, and MPD really just asks it for any metadata and parses the ones it understands.
MPD uses “grouping” as a cross-format identifier for grouping information. It
expects that particular string to be a key in the AVDictionary
returned by
FFmpeg
here.
Crucially, FFmpeg
does not expose
TIT1
as “grouping” in its metadata conversion table, having MPD drop TIT1
on
the floor like a hot potato.
It is debatable where this particular bug should be fixed. I decided to send a patch upstream to FFmpeg, given that more than just MPD can benefit from a fix there. For the next poor soul I also prepared a PR that clarifies how exactly MPD reads metadata.