aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-07-23 23:07:58 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-07-23 23:07:58 +0200
commitb7b270042512cfcdf0c3f435be0359ed361ba56c (patch)
tree62d8f197dcc06c56d9ced6580add0139830215e3
parent04e4505402b3f616fe9484f6bf0895ab68971176 (diff)
Fix MusicBrainz Metadata fetching
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzAlbumProvider.cs126
-rw-r--r--MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzArtistProvider.cs70
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;