Add extra artist splitters in tag parser (#2163)
authorOzGav <gavnosp@hotmail.com>
Fri, 2 May 2025 15:24:44 +0000 (01:24 +1000)
committerGitHub <noreply@github.com>
Fri, 2 May 2025 15:24:44 +0000 (17:24 +0200)
music_assistant/helpers/tags.py

index 7d8d23542e1852ffd497828e545e3b425fee4e14..2094fa7d70b91643da3edba9eaa8178e918524f6 100644 (file)
@@ -57,16 +57,25 @@ def split_items(org_str: str, allow_unsafe_splitters: bool = False) -> tuple[str
 
 
 def split_artists(
-    org_artists: str | tuple[str, ...], allow_ampersand: bool = False
+    org_artists: str | tuple[str, ...], allow_extra_splitters: bool = False
 ) -> tuple[str, ...]:
     """Parse all artists from a string."""
     final_artists: list[str] = []
     # when not using the multi artist tag, the artist string may contain
     # multiple artists in freeform, even featuring artists may be included in this
     # string. Try to parse the featuring artists and separate them.
-    splitters = ("featuring", " feat. ", " feat ", "feat.")
-    if allow_ampersand:
-        splitters = (*splitters, " & ")
+    splitters = [
+        " featuring ",
+        " feat. ",
+        " feat ",
+        " duet with ",
+        " with ",
+        " ft. ",
+        " vs. ",
+    ]
+    splitters += [x.title() for x in splitters]
+    if allow_extra_splitters:
+        splitters += [" & ", ", ", " + "]
     artists = split_items(org_artists, allow_unsafe_splitters=False)
     for item in artists:
         for splitter in splitters:
@@ -150,6 +159,11 @@ class AudioTags:
         if tag := self.tags.get("artist"):
             if TAG_SPLITTER in tag:
                 return split_items(tag)
+            if len(self.musicbrainz_artistids) > 1:
+                # special case: artist noted as 2 artists with ampersand or other splitter
+                # but with 2 mb ids so they should be treated as 2 artists
+                # example: John Travolta & Olivia Newton John on the Grease album
+                return split_artists(tag, allow_extra_splitters=True)
             return split_artists(tag)
         # fallback to parsing from filename
         title = self.filename.rsplit(os.sep, 1)[-1].split(".")[0]
@@ -183,10 +197,10 @@ class AudioTags:
             if TAG_SPLITTER in tag:
                 return split_items(tag)
             if len(self.musicbrainz_albumartistids) > 1:
-                # special case: album artist noted as 2 artists with ampersand
+                # special case: album artist noted as 2 artists with ampersand or other splitter
                 # but with 2 mb ids so they should be treated as 2 artists
                 # example: John Travolta & Olivia Newton John on the Grease album
-                return split_artists(tag, allow_ampersand=True)
+                return split_artists(tag, allow_extra_splitters=True)
             return split_artists(tag)
         return ()