summaryrefslogtreecommitdiffstatshomepage
path: root/content
diff options
context:
space:
mode:
authorWolfgang Müller2022-02-13 18:25:20 +0100
committerWolfgang Müller2022-02-13 18:25:20 +0100
commit6bceb12869d4a9301c3dd1ba7aa7a30a16692729 (patch)
treed79891d5342bbff1d3640152d5da042d3a9ef1e4 /content
parentfe8b9a8cbe2be67c9995c466130e240725b63f64 (diff)
downloadzunzuncito-6bceb12869d4a9301c3dd1ba7aa7a30a16692729.tar.gz
content: Add new post: "Getting MPD to parse TIT1 in MP3 files"
Diffstat (limited to 'content')
-rw-r--r--content/17/index.md81
1 files changed, 81 insertions, 0 deletions
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.