From ccbc9cf859450d4164cc88c2d668f42c9a736bf6 Mon Sep 17 00:00:00 2001 From: Josh Patra Date: Mon, 2 Feb 2026 14:35:53 -0500 Subject: [PATCH] multiple artists big fix! --- allstarr/Models/Domain/Song.cs | 5 ++ .../Jellyfin/JellyfinResponseBuilder.cs | 4 +- .../SquidWTF/SquidWTFMetadataService.cs | 77 ++++++++++++++----- 3 files changed, 64 insertions(+), 22 deletions(-) diff --git a/allstarr/Models/Domain/Song.cs b/allstarr/Models/Domain/Song.cs index 87e5925..f9abe4b 100644 --- a/allstarr/Models/Domain/Song.cs +++ b/allstarr/Models/Domain/Song.cs @@ -14,6 +14,11 @@ public class Song public string Title { get; set; } = string.Empty; public string Artist { get; set; } = string.Empty; public string? ArtistId { get; set; } + + /// + /// All artists for this track (main + featured). For display in Jellyfin clients. + /// + public List Artists { 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/Jellyfin/JellyfinResponseBuilder.cs b/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs index dd4dcea..a030e5d 100644 --- a/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs +++ b/allstarr/Services/Jellyfin/JellyfinResponseBuilder.cs @@ -186,7 +186,7 @@ public class JellyfinResponseBuilder ["Type"] = "Audio", ["Album"] = song.Album, ["AlbumArtist"] = song.Artist, - ["Artists"] = new[] { song.Artist }, + ["Artists"] = song.Artists.Count > 0 ? song.Artists.ToArray() : new[] { song.Artist }, ["RunTimeTicks"] = (song.Duration ?? 0) * TimeSpan.TicksPerSecond, ["ImageTags"] = new Dictionary { @@ -242,7 +242,7 @@ public class JellyfinResponseBuilder ["Album"] = song.Album, ["AlbumId"] = song.AlbumId ?? song.Id, ["AlbumArtist"] = song.AlbumArtist ?? song.Artist, - ["Artists"] = new[] { song.Artist }, + ["Artists"] = song.Artists.Count > 0 ? song.Artists.ToArray() : new[] { song.Artist }, ["ArtistItems"] = new[] { new Dictionary diff --git a/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs b/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs index 32aaa7e..8daf9f9 100644 --- a/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs +++ b/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs @@ -551,26 +551,36 @@ public class SquidWTFMetadataService : IMusicMetadataService ? volNum.GetInt32() : null; - // Get artist name - handle both single artist and artists array + // Get all artists - Tidal provides both "artist" (singular) and "artists" (plural array) + var allArtists = new List(); string artistName = ""; - if (track.TryGetProperty("artist", out var artist)) + string? artistId = null; + + // Prefer the "artists" array as it includes all collaborators + if (track.TryGetProperty("artists", out var artists) && artists.GetArrayLength() > 0) + { + foreach (var artistEl in artists.EnumerateArray()) + { + var name = artistEl.GetProperty("name").GetString(); + if (!string.IsNullOrEmpty(name)) + { + allArtists.Add(name); + } + } + + // First artist is the main artist + if (allArtists.Count > 0) + { + artistName = allArtists[0]; + artistId = $"ext-squidwtf-artist-{artists[0].GetProperty("id").GetInt64()}"; + } + } + // Fallback to singular "artist" field + else if (track.TryGetProperty("artist", out var artist)) { artistName = artist.GetProperty("name").GetString() ?? ""; - } - else if (track.TryGetProperty("artists", out var artists) && artists.GetArrayLength() > 0) - { - artistName = artists[0].GetProperty("name").GetString() ?? ""; - } - - // Get artist ID - string? artistId = null; - if (track.TryGetProperty("artist", out var artistForId)) - { - artistId = $"ext-squidwtf-artist-{artistForId.GetProperty("id").GetInt64()}"; - } - else if (track.TryGetProperty("artists", out var artistsForId) && artistsForId.GetArrayLength() > 0) - { - artistId = $"ext-squidwtf-artist-{artistsForId[0].GetProperty("id").GetInt64()}"; + artistId = $"ext-squidwtf-artist-{artist.GetProperty("id").GetInt64()}"; + allArtists.Add(artistName); } // Get album info @@ -596,6 +606,7 @@ public class SquidWTFMetadataService : IMusicMetadataService Title = track.GetProperty("title").GetString() ?? "", Artist = artistName, ArtistId = artistId, + Artists = allArtists, Album = albumTitle, AlbumId = albumId, Duration = track.TryGetProperty("duration", out var duration) @@ -649,9 +660,34 @@ public class SquidWTFMetadataService : IMusicMetadataService } } - // Get artist info - string artistName = track.GetProperty("artist").GetProperty("name").GetString() ?? ""; - long artistIdNum = track.GetProperty("artist").GetProperty("id").GetInt64(); + // Get all artists - prefer "artists" array for collaborations + var allArtists = new List(); + string artistName = ""; + long artistIdNum = 0; + + if (track.TryGetProperty("artists", out var artists) && artists.GetArrayLength() > 0) + { + foreach (var artistEl in artists.EnumerateArray()) + { + var name = artistEl.GetProperty("name").GetString(); + if (!string.IsNullOrEmpty(name)) + { + allArtists.Add(name); + } + } + + if (allArtists.Count > 0) + { + artistName = allArtists[0]; + artistIdNum = artists[0].GetProperty("id").GetInt64(); + } + } + else if (track.TryGetProperty("artist", out var artist)) + { + artistName = artist.GetProperty("name").GetString() ?? ""; + artistIdNum = artist.GetProperty("id").GetInt64(); + allArtists.Add(artistName); + } // Album artist - same as main artist for Tidal tracks string? albumArtist = artistName; @@ -685,6 +721,7 @@ public class SquidWTFMetadataService : IMusicMetadataService Title = track.GetProperty("title").GetString() ?? "", Artist = artistName, ArtistId = $"ext-squidwtf-artist-{artistIdNum}", + Artists = allArtists, Album = albumTitle, AlbumId = $"ext-squidwtf-album-{albumIdNum}", AlbumArtist = albumArtist,