zunzuncito

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.