if org_str is None:
return ()
if isinstance(org_str, list):
- return (x.strip() for x in org_str)
+ return tuple(x.strip() for x in org_str)
org_str = org_str.strip()
if TAG_SPLITTER in org_str:
return clean_tuple(org_str.split(TAG_SPLITTER))
return await asyncio.to_thread(parse_tags, input_file, file_size)
-def parse_tags(input_file: str, file_size: int | None = None) -> AudioTags:
+def parse_tags(input_file: str, file_size: int | None = None) -> AudioTags: # noqa: PLR0915
"""
Parse tags from a media file (or URL). NOT Async friendly.
if (
not input_file.startswith("http")
and input_file.endswith(".mp3")
- and "musicbrainzrecordingid" not in tags.tags
and os.path.isfile(input_file)
):
# eyed3 is able to extract the musicbrainzrecordingid from the unique file id
if uf_id.owner_id == b"http://musicbrainz.org" and uf_id.uniq_id:
tags.tags["musicbrainzrecordingid"] = uf_id.uniq_id.decode()
break
+ if audiofile.tag.version == (2, 4, 0):
+ # ffmpeg messes up reading ID3v2.4 tags from mp3 files, especially
+ # on multi-item tags. We need to read the TXXX frames manually
+ if frameset := audiofile.tag.frame_set.get(b"TXXX"):
+ for raw_tag in frameset:
+ if not hasattr(raw_tag, "description"):
+ continue
+ if raw_tag.description.upper() == "ARTISTS":
+ tags.tags["artists"] = raw_tag.text.split("\x00\ufeff")
+ if raw_tag.description == "MusicBrainz Artist Id":
+ tags.tags["musicbrainzartistid"] = raw_tag.text.split("\x00\ufeff")
+ if raw_tag.description == "MusicBrainz Album Artist Id":
+ tags.tags["musicbrainzalbumartistid"] = raw_tag.text.split(
+ "\x00\ufeff"
+ )
+ if frameset := audiofile.tag.frame_set.get(b"TSOP"):
+ for raw_tag in frameset:
+ if not hasattr(raw_tag, "text"):
+ continue
+ tags.tags["artistsort"] = raw_tag.text.split("\x00\ufeff")
+ if frameset := audiofile.tag.frame_set.get(b"TSO2"):
+ for raw_tag in frameset:
+ if not hasattr(raw_tag, "text"):
+ continue
+ tags.tags["albumartistsort"] = raw_tag.text.split("\x00\ufeff")
+ if frameset := audiofile.tag.frame_set.get(b"TCON"):
+ for raw_tag in frameset:
+ if not hasattr(raw_tag, "text"):
+ continue
+ tags.tags["genre"] = raw_tag.text.split("\x00\ufeff")
del audiofile
return tags
except subprocess.CalledProcessError as err: