add Release Type field
Every online metadata resource (discogs, RYM, musicbrainz, allmusic) has some form of Release Type field: Album, Single/EP, Live, Compilation, DJ Mix, Audiobook, etc. Sooner or later people are going to ask for this to be implemented (pretty much every forum/reddit for every music server/player has threads on this), so it's probably at least a good idea to prepare for it. Implement it well, and navidrome is ahead of pretty much everyone out there.
So we'd be looking at adding a Release Type field in:
- [ ] the navidrome DB structure
- [ ] the WebUI design (grouping by release type, like how for example RYM and Discogs display artist discographies)
- [ ] possible extensions to the subsonic API, to push this field to clients
For info: here's how Musicbrainz implements it in their DB: https://musicbrainz.org/doc/Release_Group/Type . MZB Picard writes these tags: RELEASETYPE (Vorbis/FLAC) and TXXX:MusicBrainz Album Type (custom tag in id3v2.4).
Update Jan 2023:
I am experimenting with an implementation of this now, I see a few ways to do Release Type:
- the easy/lazy way: how Plex does it. Read the Release Type tag, condense it down to one value. So "album;live" -> "Live". "single;live" -> "Singles/EPs". "album;compilation;soundtrack" -> "Soundtracks". Advantage: very easy to implement, only requires one extra field in the DB & API. Plex users are used to it. Disadvantage: no way to allow for releases with multiple types, for example if you filter/smart playlist for "live" it will exclude live singles, since those are stored only as "single".
- the slightly more elaborate way: store a boolean per defined MBZ Release Type:
typeAlbum= true/false,typeSingle= true/false,typeSoundtrack= true/false,typeAudiobook= true/false. Advantage: allows for multiple types. Disadvantage: 20+ new fields in the DB, and we would need to create a new Type column each time that MusicBrainz adds a new Type too (although, that doesn't seem happen too often) - a hybrid of the above: assign an album one release type from the MBZ list of types like "Album", "Single", "EP", "Soundtrack", "Demo", "Mixtape", "Audiobook", "Broadcast", "Interview" but also extract and store a few true/false attributes like "Live", "Compilation", "DJ Mix" and "Remix". Advantage: easy implementation, only four new fields needed in the DB and API, as one boolean (Compilation) already exists in ND.
- the hard way: like Genres, create a many-to-many DB structure with separate tables, JOINs etc. Advantage: allows for complete freedom to use custom release types, we don't have to stick to the MBZ-defined types. Disadvantage: complex implementation, possibly impacts performance
I've been thinking about this. I think it is a great addition, my only concern is what to do with albums that do not have this field, or whole libraries from users that don't care about this. Display a filter with empty fields is not a great UX....
Also, this field is multi-valued, usually a comma-separated list, but is basically a free form field. What would be the best way to normalize it?
"my only concern is what to do with albums that do not have this field, or whole libraries from users that don't care about this"
I would say, like it is currently used: every release is deemed an Album. So if you don't use this field, nothing changes. The DB just stores "Album".
"Also, this field is multi-valued, usually a comma-separated list"
Is it indeed a comma separated list, or a 'proper' multi value tag (i.e., multiple single-value RELEASETYPE Vorbis tags, null-separated id3v2.4 tag)?
Navidrome doesn't read the tags directly, it uses ffmpeg to extract them. In ffmpeg output, it seems to always be a comma-separated list. See examples below (all tagged with beets and matched against Discogs):
Example from a FLAC file:
Input #0, flac, from 'Don't Need A Gun/01-01 Don't Need A Gun (Melt Down Mix).flac':
Metadata:
ALBUM : Don't Need A Gun
ALBUM ARTIST : Billy Idol
album_artist : Billy Idol
MUSICBRAINZ_ALBUMTYPE: 12", 45 RPM, Single
MUSICBRAINZ_ALBUMID: 6294185
Example from a Ogg/Opus file:
Input #0, ogg, from 'Adamski/Killer/01-01 Killer (21st Century Version).opus':
Duration: 00:07:33.23, start: 0.007500, bitrate: 142 kb/s
Stream #0:0(eng): Audio: opus, 48000 Hz, stereo, fltp
Metadata:
ALBUM : Killer
ALBUM ARTIST : Adamski
album_artist : Adamski
MUSICBRAINZ_ALBUMTYPE: Promo, Single
MUSICBRAINZ_ALBUMID: 3108587
Example from a MP3 file:
Input #0, mp3, from 'Madonna/Celebration/01-01 Hung Up.mp3':
Metadata:
title : Hung Up
artist : Madonna
track : 1/18
album : Celebration
genre : House/Ballad/Dance-Pop/Pop Rap
compilation : 0
MusicBrainz Album Type: Compilation, Remastered
MusicBrainz Album Id: 1930797
Also note how MusicBrainz and Discogs diverge when adding things like "Deluxe Edition". One example of each:
From Discogs:
Input #0, flac, from 'The Velvet Underground/The Velvet Underground & Nico (45th Anniversary Super Deluxe Edition)/01-01 Sunday Morning.flac':
Metadata:
ALBUM : The Velvet Underground & Nico (45th Anniversary Super Deluxe Edition)
ALBUM ARTIST : The Velvet Underground
album_artist : The Velvet Underground
MUSICBRAINZ_ALBUMTYPE: Deluxe Edition, Limited Edition
MUSICBRAINZ_ALBUMID: 4002025
From MusicBrainz:
Input #0, flac, from 'U2/The Joshua Tree [Super Deluxe Edition]/01-01 Where the Streets Have No Name.flac':
Metadata:
ALBUM : The Joshua Tree [Super Deluxe Edition]
ALBUM ARTIST : U2
album_artist : U2
ALBUMARTIST_CREDIT: U2
ALBUMARTISTSORT : U2
MUSICBRAINZ_ALBUMCOMMENT: super deluxe, mastered for iTunes
MUSICBRAINZ_ALBUMSTATUS: Official
MUSICBRAINZ_ALBUMTYPE: album
MUSICBRAINZ_ALBUMID: 1003db0d-3e7f-46e7-a965-ebc093669c30
Should we merge the comma-separated list from ALBUMTYPE with the one from ALBUMCOMMENT? Or ignore the ALBUMCOMMENT, as it can potentially have information not regarding to the type itself?
Also, seems that the docs you pointed out are not strictly followed by MusicBrainz. Below is a compilation album, based on the docs it should have the release type as album, compilation as opposed to just compilation
Input #0, flac, from 'Mantronix/King of the Beats_ Anthology 1985โ1988/01-01 Bassline.flac':
Metadata:
ALBUM : King of the Beats: Anthology 1985โ1988
ALBUM ARTIST : Mantronix
album_artist : Mantronix
ALBUMARTIST_CREDIT: Mantronix
ALBUMARTISTSORT : Mantronix
MUSICBRAINZ_ALBUMSTATUS: Official
MUSICBRAINZ_ALBUMTYPE: compilation
MUSICBRAINZ_ALBUMID: d5fbb0fd-81a6-40d3-8f88-4b4315e4b7c2
@certuna Any more thoughts on this? Should we simply import the field and use a configurable field separator to break multi-valued values?
I think so yes.
Things like "Deluxe Edition", "Remastered" or "Limited Edition" are not really very useful (or from the user pov, expected) categories so maybe there needs to be a whitelist of accepted release types (I'm thinking Album, Compilation, Single, EP, Live, etc - basically the RYM/Discogs categories), and ignore the rest, either on import or in query when they're pulled out of the DB.
Basically, every choice you make is slightly arbitrary and messy, which is to be expected - as with all these things, if it was easy and straightforward to implement, everyone else (library managers/music players) would have already done it.
Edition details aren't usually added to that field (MUSICBRAINZ_ALBUMTYPE) on the default implementation of Musicbrainz Picard (or even their API). This is the whitelist of terms approved by MBZ, if you feel like having a look. MUSICBRAINZ_ALBUMCOMMENT is a non-standard but I don't see any issue with having that extra bit of data since a ton of people use beets. My suggestion would be to use the whitelist for filtering out the terms that would be used to determine the release type and move everything else to a different field (like MUSICBRAINZ_ALBUMCOMMENT) in the ND database, which can open up prospects of displaying them in the album view if the user wishes to.
I think we should join the terms from both fields, and have a configurable whitelist (default to the one provided by MusicBrainz). As this will be a relation between the album and the release_type tables, we could keep the original, untouched values in the media_file table and store the processed and filtered values in the relation table. Thoughts?
Yeah, that seems fine to me.
Regarding the storing of a large number of true/false flags, may I recommend bit fields ? I think solution 3 is probably the best compromise.
Yeah I thought about bit fields too but since DB are more or less 1:1 mapped into the native API, this would mean bringing the bit field also into the API, and that means the Web UI code would have to parse the bit field, which maybe isn't so nice for debugging/readability.
@deluan from our discussion on Discord, you still prefer a full M2M implementation with join tables etc for this?
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.
Still valid, probably has to be done after the move to React Admin v4.
Since OpenSubsonic now supports ReleaseTypes, this could be implemented for OpenSubsonic ahead of the UI redesign, if desired. (I am going to display the release type (normalized) in Supersonic on the album views soon, defaulting to "Album" if none available)
This is a multi-valued tag, so it is not just the UI, but also a change in the DB layout. I'm working on the new scanner (#2709) and I will add support for multi-valued tags as discussed briefly here. Mood, Publisher and ReleaseType will be the first ones to be handled this way.
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.
Should not be stale, since it's being actively worked on :)