From 6bceb12869d4a9301c3dd1ba7aa7a30a16692729 Mon Sep 17 00:00:00 2001 From: Wolfgang Müller Date: Sun, 13 Feb 2022 18:25:20 +0100 Subject: content: Add new post: "Getting MPD to parse TIT1 in MP3 files" --- content/17/index.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 content/17/index.md (limited to 'content') diff --git a/content/17/index.md b/content/17/index.md new file mode 100644 index 0000000..2c79af6 --- /dev/null +++ b/content/17/index.md @@ -0,0 +1,81 @@ ++++ +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. -- cgit v1.2.3-2-gb3c3