+++ 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.