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,