diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-23 23:07:58 +0200 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-07-23 23:07:58 +0200 |
| commit | b7b270042512cfcdf0c3f435be0359ed361ba56c (patch) | |
| tree | 62d8f197dcc06c56d9ced6580add0139830215e3 | |
| parent | 04e4505402b3f616fe9484f6bf0895ab68971176 (diff) | |
Fix MusicBrainz Metadata fetching
| -rw-r--r-- | MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs | 126 | ||||
| -rw-r--r-- | MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs | 70 |
2 files changed, 154 insertions, 42 deletions
diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs index 715bdd9da4..92e215fc70 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs @@ -155,7 +155,6 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu /// <inheritdoc /> public async Task<MetadataResult<MusicAlbum>> GetMetadata(AlbumInfo info, CancellationToken cancellationToken) { - // TODO: This sets essentially nothing. As-is, it's mostly useless. Make it actually pull metadata and use it. var query = MusicBrainz.Plugin.Instance!.MusicBrainzQuery; var releaseId = info.GetReleaseId(); var releaseGroupId = info.GetReleaseGroupId(); @@ -169,13 +168,8 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu if (string.IsNullOrWhiteSpace(releaseId) && !string.IsNullOrWhiteSpace(releaseGroupId)) { // TODO: Actually try to match the release. Simply taking the first result is stupid. - var releaseGroup = await query.LookupReleaseGroupAsync(new Guid(releaseGroupId), Include.None, null, cancellationToken).ConfigureAwait(false); - var release = releaseGroup.Releases?.Count > 0 ? releaseGroup.Releases[0] : null; - if (release is not null) - { - releaseId = release.Id.ToString(); - result.HasMetadata = true; - } + var releaseGroupLookup = await query.LookupReleaseGroupAsync(new Guid(releaseGroupId), Include.None, null, cancellationToken).ConfigureAwait(false); + releaseId = releaseGroupLookup.Releases?.Count > 0 ? releaseGroupLookup.Releases[0].Id.ToString() : null; } // If there is no release ID, lookup a release with the info we have @@ -205,43 +199,117 @@ public class MusicBrainzAlbumProvider : IRemoteMetadataProvider<MusicAlbum, Albu { releaseGroupId = releaseResult.ReleaseGroup.Id.ToString(); } - - result.HasMetadata = true; - result.Item.ProductionYear = releaseResult.Date?.Year; - result.Item.Overview = releaseResult.Annotation; } } - // If we have a release ID but not a release group ID, lookup the release group - if (!string.IsNullOrWhiteSpace(releaseId) && string.IsNullOrWhiteSpace(releaseGroupId)) + if (string.IsNullOrWhiteSpace(releaseId) && string.IsNullOrWhiteSpace(releaseGroupId)) { - var release = await query.LookupReleaseAsync(new Guid(releaseId), Include.ReleaseGroups, cancellationToken).ConfigureAwait(false); - releaseGroupId = release.ReleaseGroup?.Id.ToString(); - result.HasMetadata = true; + return result; } - // If we have a release ID and a release group ID - if (!string.IsNullOrWhiteSpace(releaseId) || !string.IsNullOrWhiteSpace(releaseGroupId)) + // Fetch the full release (and its release group) so we can populate everything MusicBrainz returns. + IRelease? release = null; + if (!string.IsNullOrWhiteSpace(releaseId)) { - result.HasMetadata = true; - } + release = await query.LookupReleaseAsync( + new Guid(releaseId), + Include.Artists | Include.ReleaseGroups | Include.Labels | Include.Genres | Include.Tags | Include.Annotation, + cancellationToken).ConfigureAwait(false); - if (result.HasMetadata) - { - if (!string.IsNullOrEmpty(releaseId)) + if (string.IsNullOrWhiteSpace(releaseGroupId) && release?.ReleaseGroup?.Id is not null) { - result.Item.SetProviderId(MetadataProvider.MusicBrainzAlbum, releaseId); + releaseGroupId = release.ReleaseGroup.Id.ToString(); } + } - if (!string.IsNullOrEmpty(releaseGroupId)) - { - result.Item.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, releaseGroupId); - } + IReleaseGroup? releaseGroup = null; + if (!string.IsNullOrWhiteSpace(releaseGroupId)) + { + releaseGroup = await query.LookupReleaseGroupAsync( + new Guid(releaseGroupId), + Include.Artists | Include.Genres | Include.Tags | Include.Annotation, + null, + cancellationToken).ConfigureAwait(false); } + result.HasMetadata = true; + + if (!string.IsNullOrEmpty(releaseId)) + { + result.Item.SetProviderId(MetadataProvider.MusicBrainzAlbum, releaseId); + } + + if (!string.IsNullOrEmpty(releaseGroupId)) + { + result.Item.SetProviderId(MetadataProvider.MusicBrainzReleaseGroup, releaseGroupId); + } + + Populate(result.Item, release, releaseGroup); + return result; } + private static void Populate(MusicAlbum item, IRelease? release, IReleaseGroup? releaseGroup) + { + // Prefer the release group (album-level) data, falling back to the specific release. + var overview = releaseGroup?.Annotation; + if (string.IsNullOrWhiteSpace(overview)) + { + overview = release?.Annotation; + } + + if (!string.IsNullOrWhiteSpace(overview)) + { + item.Overview = overview; + } + + // The release group's first release date is the original album date. + var date = releaseGroup?.FirstReleaseDate ?? release?.Date; + if (date is not null) + { + item.PremiereDate = date.NearestDate; + item.ProductionYear = date.Year; + } + + var artistCredit = release?.ArtistCredit ?? releaseGroup?.ArtistCredit; + if (artistCredit is not null && artistCredit.Count > 0) + { + item.AlbumArtists = artistCredit + .Select(credit => credit.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToArray(); + } + + var genres = releaseGroup?.Genres ?? release?.Genres; + if (genres is not null && genres.Count > 0) + { + item.Genres = genres + .OrderByDescending(genre => genre.VoteCount) + .Select(genre => genre.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToArray(); + } + + var tags = releaseGroup?.Tags ?? release?.Tags; + if (tags is not null && tags.Count > 0) + { + item.Tags = tags + .OrderByDescending(tag => tag.VoteCount) + .Select(tag => tag.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToArray(); + } + + if (release?.LabelInfo is not null && release.LabelInfo.Count > 0) + { + item.Studios = release.LabelInfo + .Where(labelInfo => !string.IsNullOrWhiteSpace(labelInfo.Label?.Name)) + .Select(labelInfo => labelInfo.Label!.Name!) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray(); + } + } + /// <inheritdoc /> public Task<HttpResponseMessage> GetImageResponse(string url, CancellationToken cancellationToken) { diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs index ea8984afb5..732a1ec242 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs @@ -101,28 +101,72 @@ public class MusicBrainzArtistProvider : IRemoteMetadataProvider<MusicArtist, Ar var musicBrainzId = info.GetMusicBrainzArtistId(); + // If we don't have an id yet, resolve one by name so we can look the artist up. if (string.IsNullOrWhiteSpace(musicBrainzId)) { var searchResults = await GetSearchResults(info, cancellationToken).ConfigureAwait(false); + musicBrainzId = searchResults.FirstOrDefault()?.GetProviderId(MetadataProvider.MusicBrainzArtist); + } - var singleResult = searchResults.FirstOrDefault(); + if (string.IsNullOrWhiteSpace(musicBrainzId)) + { + return result; + } - if (singleResult is not null) - { - musicBrainzId = singleResult.GetProviderId(MetadataProvider.MusicBrainzArtist); - result.Item.Overview = singleResult.Overview; + var query = Plugin.Instance!.MusicBrainzQuery; + var artist = await query.LookupArtistAsync(new Guid(musicBrainzId), Include.Annotation | Include.Genres | Include.Tags, null, null, cancellationToken).ConfigureAwait(false); - if (Plugin.Instance!.Configuration.ReplaceArtistName) - { - result.Item.Name = singleResult.Name; - } - } + if (artist is null) + { + return result; + } + + result.HasMetadata = true; + result.Item.SetProviderId(MetadataProvider.MusicBrainzArtist, artist.Id.ToString()); + + if (Plugin.Instance!.Configuration.ReplaceArtistName && !string.IsNullOrWhiteSpace(artist.Name)) + { + result.Item.Name = artist.Name; + } + + if (!string.IsNullOrWhiteSpace(artist.Annotation)) + { + result.Item.Overview = artist.Annotation; + } + + if (artist.LifeSpan?.Begin is not null) + { + result.Item.PremiereDate = artist.LifeSpan.Begin.NearestDate; + result.Item.ProductionYear = artist.LifeSpan.Begin.Year; + } + + if (artist.LifeSpan?.End is not null) + { + result.Item.EndDate = artist.LifeSpan.End.NearestDate; + } + + var location = string.IsNullOrWhiteSpace(artist.Area?.Name) ? artist.Country : artist.Area!.Name; + if (!string.IsNullOrWhiteSpace(location)) + { + result.Item.ProductionLocations = [location]; + } + + if (artist.Genres is not null && artist.Genres.Count > 0) + { + result.Item.Genres = artist.Genres + .OrderByDescending(genre => genre.VoteCount) + .Select(genre => genre.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToArray(); } - if (!string.IsNullOrWhiteSpace(musicBrainzId)) + if (artist.Tags is not null && artist.Tags.Count > 0) { - result.HasMetadata = true; - result.Item.SetProviderId(MetadataProvider.MusicBrainzArtist, musicBrainzId); + result.Item.Tags = artist.Tags + .OrderByDescending(tag => tag.VoteCount) + .Select(tag => tag.Name) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToArray(); } return result; |
