beetbox / mediafile

elegant audio file tagging
http://mediafile.readthedocs.io/
MIT License
97 stars 24 forks source link

In MP3s, TXXX fields are always case insensitive #62

Open jimbo27 opened 1 year ago

jimbo27 commented 1 year ago

Beets seems to write replaygain tags in upper-case regardless of changelog entry 1.3.2 (https://beets.readthedocs.io/en/stable/changelog.html#december-22-2013) There are music player in the wild which only understand lower-case ReplayGain tags (Poweramp, KODI),

Using an actual version of a of Beets I can only find upper-case ReplayGain tags in my tagged files with a hex editor.

How I reproduced it:

First of all I download a clean WAV file from bandcamp.com for example. I convert the WAV file to a mp3 via Foobar using the Lame mp3 encoder. After that this mp3 goes into Picard. This goes through processing by Beets. For this I use a Docker Beets version (https://hub.docker.com/r/linuxserver/beets). After that I get a mp3 file including replay gain tags: 03 - New Light.mp3

03.-.New.Light.zip

Using a hex editor I only find upper-case ReplayGain tags in the header of the file.

192885491-bf485e2e-22b7-48fb-8386-0ed8d8900031

I tried beet write (files have not changed) and beet write -f (files have changed) but the mp3 files still only have upper-case ReplayGain tags.

I also tried: I have completely deleted the ReplayGain tags from a series of files with zero and checked that they are really gone in the library (info) and the mp3 files. After that I re-tagged them with replaygain (replaygain). After that I found the ReplayGain tags again, only in upper-case.

I changed the lines of code in mediafile.py (https://github.com/beetbox/mediafile/blob/edc64145e9e96624f8a77fd3cb929891c946d4dc/mediafile.py#L2202-L2209) to see what tags are written. After applying scrub and relaygain again, I suddenly found two tags in my file, although with different names. So when both are named differently, all of a sudden both show up. If both have the same name but are capitalized differently, they don't show up.

194117912-0c47220f-0332-4673-b2b3-2ef49e6a7eb8

194117932-44bebc12-37e3-46a3-ac4a-eabd21f8424a

sampsyo commented 1 year ago

Thank you for the thorough investigation. This is definitely a bug. The problem is here, in MP3DescStorageStyle: https://github.com/beetbox/mediafile/blob/edc64145e9e96624f8a77fd3cb929891c946d4dc/mediafile.py#L905-L909

Namely, when storing data into an ID3 TXXX field, which is disambiguated by its desc field, we currently match that desc string case-insensitively. This means that, if we first write the upper-case version of this field, then the second call to store will modify that field—rather than creating a second entry, as intended.

We should probably introduce a mode where these fields can be made case sensitive, as is required in this case.