quodlibet / mutagen

Python module for handling audio metadata

Home Page:https://mutagen.readthedocs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mutagen updates ID3v1 tags but does not save ID3v2 tags

unikitty37 opened this issue · comments

I'm trying to reorganise the tags in some old radio programmes that I ripped years ago, and am trying to change artist, title, and album based on the filename. I'm also removing some comments that the ripping software auto-added.

(Please excuse any poor-quality Python — I'm a Ruby developer who's had to learn a little Python to do this as there are no up-to-date and working Ruby libraries that I can find to do this :)

#!/usr/bin/env python3

from sys import argv
import re
from mutagen.id3 import ID3, ID3v1SaveOptions, TIT2, TALB, TPE1, TPE2

pattern = re.compile(r'(?P<programme>[^/]+) - S(?P<series>\d+) - E(?P<episode>\d+) - (?P<title>.*)\.mp3$')

filenames = argv[1:]
for filename in filenames:
  matches = pattern.search(filename)
  if matches == None:
    break

  audio = ID3(filename)
  audio.update_to_v24()
  audio.delall('COMM')
  audio.add(TIT2(text=f'{matches.group("episode")} - {matches.group("title")}'))
  audio.add(TALB(text=f'{matches.group("programme")} - Series {matches.group("series")}'))
  audio.add(TPE1(text=f'{matches.group("programme")}'))
  audio.add(TPE2(text=f'{matches.group("programme")}'))
  audio.save(v1 = ID3v1SaveOptions.CREATE)

…but when I run it, it changes the ID3v1 tags but doesn't seem to save the ID3v2 tags, despite the documentation for save() saying "The lack of a way to update only an ID3v1 tag is intentional."

I'm not sure whether this is me doing something wrong (extremely likely!) or a Mutagen bug. Could somebody please point me in the right direction?

(BTW, shouldn't that v2 parameter in the list be v2_version? :)

Here's the before and after, with some light redaction (the id3v2 command is from https://id3v2.sourceforge.io/):

╰─▷ id3v2 -l "/tmp/Programme Name - S01 - E01 - Episode Title.mp3"
id3v1 tag info for /tmp/Programme Name - S01 - E01 - Episode Title.mp3:
Title  : Programme Name                   Artist: Programme Name
Album  : Programme Name - Series 01       Year: 1922, Genre: Comedy (57)
Comment: This is a comment                Track: 1
id3v2 tag info for /tmp/Programme Name - S01 - E01 - Episode Title.mp3:
TIT2 (Title/songname/content description): Programme Name
TPE1 (Lead performer(s)/Soloist(s)): Programme Name
TCON (Content type): Comedy (57)
TPE2 (Band/orchestra/accompaniment): Programme Name
TALB (Album/Movie/Show title): Programme Name - Series 01
COMM (Comments): ()[eng]: This is a comment
TYER (Year): 1922
TRCK (Track number/Position in set): 1

╰─▷ retag.py "/tmp/Programme Name - S01 - E01 - Episode Title.mp3"

╰─▷ id3v2 -l "/tmp/Programme Name - S01 - E01 - Episode Title.mp3"
id3v1 tag info for /tmp/Programme Name - S01 - E01 - Episode Title.mp3:
Title  : 01 - Episode Title           Artist: Programme Name
Album  : Programme Name - Series 01       Year: 1922, Genre: Comedy (57)
Comment:                                 Track: 1
/tmp/Programme Name - S01 - E01 - Episode Title.mp3: No ID3v2 tag

System info:

macOS 12.6 (21G115)

╰─▷ pip3 show mutagen
Name: mutagen
Version: 1.46.0
Summary: read and write audio tags for many formats
Home-page: https://github.com/quodlibet/mutagen
Author: Christoph Reiter
Author-email: reiter.christoph@gmail.com
License: GPL-2.0-or-later
Location: /opt/homebrew/lib/python3.10/site-packages
Requires:
Required-by:

╰─▷ python3 --version
Python 3.10.7

If there are no ID3v2.x tags yet mutagen does not automatically add them. You need to do some check like:

if audio.tags is None:
    audio.add_tags()

Thanks, but the file already has ID3v2 tags (as shown in the example output). Adding a print(mutagen.File(filename).tags.pprint()) just before audio = ID3(filename) produces this:

COMM==eng=This is a comment
COMM=ID3v1 Comment=eng=This is a comment
TALB=Programme Name - Series 01
TCON=Comedy
TDRC=1922
TIT2=Programme Name
TPE1=Programme Name
TPE2=Programme Name
TRCK=1

In any case, audio.tags doesn't seem to be the right thing:

Traceback (most recent call last):
  File "/Users/me/bin/retag.py", line 18, in <module>
    if audio.tags is None:
AttributeError: 'ID3' object has no attribute 'tags'

@unikitty37 The issue seems to be not writing the file, but the verification with the id3v2 utility, which does not support ID3v2.4. Either verify with e.g. mutagen-inspect or another tool actually supporting v2.4 tags, or save v2.3 tags by passing v2_version=3 to the save call.

I am closing this. I tried your script directly and it does save the ID3v2.4 tags. The old id3v2 utility does not support that. Saving with v2_version=3 makes it visible in that utility as well.

(BTW, shouldn't that v2 parameter in the list be v2_version? :)

Docs are fixed with 3cbcc1b