+++
date = 2022-02-13T18:25:11+01:00
title = "Getting MPD to parse TIT1 in MP3 files"
[taxonomies]
tags = ["TIL"]
+++
I have a pretty extensive music library that I manage with MPD, the [Music
Player Daemon](https://www.musicpd.org/). For the longest time now I have also
been aware of [`beets`](https://beets.readthedocs.io/en/stable/), 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](https://musicbrainz.org/) 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](https://www.discogs.com/). `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](https://id3.org/id3v2.4.0-frames), 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](https://github.com/MusicPlayerDaemon/MPD/issues/563) 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](https://github.com/MusicPlayerDaemon/MPD/commit/319c9699fb09e7c35e2aafa022ff8e1f0dcfcd8b#diff-740cf5f8b0a6d5c79ba81c3c4325726dbac10a838f5f704b630f6a8967574b60R320)
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](https://ffmpeg.org/), something dawned on me. Perhaps it was FFmpeg
that was reading the tags.
[Indeed it was](https://github.com/MusicPlayerDaemon/MPD/blob/ad4cf79cc967f973f264efe1024f5be1c9a962ec/src/decoder/plugins/FfmpegMetaData.cxx#L75-L94).
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](https://github.com/MusicPlayerDaemon/MPD/blob/ad4cf79cc967f973f264efe1024f5be1c9a962ec/src/decoder/plugins/FfmpegMetaData.cxx#L61-L62).
Crucially, FFmpeg
[does not expose](https://git.ffmpeg.org/gitweb/ffmpeg.git/blob/68595b46cb374658432fff998e82e5ff434557ac:/libavformat/id3v2.c#l64)
`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](https://ffmpeg.org/pipermail/ffmpeg-devel/2022-February/292948.html)
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](https://github.com/MusicPlayerDaemon/MPD/pull/1439)
that clarifies how exactly MPD reads metadata.