diff --git a/allstarr/Models/Domain/Song.cs b/allstarr/Models/Domain/Song.cs index c61202e..0b244e5 100644 --- a/allstarr/Models/Domain/Song.cs +++ b/allstarr/Models/Domain/Song.cs @@ -19,6 +19,12 @@ public class Song /// All artists for this track (main + featured). For display in Jellyfin clients. /// public List Artists { get; set; } = new(); + + /// + /// All artist IDs corresponding to the Artists list. Index-matched with Artists. + /// + public List ArtistIds { get; set; } = new(); + public string Album { get; set; } = string.Empty; public string? AlbumId { get; set; } public int? Duration { get; set; } // In seconds diff --git a/allstarr/Services/Deezer/DeezerMetadataService.cs b/allstarr/Services/Deezer/DeezerMetadataService.cs index ae5aa3e..434b6b5 100644 --- a/allstarr/Services/Deezer/DeezerMetadataService.cs +++ b/allstarr/Services/Deezer/DeezerMetadataService.cs @@ -384,17 +384,23 @@ public class DeezerMetadataService : IMusicMetadataService } } - // Contributors + // Contributors (all artists including features) var contributors = new List(); + var contributorIds = new List(); if (track.TryGetProperty("contributors", out var contribs)) { foreach (var contrib in contribs.EnumerateArray()) { - if (contrib.TryGetProperty("name", out var contribName)) + if (contrib.TryGetProperty("name", out var contribName) && + contrib.TryGetProperty("id", out var contribId)) { var name = contribName.GetString(); + var id = contribId.GetInt64(); if (!string.IsNullOrEmpty(name)) + { contributors.Add(name); + contributorIds.Add($"ext-deezer-artist-{id}"); + } } } } @@ -437,6 +443,8 @@ public class DeezerMetadataService : IMusicMetadataService ArtistId = track.TryGetProperty("artist", out var artistForId) ? $"ext-deezer-artist-{artistForId.GetProperty("id").GetInt64()}" : null, + Artists = contributors.Count > 0 ? contributors : new List(), + ArtistIds = contributorIds.Count > 0 ? contributorIds : new List(), Album = track.TryGetProperty("album", out var album) ? album.GetProperty("title").GetString() ?? "" : "", diff --git a/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs b/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs index ce47e91..a621469 100644 --- a/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs +++ b/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs @@ -299,13 +299,11 @@ public class JellyfinResponseBuilder ["ItemId"] = song.Id }, ["Artists"] = artistNames.Count > 0 ? artistNames.ToArray() : new[] { artistName ?? "" }, - ["ArtistItems"] = artistNames.Count > 0 + ["ArtistItems"] = artistNames.Count > 0 && song.ArtistIds.Count == artistNames.Count ? artistNames.Select((name, index) => new Dictionary { ["Name"] = name, - ["Id"] = index == 0 && song.ArtistId != null - ? song.ArtistId - : $"{song.Id}-artist-{index}" + ["Id"] = song.ArtistIds[index] }).ToArray() : new[] { diff --git a/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs b/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs index b14c6bf..6dae3f8 100644 --- a/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs +++ b/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs @@ -595,6 +595,7 @@ public class SquidWTFMetadataService : IMusicMetadataService // Get all artists - Tidal provides both "artist" (singular) and "artists" (plural array) var allArtists = new List(); + var allArtistIds = new List(); string artistName = ""; string? artistId = null; @@ -604,9 +605,11 @@ public class SquidWTFMetadataService : IMusicMetadataService foreach (var artistEl in artists.EnumerateArray()) { var name = artistEl.GetProperty("name").GetString(); + var id = artistEl.GetProperty("id").GetInt64(); if (!string.IsNullOrEmpty(name)) { allArtists.Add(name); + allArtistIds.Add($"ext-squidwtf-artist-{id}"); } } @@ -614,7 +617,7 @@ public class SquidWTFMetadataService : IMusicMetadataService if (allArtists.Count > 0) { artistName = allArtists[0]; - artistId = $"ext-squidwtf-artist-{artists[0].GetProperty("id").GetInt64()}"; + artistId = allArtistIds[0]; } } // Fallback to singular "artist" field @@ -623,6 +626,7 @@ public class SquidWTFMetadataService : IMusicMetadataService artistName = artist.GetProperty("name").GetString() ?? ""; artistId = $"ext-squidwtf-artist-{artist.GetProperty("id").GetInt64()}"; allArtists.Add(artistName); + allArtistIds.Add(artistId); } // Get album info @@ -649,6 +653,7 @@ public class SquidWTFMetadataService : IMusicMetadataService Artist = artistName, ArtistId = artistId, Artists = allArtists, + ArtistIds = allArtistIds, Album = albumTitle, AlbumId = albumId, Duration = track.TryGetProperty("duration", out var duration) @@ -711,6 +716,7 @@ public class SquidWTFMetadataService : IMusicMetadataService // Get all artists - prefer "artists" array for collaborations var allArtists = new List(); + var allArtistIds = new List(); string artistName = ""; long artistIdNum = 0; @@ -719,9 +725,11 @@ public class SquidWTFMetadataService : IMusicMetadataService foreach (var artistEl in artists.EnumerateArray()) { var name = artistEl.GetProperty("name").GetString(); + var id = artistEl.GetProperty("id").GetInt64(); if (!string.IsNullOrEmpty(name)) { allArtists.Add(name); + allArtistIds.Add($"ext-squidwtf-artist-{id}"); } } @@ -736,6 +744,7 @@ public class SquidWTFMetadataService : IMusicMetadataService artistName = artist.GetProperty("name").GetString() ?? ""; artistIdNum = artist.GetProperty("id").GetInt64(); allArtists.Add(artistName); + allArtistIds.Add($"ext-squidwtf-artist-{artistIdNum}"); } // Album artist - same as main artist for Tidal tracks @@ -771,6 +780,7 @@ public class SquidWTFMetadataService : IMusicMetadataService Artist = artistName, ArtistId = $"ext-squidwtf-artist-{artistIdNum}", Artists = allArtists, + ArtistIds = allArtistIds, Album = albumTitle, AlbumId = $"ext-squidwtf-album-{albumIdNum}", AlbumArtist = albumArtist,