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

Import all artists found in tracks, and make them browseable/searchable/filterable #211

Open
4 tasks
deluan opened this issue Apr 24, 2020 · 28 comments
Open
4 tasks

Comments

@deluan
Copy link
Member

deluan commented Apr 24, 2020

Currently Navidrome only add AlbumArtists to the Artist table. It should collect all artists from the imported tags.

  • Add all artist-related fields (track artists, composer, lyricist, producer?, performer?, mixer?, engineer?) to the artists table when importing a track
  • Enable filter artists by "only compilation appearances, no composer credits, etc" in the artists list view
  • Add option (per user?) to enable exposing all artists in the Subsonic API, as it does not support this kind of filtering
  • Allow clicking on track artist to go to the artist page

Ref: #94 (comment)

@Nelyah
Copy link
Contributor

Nelyah commented May 1, 2020

Thanks for the beautiful work you've done already on Navidrome!

I just wanted to add maybe to this issue that such artist-related tags (especially composer) was essential to efficiently use the Navidrome for classical music. It would be amazing to see this land!

@deluan
Copy link
Member Author

deluan commented May 9, 2020

Hey @Nelyah (and @certuna), how do you see all these "artist" fields being exposed through the Subsonic API? Would they appear as individual artists, and when you select ex: an artist that is only a composer, the API would return all album/songs where they worked on?

If we enable this, remember that the API only have provision for one "artist", so which one should we return in the API in the case of a song/album having multiple "artists" tags/fields available?

@certuna
Copy link
Contributor

certuna commented May 11, 2020

Yes this is where the limitations of the Subsonic API hit hard. I think it's impossible to expose this in a meaningful way to Subsonic clients. Even restricting it to Artist is suboptimal since the API can't even handle multiple artists per track.

This functionality might have to be limited to the WebUI or other API's, unfortunately. This is the point where navidrome becomes way more powerful than Subsonic.

@MichaelBechHansen
Copy link

As a client app developer (play:Sub, iOS), I would really like to this exposed in the API in some way.
Preferably the least hackish way of course :)

I'm going to spitball a bunch of thoughts here and see if any of them catches on...

Add metadata to album and tracks in API

Adding composer, conductor, remixer and so on as custom metadata properties to albums and songs in the API would go a long way.
With the data available, much functionality can be built in client apps from just this.
Taking album information as an example:

"subsonic-response": {
  "status": "ok", 
    "album": {
        "name": "Album Name", 
        "artist": "Artist Name", 
        "artistId": "0", 
        "x-composer": "COMPOSER NAME", 
        "x-conductor": "CONDUCTOR NAME", 

Enhanced artist list

This is an interpretation of what's being proposed.
Use the artists list to contain "synthetic" artists for composer, conductor etc.
I propose two things here:

  1. Change the name of the synthetic artists to contain the role, i.e. "Artist Name (Conductor)"
  2. Add a custom property to indicate the role, i.e. "x-artist-role" : "conductor".

Example (trimmed for brevity):

"subsonic-response": {
    "status": "ok", 
    "artists": {
        "index": [
        {
            "name": "A", 
            "artist": [
            {
                "name": "Artist Name",
                "x-artist-role" : "original-artist"
            }, 
            {
                "name": "Artist Name (Composer)",
                "x-artist-role" : "composer"
            }, 

The modified name-properties would be picked up by all existing client apps, and the x-artist-role property would allow client apps to build special support if needed/wanted.
The would of course have options to control whether the synthesised artists should be emitted at all.
(One caveat with the modified artist names would be localisation of course)

@certuna
Copy link
Contributor

certuna commented May 13, 2020

In the current documentation of the subsonic API I can't see provisions for custom fields, so you'd basically fork/extend the subsonic API away from its current 1.16.1, and (presumably) merge any changes that subsonic makes back into it. So it's hacky any way you spin it I guess :)

I like the Artist Name (Composer) solution. If you change the order around to Composer: Artist Name, you would also in any existing client app automatically have an alphabetic list of Composers embedded in the Artist list (albeit in the middle under "C").

It could also be a way to get around subsonics "no multiple values per field" limitation (ie, "x-artist-role": "original-artist-2")

A completely different way to support richer metadata than subsonic allows, is to push the entire metadata database to the client app, or allow the client to pull it (after auth of course). Either as a single big csv table (since presumably the client app will just import/map it to its own internal db) or as a straight copy of the relational navidrome db.

This is how iOS app Prism works with Plex, and it has allowed the developer to a) vastly speed up search/smart playlists/etc (since it's all local) and b) implement things that the database holds but the API doesn't cater for yet. Downside is that when the db changes serverside, the clients need some way to find out about it. Prism basically just seems to do 'dumb' periodic checks/manual refreshes. Pushing back changes (playcounts etc) can then still be done over the API.

@MichaelBechHansen
Copy link

Agreed - this would be an extension of the Subsonic API.
I think navidrome already sends a few custom properties, "serverVersion" and "version":

{
    "subsonic-response": {
        "status": "ok", 
        "serverVersion": "master (9235ab6)", 
        "version": "1.8.0", 
        "type": "navidrome", 
        "license": {
            "valid": true
        }
    }
}

At least "type" is kind of defacto standard across many server-variants.

On this topic:
I actually see the custom properties as less hacky than the use of "(Composer)" in the artist names.
Also I think providing a completely different mechanism for getting the metadata out to clients will be less likely to be adopted by apps and other server-variants.

Dumping the relational navidrome db to client apps will probably not fly with general purpose Subsonic client apps, and maybe even have it's own world of pain with versioning of the db schema and whatnot.
It could probably work OK for a dedicated Navidrome app.

@certuna
Copy link
Contributor

certuna commented May 13, 2020

Agreed, custom properties are the least hacky. From a client point of view, how would you ideally receive multiple values per field (multiple artists, composers or genres for 1 song), something like:

    "album": {
        "name": "Album Name", 
        "artist": "First Artist",                 <---existing apps use only this one
        "artistId": "0", 
        "x-artist2": "Second Artist", 
        "x-artist2Id": "1", 

Or with a custom property that can hold multiple values:

    "album": {
        "name": "Album Name", 
        "artist": "First Artist & Second Artist",           <---navidrome concatenates the multiple values in its db to a single string, existing apps use this one
        "artistId": "0", 
        "x-artist": "First Artist<null>Second Artist",     <---null separated list, like in id3v2.4
        "x-artistId": "0<null>1", 

Or can you just send do multiple "x-artist" elements in the xml (xs:list)?

@MichaelBechHansen
Copy link

I think a null-separated list would take most clients by surprise, and not in a good way :D

As for multiple values per field, I guess there can be multiple values for all the composer, conductor, etc fields, yes?

Personally I would prefer some kind of list structure over the x-artistN scheme. Seems more explicit about intent.
Maybe like this:

"x-artist": [ 
    { 
        "name" : "First Artist", 
        "id" : "0" 
    }, { 
        "name" : "Second Artist", 
        "id" : "1" 
    }
]

@deluan
Copy link
Member Author

deluan commented May 14, 2020

My concern with extending the API with the x- fields, is diverging too much from the original one and becoming a Unicorn, forcing client implementations to cater for these differences. Imagine if every server dev decides to implement this feature in a slightly different way? Then client development would be really hard....

I'm not saying I'm not gonna implement or evaluate a PR with this approach, but I'd like to have consensus from other server/client developers.

What I really wanted to do re: Subsonic API is start a new API, version 2 if you will, that would tackle the current limitations of the API:

  • It would be RESTful, allowing simpler client/server implementations
  • Better authentication (the current ones, token based and clear password, suck big time!)
  • Independent from any implementation project. The API would be a project itself, maintained by a community of client and server devs. Any dev could propose extensions to it, that could be voted and incorporated to the common spec

I have more ideas for it, but I'm not sure this is the right place to document this.

@MichaelBechHansen / @certuna Feel free to join our current discussions about this and other dev topics in our Discord server

@certuna
Copy link
Contributor

certuna commented May 15, 2020

Do you know what the Subsonic developers think of this? If you can get them on board it would benefit everyone, and prevent clients for having to support/choose between two API's.

@MichaelBechHansen
Copy link

I don't know.

There has been pretty much total radio silence from Sindre Mehus for some years.
I suggested additional metadata enhancements to the Subsonic API in the Subsonic app developers group a couple of years ago, and got no response:
https://groups.google.com/forum/#!topic/subsonic-app-developers/QJ_b4qSoKJo
https://groups.google.com/forum/#!topic/subsonic-app-developers/1YJZIz3i1VI

But I think it's worth a try to reach out and probe the interest.

@certuna
Copy link
Contributor

certuna commented May 15, 2020

The airsonic folks appear to have some thoughts in the same direction, as has the LMS developer.

@certuna
Copy link
Contributor

certuna commented Apr 28, 2021

Put up an issue at the Sonic Extensions API project to enable multi-valued artist/genre: https://gitlab.com/sonic-extensions-api/specification/-/issues/3

Is this initiative dormant/dead?

@deluan
Copy link
Member Author

deluan commented Apr 28, 2021

I think it is dormant.... not dead. From my side, I'd like to get to implement these changes in the DB first, I don't have much to add until I actually see what the implementation will require (I also don't have much free time to delve into that ATM)

@github-actions
Copy link

github-actions bot commented Mar 7, 2023

This issue has been automatically marked as stale because it has not had recent activity. The resources of the Navidrome team are limited, and so we are asking for your help.
If this is a bug and you can still reproduce this error on the master branch, please reply with all of the information you have about it in order to keep the issue open.
If this is a feature request, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.

@github-actions github-actions bot added the stale label Mar 7, 2023
@certuna
Copy link
Contributor

certuna commented Mar 13, 2023

Still relevant and valueble!

@github-actions github-actions bot removed the stale label Mar 14, 2023
@Xarishark
Copy link

Any news on this feature? You have it on the official page for 3 years now.

@certuna
Copy link
Contributor

certuna commented May 17, 2023

Any news on this feature? You have it on the official page for 3 years now.

I'm now working on and testing an experimental build where all artist tags are added to the search keywords, so they will show up in search. Composer/Conductor/Lyricist/RemixerProducer/etc, plus any additional Artists & Album Artist when those tags contain more than one value.

This means: when you type "beethoven" in search, all songs that have "Ludwig von Beethoven" in the Composer tag will show up - even if the UI can't display composer credits yet.

This is not a "full" implementation, where we'd have a nice list of all the involved people with full credits in the UI, or all credits nicely sorted under the artist Discogs-style, but it's relatively easy to add. If it all works well I'll submit a PR so we can test it, maybe in one of the next versions.

@Xarishark
Copy link

Will multiple artists display correctly on the player? Like on streaming services that each artists is clickable on the player and not 2 artists stuck together with their delimiter? Right now Navidrome only shows the first artist right?

@certuna
Copy link
Contributor

certuna commented May 17, 2023

Unfortunately not - for this, the database and API have to be refactored, and that's a much more complex job. You'd have to ask @deluan about this. This is what was done with Genre a while ago, albums and songs can now have multiple genres in Navidrome. But artists/credits is a trickier design since there's three relations: a song/album can have multiple artists, but also multiple credits (Artist, Composer, Producer, etc).

Indeed Navidrome only shows the first artist, and either discards the other artists (in the case of 'correct' multi-valued tags) or doesn't split them (in the case of 'non-standard' semicolon or comma separated values). It behaves the same as Plex and Apple Music in this respect.

It is relatively easy to make Navidrome read multiple artists and display them all as one concatenated string, like "Jay-Z;Kanye West", but then the artists not individually clickable, this would then be a new artist separate from "Jay-Z" and "Kanye West", which is probably not the behaviour we want.

Bear in mind that the (current) Subsonic API does not support multiple artists at all - whatever we do internally in Navidrome, we cannot change that. All 3rd party clients have the same limitations, unfortunately.

@certuna
Copy link
Contributor

certuna commented Jun 27, 2023

Here's the roadmap for what I'm working on:

Goals that can be achieved without full M2M database/API refactoring of artists:

  • read multivalued artist tags, both with standard and custom separators, as well as in Picard-style ARTIST/ARTISTS form
  • make all track artists and album artists searchable
  • make the Artist detail view list all albums where said artist appears on: as album artist, as track artist, or as guest/remixer
  • make the first track artists and first album artists browseable/clickable/filterable
  • all of this in the Web UI, without breaking stuff in the Subsonic API

Milestones reached in my experimental Navidrome fork, will be submitted as PRs in this order:

  • sort the artist's own albums before compilation/guest appearances
    Progress: done, PR submitted Improved sorting in Artist view #2413
  • have the refresher create records in the artists table for all artists, not only album artists:
    for track artists: model/mediafile.go -> ToArtist(), updates SongCount + Size
    for album artists model/album.go -> ToAlbumArtist() updates AlbumCount + Size
    This will make all track artists clickable in the UI, so no more tracklists/playlists where some track artists are clickable and some are not.
    Default behaviour will be unchanged: when the user clicks on the Artists section in the nav bar or queries an "all artists" list through Subsonic API, it only shows a list of Album Artists (AlbumCount >= 1) by default
    Provide a server option to show all artists with OnlyAlbumArtists = true/false
    Progress: done, now testing
  • read multivalued track artists and album artists tags, see Support multiple artists, with custom separator #238
    Store concatenated strings in artistName and albumArtistName ("Jay-Z · Kanye West") for display purposes and allArtistIDs ("0e37575446e8659caa9f2a3e298afc86 0b48849166b97b6b053a0e1e5e131231") for filtering purposes
    But keep artistID and albumArtistID single-valued ("0e37575446e8659caa9f2a3e298afc86") to maintain 1NF for the other exisiting queries. I.e., all artists are searchable, but only the first artist of an album/song is clickable
    Fix last.fm and listenbrainz scrobbling so that only "Jay-Z" is used in the query, not the concatenated string "Jay-Z · Kanye West" - this fixes the existing issues with joined artists as well
    Progress: done, now testing
  • Optionally add Remixer to the concatenated Artist Name, Spotify-style
    Using a server option Scanner.RemixerToArtist = true/false
    Progress: done, now testing
  • Web UI: since only the first artist of ("Jay-Z · Kanye West") is clickable, fix the code to make the hyperlinks appear under the first artist only and not the whole concatenated string
    Progress: to be done
  • Web UI: make the Artists section in the nav bar collapse like the Albums section above it, and have two items "All Artists" + "Album Artists". Making the Artists section a collapsible menu will allow for later expansion with sections like "Composer".
    This would make the OnlyAlbumArtists option not needed anymore, btw.
    Progress: to be done - maybe wait until after the migration to RAv4?
  • add the ArtistNames + ArtistIDs from other tags like Conductor, Composer, Lyricist etc to the all_artist_ids + full_text fields, so they can be searchable, and appear up on the artist page
    Progress: to be done

Goals that (probably) can only be achieved after a database refactoring & API rework:

  • make all track artists and album artists browseable/clickable/filterable
  • full support of artists + roles like Conductor, Composer, Remixer, etc.

Goals that can only be achieved after database/API rework AND the migration to React Admin v4:

  • Artist view with segmented sections like "Guest appearances", "tracks on V/A Compilations" or "Remixes"

@audiomuze
Copy link

Why not implement something like SlimProto and abandon AirSonic. It’s not fit for purpose for a modern music server, and frankly it serves only to hold Navidrome back.

@deluan
Copy link
Member Author

deluan commented Nov 20, 2023

Why not implement something like SlimProto and abandon AirSonic. It’s not fit for purpose for a modern music server, and frankly it serves only to hold Navidrome back.

One word: clients!

The idea of implementing the Subsonic API was to leverage the already existing ecosystem of clients, without having to spend lots of time writing at least one good client for each platform. At the time the project started, Subsonic was the most healthy ecosystem. And I would argue it still is as of today.

This does not prevent Navidrome to have other API implementations working in parallel. In fact, it already have two APIs: Subsonic and the Native one, used by the WebUI, Feichin and Thunderdrome.

AFAIU, SlimProto is a dying protocol, but I can be proved wrong and if anyone is interested in implementing it, I can support that. Or the Jellyfin API, or any other API for that matter.

Just keep in mind that the Subsonic API is evolving, with the OpenSubsonic initiative, and one of the new features is Multiple Artists. This has not been implemented yet due to limitations in Navidrome itself, not the API. But supporting it is in the roadmap and should be one of the next features.

@audiomuze
Copy link

audiomuze commented Nov 20, 2023

I’d disagree re SlimProto being a dying protocol. It’s decades old and has been able to support playback of virtually all audio types to an endpoint which feeds into a DAC. It’s been implemented in Squeezelite which makes virtually any PC or SOC a viable endpoint for streaming to a DAC. Navidrome’s protocol support means you can’t easily get lossless tunes to a Hi-Fi. Great for on the road playback via a mobile device or sitting at a desktop, but a non-starter for any Hi-Fi based listening.

you should install Logitechmediaserver with its Material skin plugin to see how it’s developed. It’s decades old yet eons ahead of any Navidrome server / subsonic client config in terms of leveraging metadata to find and explore and play music. Subsonic is what holds Navidrome back in this area.

@Tolriq
Copy link

Tolriq commented Nov 21, 2023

Read about OpenSubsonic and test Symfonium then you'll probably revise your thinking.
The missing metadata is being added to the protocol, Top clients are already supporting them and more will come.
A lot more than apps supporting slimproto that is not well designed for many things and is only supported by one server ...

@audiomuze
Copy link

audiomuze commented Nov 21, 2023

SlimProto is designed to get an audio stream to a DAC seamlessly, and it does that with aplomb, supporting multi-room playback and synchronisation streaming to multiple endpoints. That LMS still enjoys a large user base decades after initial release is in itself quite telling. If it were added to Navidrome it’d suddenly open up a whole new community of users that use hi-fi to listen to music as opposed to sitting in front of a pc or using a phone with iem’s.

With OpenSubsonic you’re all hailing the ability to pass multiple artists, in 2023! As a Navidrome user (when commuting) it’s clear the data model is pretty rudimentary and I’d posit that’s because it’s been a slave to a protocol that should have been put to pasture eons back. In any event, it’d be good to see opensubsonic modernise what’s possible to bring metadata rich browsing, exploration and capabilities to Navidrome.

@Tolriq
Copy link

Tolriq commented Nov 21, 2023

No with OpenSubsonic we hailing to finally have brought together tons of servers and client to build the future on a proper open base without breaking an existing working API to ensure success.
And yes it's only done in 2023 after countless hours of work from me to gather all of them and move forward.

SlimProto is made for the client part connected to the DAC not for the server to expose it's data for clients to consume ...
You even says it: "a viable endpoint for streaming to a DAC"...

Navidrome is not an endpoint it's a source point ;) So while you can add support for SlimProto for Navidrome webinterface to play to SlimProto clients, this is completely unrelated to the API and OpenSubsonic.

It would be a setting for the Jukebox API to play on SlimProto.

Copy link

This issue has been automatically marked as stale because it has not had recent activity. The resources of the Navidrome team are limited, and so we are asking for your help.
If this is a bug and you can still reproduce this error on the master branch, please reply with all of the information you have about it in order to keep the issue open.
If this is a feature request, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.

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

No branches or pull requests

7 participants