Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple artists, with custom separator #238

Open
nebula-it opened this issue Apr 28, 2020 · 43 comments · May be fixed by #2524
Open

Support multiple artists, with custom separator #238

nebula-it opened this issue Apr 28, 2020 · 43 comments · May be fixed by #2524

Comments

@nebula-it
Copy link

As discussed here it would be a good idea to implement a setting where end user can select a custom character that will be used to split multiple artist into separate values.

Current Behavior

A song has Contributing Artist value Artist1, Artist2. Navidrome reads the artist as a single value with name "Artist1, Artist2"

Expected Behavior

A song has Contributing Artist value Artist1, Artist2. Navidrome reads the artist and recognizes there are two or multiple artists separated by comma and song show up under the Artist page of Artist1 and Artist2.
The separator character can be selected (comma in the above example) by end user depending on how their library is tagged.

@deluan
Copy link
Member

deluan commented Apr 28, 2020

Thanks, I will try to work on this after #211

@JaneX8
Copy link
Contributor

JaneX8 commented Apr 28, 2020

I would like to see this available for multiple custom seperators, not limited to one or several single characters. For uses such as " feat. ", " featuring ", " vs ", " vs." and " versus " and possible " & ", " and ". All should be case insensitive (or optional) and after separation the values should be trimmed.

Maybe we can allow regular expressions for separation? Keep in mind that introduces some possible security implications like ReDoS.

@deluan
Copy link
Member

deluan commented Apr 28, 2020

Yes, the idea is to allow multiple words as separators. Not sure if Regex is any good here (and have the security implications as you said)

@certuna
Copy link
Contributor

certuna commented May 7, 2020

Bear in mind that there is a standard separator: / for id3v2.3, and the null character (0x00) for id3v2.4. Vorbis Comments (used for FLAC) just has multiple ARTIST tags. Other separators like ;,& are technically nonstandard hacks.

The fancier the separators are, the more chance of false positives. Some examples that get split accidentally:

  • "Earth, Wind & Fire"
  • "AC/DC" - this was cited back in the days as the big reason why id3v2.3 was terrible and the spec change for v2.4 was needed :)
  • "Ånd"
  • "Angels Versus Animals"
  • "Little Feat"

Interesting discussions:
https://hydrogenaud.io/index.php?topic=112634.0
https://emby.media/community/index.php?/topic/5731-question-on-music-tags-and-delimiters/
https://community.mp3tag.de/t/multiple-genres-in-1-genre-tag/17159

@deluan
Copy link
Member

deluan commented Jul 5, 2020

ffmpeg (used to extract the tags) does not support id3v2.4 multi-valued tags: https://trac.ffmpeg.org/ticket/6949. I just tested with the latest version and it basically ignore everything after the null separator....

To make this work, I'll need to find an alternative way to read tags (at least id3 tags, have to test with vorbis and mp4), that is robust enough and does not add extra dependencies to the project....

@certuna
Copy link
Contributor

certuna commented Aug 1, 2020

That is pretty terrible actually - three years and still not fixed?

@certuna
Copy link
Contributor

certuna commented Aug 24, 2020

By the looks of it, the ffmpeg devs don't care, so the solution is either find another tag library or write a commit for ffmpeg (how's your C?) - what's the least amount of work?

@deluan
Copy link
Member

deluan commented Aug 24, 2020

Both options are huge tasks (for my limited time). I tried replacing ffmpeg before, but could not find a library that would cover all formats and all required info I need from the files (including duration and bitrate). I also use https://github.com/dhowden/tag to extract pictures (and it gets null-separated multi-valued fields correctly), but it does not provide all info required.

I'll take a look in the ffmpeg codebase, but I don't anticipate a easy change to fix this...

@deluan deluan changed the title Custom character as separator for multiple Artists Support multiple artists, with custom separator Aug 24, 2020
@certuna
Copy link
Contributor

certuna commented Sep 3, 2020

So taglib is our new saviour?

@deluan
Copy link
Member

deluan commented Sep 3, 2020

@certuna I'm still evaluating it, but it seems to be a better option for extracting metadata. Some of the bugs/annoyances we have with ffmpeg don't exist with taglib. I'm doing more tests with it this week

@certuna
Copy link
Contributor

certuna commented Sep 3, 2020

Is there any reason why there still seems to be (reasonably) recent commits but no releases since 2016?

@certuna
Copy link
Contributor

certuna commented Oct 28, 2020

By the way, I see that Picard has introduced a custom tag for "artists" (TXXX:Artists in id3, ARTISTS in Vorbis) to store multivalued artists, presumably so old/noncompliant players don't choke on multivalued fields in the regular "artist" fields TPE1 and ARTIST . An ugly hack I think, but probably worth including this frame when multivalued fields are implemented.

@orlea
Copy link
Contributor

orlea commented Nov 19, 2021

Will this feature be added in the future?

@deluan
Copy link
Member

deluan commented Nov 19, 2021

Yes, definitely. Probably next after some big PRs are merged and I finish Smart playlists

@krateng
Copy link

krateng commented May 9, 2022

In the meantime, while Navidrome can only accept one artist, is there something that could be done about the multiple artist tags in Vorbis comments (flac)? If I have a track with

ARTIST=K/DA
ARTIST=Seraphine

it only shows one of them - would be nice to simply display that as K/DA;Seraphine for the purpose of scrobbling.

@certuna
Copy link
Contributor

certuna commented May 10, 2022

That's a good idea - I'll have a look how hard it is to implement that. BTW this can only be done when using TagLib as a scanner, since ffmpeg will never read the second value.

I have been thinking whether it makes sense to treat album artists and track artists differently: Abum Artists, reduce "Artist1;Artist2" to "Artist1", Track Artist, store as "Artist1;Artist2". But this is probably confusing for users and also not how a lot of people would want it.

All this is temporary anyway, until Navidrome supports multiple artists.

@Baswazz
Copy link

Baswazz commented May 21, 2022

I see LMS is supporting \\ as a separator. This could be an idea also supported with multiple genres.

Artist1\\Artist2

@irdkwmnsb
Copy link

Any progress on this feature?

@KucharczykL
Copy link

Seems this will be fixed in ffmpeg itself according to the latest comments in http://trac.ffmpeg.org/ticket/6949

@jmbannon
Copy link

id3v2.4 using albumartists should be the way multiple artists is implemented, not separators

@certuna
Copy link
Contributor

certuna commented Nov 23, 2022

the custom tag fields artists and albumartists are a pretty messy hack for applications that cannot read multivalued tags correctly, it's probably better to just implement multivalued tags outright.

But once multivalued artists are implemented, it's relatively easy to add support for it - just on scan, do: if artists frame exists, then include the values in that frame

@tam481
Copy link

tam481 commented Jan 2, 2023

This will also help with multilingual tagging where the artist name can be in the native language and perhaps the "ARTISTSORT" tag can be used for the English version of the name etc

@Xarishark
Copy link

Streaming services have made the best version of this right now. On Deezer the album/song appears on both artists pages and where the artists info is it displays both artists as separate clickable links to go to their artist page. Navidrome currently does not even SHOW that there is a second artists let alone let you click him etc.

@certuna
Copy link
Contributor

certuna commented Jun 17, 2023

The advantage that Spotify/Deezer/Tidal have is that they can control the exact formatting of the tags, which is a luxury we don't have. Also, they likely have implemented M2M relations in their underlying DB, which Navidrome doesn't have (yet).

There are basically three main ways that multiple artists are tagged these days:

  1. multi-value like the standard prescribes, so in id3v2.4: TPE1 = "Alice(null)Bob", or in FLAC/Vorbis with: ARTIST = "Alice" and ARTIST = "Bob"
  2. single-value with a non-standard separator, usually semicolon: TPE1 = "Alice;Bob" . The trick here is to avoid using separators that are too often used in artist names: "AC/DC" or "Earth, Wind & Fire" should clearly not be split.
  3. using two tags, one single-value and one multi-value: TPE1 = "Alice feat. Bob" and TXXX:ARTISTS = "Alice(null)Bob". It may seem a bit hacky to use two tags to do the work of one, but this is how MusicBrainz Picard auto-tags by default

All three methods would have to be supported.

I now have an experimental build running with multiple artist support (all three variants), see screenshot below. However, due to the current DB/API limitations, the links in the UI only take you to the first artist. But it's a lot better than nothing. Search does work over all artists, and the album will show up in the artist details pages of both Jay-Z and Kanye West (and also Frank Ocean, Beyoncé, etc).

Screenshot 2023-06-16 at 14 08 49

@jmbannon
Copy link

Looks awesome @certuna
For any beets users, I have a PR up for multi-tag support: beetbox/beets#4743

@certuna
Copy link
Contributor

certuna commented Jun 18, 2023

One of the tricky things of the two-tags approach is the edge case ARTIST = "Alice;Bob" and ARTISTS = "Carol", "Dave" - what should the application use?

@jmbannon
Copy link

jmbannon commented Jun 18, 2023

I thought ARTIST and ALBUMARTIST typically included the join phrase, i.e. "Alice featuring Bob", "Alice, Bob", "Alice ft. Bob", etc. The app should use ARTISTS since it's more uniform. ARTIST should be treated more-so as the display artist

@jmbannon
Copy link

But then again not everyone will have multi-tags, so maybe use ARTIST as a fall-back

@certuna
Copy link
Contributor

certuna commented Jun 18, 2023

Exactly, but this assumes ARTIST has consistency with ARTISTS, which may be true for collections fully managed with autotaggers like Picard/beets, but otherwise not guaranteed, for example when someone has manually fixed tags.

In my experimental branch, ARTISTS is only used when both of the following are true:

  • ARTIST has one value
  • ARTISTS has multiple values

@pjadeslandes
Copy link

I would like to see this available for multiple custom seperators, not limited to one or several single characters. For uses such as " feat. ", " featuring ", " vs ", " vs." and " versus " and possible " & ", " and ". All should be case insensitive (or optional) and after separation the values should be trimmed.

Maybe we can allow regular expressions for separation? Keep in mind that introduces some possible security implications like ReDoS.

I know this is super old, but I'm investigating Navidrome because I have exactly this request.

I'm aware of some of the edge cases that exist, but I always imagine there are ways around them.

For example, "AC/DC" is a continuous string with no spaces, so if using / as a delimiter, put spaces around it.

Also the use of & - to me, that's used to separate different artists, while "and" is not. Eg "Marina and The Diamonds" is one artist, while "Beyoncé & Lady Gaga" is two. And so if I want, I can treat "Prince and The Revolution" as one artist or, better for me, as two by changing the tag to "Prince & The Revolution", not because I need to see The Revolution as an artists, but I'll take that if it means that all of Prince's music is in one place, whether he was with one of his bands or not.

One slight tweak to the request: I'd like to pull artists from the track name using a format like " (feat , , etc)".

Am following the main thread on all the most recent updates. Amazing work by all involved, however far all of this gets. Such a shame commercial players like Plex aren't as dedicated to as high a quality of experience. V happy to pay / donate to something like the Navidrome prject, which is so responsive to such specific user requests.

@certuna
Copy link
Contributor

certuna commented Jun 29, 2023

  • & is an extremely unreliable separator. There are way, way too many single artists/groups with this character in their name - from Years & Years to Earth, Wind & Fire to Kool & The Gang to Milk & Sugar to The Mamas & The Papas. Discogs has over 200,000 (!) artists with & in the name, and these are not all duos.
  • / has less issues, but still has lots of exceptions, Discogs has over 3,000 artists
  • ; is a very reliable separator, Discogs has only 12 artists

Splitting text strings reliably is very hard, this is why the ARTIST/ARTISTS tagging method is used by for example Picard: ARTIST = "Alice featuring Bob", ARTISTS = "Alice", "Bob". This is a workaround so applications that can handle multiple artists use what's in the ARTISTS tag without having to do complex splitting operations, while oldschool applications that can only handle one artist (Plex, Apple Music etc) use the contents of ARTIST.

I'm now experimenting with splitting on phrases like "feat." and "vs.", only if there's no ARTISTS tag. So far this works quite well, but even a phrase like "vs." can throw up annoying edge cases like "Angels vs. Animals", etc. Not to mention that this is a very Anglo-centric approach: characters like & are fairly universal, but it's almost impossible to capture all join phrases like "featuring" in 120+ languages.

@jmbannon
Copy link

My two cents, if ARTIST was possible to reliably split on, there would be no need for ARTISTS. There will always be an edge case, which is why self hosted music should embrace the ARTISTS + ALBUMARTISTS multi-tags. I guarantee Spotify, Deezer, etc use something very similar to ARTISTS in the form of a database.

@certuna
Copy link
Contributor

certuna commented Jun 29, 2023

My two cents, if ARTIST was possible to reliably split on, there would be no need for ARTISTS.

Absolutely true - and ARTIST can be reliably split, the standards (id3, Vorbis, mp4) explicitly tell us how: null-separated strings (id3v2.4) or multiple ARTIST frames (Vorbis, mp4). However, over the past 25 years, users & application developers have ignored the standards, so here were are: trying to unpack other people's workarounds.

I guarantee Spotify, Deezer, etc use something very similar to ARTISTS in the form of a database.

Yeah, but these guys have full control over what goes in, they can just implement M2M relations in the DB, and ignore the millions of songs that the general public has tagged, out there in the wild. This is a luxury that self-hosted music servers don't have. Refactoring the Navidrome database would help with the multiple-artist functionality (hoping that deluan has some time for this somewhere after the UI migration), but we still have the problem of parsing what people have tagged, in a reliable/predictable manner.

@jmbannon
Copy link

Supporting multiple artists for folks who don't have multi-tags, to put it bluntly, is not feasible, and trying to do so I think contributes to the problem of self-hosted music's messy standard for supporting multiple artists that we see today.

The software that I use that does support multiple artists (Kodi, Jellyfin, MusicBee) treats ARTIST/ALBUMARTIST as the display artist containing the join phrases (ft. featuring, with, etc) without trying to be split on, and ARTISTS/ALBUMARTISTS to use strictly for multiple artists. This is the closest standard I've seen that I think should be adopted abroad and in your approach. There is plenty of available software (MusicBrainz Picard currently the best, beets very soon with beetbox/beets#4743) that can add these multi-tags.

Only using multi-tags for multiple artist support will both simplify your PR and help cement this standard. I think it's okay to leave behind folks who refuse to add multi-tags.

(sorry if this comes off as brash, I just want the world to use multi-tags and enjoy multiple artist support like I do :P )

@certuna
Copy link
Contributor

certuna commented Jun 29, 2023

It's not so bad.

  • Supporting standard-conforming ARTIST/TPE1/TPE2 multi-tags (like you tag with mp3tag, Yate, kid3, foobar2k etc) is easy.

  • Supporting the ARTIST+ARTISTS hack/workaround of Musicbrainz Picard is also easy, only thing you need to watch out for is inconsistency between the two tags.

  • The more problematic part is non-standard separator characters in a single-value field, the way I've implemented it now is that it only supports the semicolon ; by default, and if people insist on using other characters like /, they're able to specify them.

  • Parsing complex join phrases in single-value fields ("feat", "with", "meets", "und", "mit", "et", "y") is a minefield, I'm not going there. This is the point where you just have to tell people to (re)tag using one of the above three methods.

@pjadeslandes
Copy link

I was only thinking of these delimiters as optional characters, I'm aware something like "&" won't work for everyone but I know it would work for me. I'm all for using tags such as ARTISTS, although I use mp3Tag and I don't see it there so I guess I'd have to move apps, which won't kill me! As ever, I'm impressed by how engaged everyone here is and am very appreciative of the work done by @certuna and all other contributors.

@jmbannon
Copy link

@pjadeslandes I think it's under extended tags

@certuna
Copy link
Contributor

certuna commented Jul 3, 2023

BTW I'm just discovering that Musicbrainz Picard by default writes ARTIST (single) + ARTISTS (multi), but not like you'd expect ALBUMARTIST + ALBUMARTISTS - it just drops any additional album artists and writes ALBUMARTIST as a single field. But then Picard does write multiple artist IDs to the MBZ Release Artist ID field...so as usual with non-standard stuff, sloppy implementations everywhere.

@jmbannon
Copy link

jmbannon commented Jul 3, 2023

They have it but you have to enable it manually. See the bottom of https://kodi.wiki/view/Music_tagging

@certuna
Copy link
Contributor

certuna commented Jul 3, 2023

Yeah I saw that - I've had that for testing, but it's a bit annoying for widespread adoption that it's not on by default.

@certuna
Copy link
Contributor

certuna commented Jul 6, 2023

The Navidrome fork I'm using for testing is now open and available for all to try, if you're interested: https://github.com/certuna/navidrome/tree/multi-artists . Still doing more testing before I submit the PR to the main Navidrome repo, but so far I see no showstoppers. Scanning speed appears to be unchanged on my 160k song library.

Four new server options (default):

  • OnlyAlbumArtists (true): when clicking on the Artists section in the left-side nav bar, either show a list of only the artists that have an album, or a list of all artists including those with only V/A compilation appearances.
  • Scanner.MultipleArtists (true): if set to false, ND will only use the first track/album artist, like now
  • Scanner.ArtistSeparators (";"): self explanatory - list of custom characters to split artists on, exactly like with the existing Scanner.GenreSeparators option.
  • Scanner.RemixerToArtist (true): adds the Remixer to the list of track artists, like Spotify, Tidal and Deezer do. Of course, for this to work, you need to have the Remixer tag (TPE4 in id3) properly tagged.

@Cassian-Andor
Copy link

@certuna Do you trim the resulting array so that Artist1 ; Artist 2 works the same as Artist1; Artist2?

@jmbannon
Copy link

jmbannon commented Sep 1, 2023

@certuna plz add id3v2.4 multi support for a separator type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.