From 48a13fbccb1f0ed4ddf046b1cbfbeb0f0451ca5d Mon Sep 17 00:00:00 2001 From: Honey Date: Sat, 25 Jul 2026 00:02:35 +0200 Subject: [PATCH] fix(backend): album_artist from iTunes collectionArtistName, not the lead single's artist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The album download tagged album_artist with the request's `artist`, which can be a single track's performer — the lead single "TAKEDOWN" is by TWICE, so a whole KPop-Demon-Hunters soundtrack got album_artist=TWICE on every track. Derive the album artist from the iTunes tracks' collectionArtistName (the album-level artist, identical across the album) and fall back to the request artist only if iTunes omits it. This is the documented intent (mainArtist = collectionArtistName when available) and keeps album_artist consistent so Navidrome doesn't split the album. Co-Authored-By: Claude Opus 4.8 --- backend/novasonic-server.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/novasonic-server.js b/backend/novasonic-server.js index 6ea8c28..f2216c4 100644 --- a/backend/novasonic-server.js +++ b/backend/novasonic-server.js @@ -623,7 +623,13 @@ app.post('/api/download', async (req, res) => { if (!tracks.length) { throw new Error(`Keine einzelnen Tracks für "${album || title}" gefunden. Bitte über iTunes Global-Suche herunterladen.`); } - const { done: dlDone, skipped: dlSkipped } = await downloadAlbumTracks({ jobId, artist, albumTitle: album || title, tracks, artworkUrl }); + // Album artist: prefer iTunes' album-level collectionArtistName (identical across every track) + // over the request's `artist`, which can be a single track's performer — e.g. the lead single + // "TAKEDOWN" is by TWICE, so `artist` arrives as "TWICE" and would tag the whole soundtrack's + // album_artist as TWICE. Keeps album_artist consistent so Navidrome doesn't split the album. + const albumArtistName = tracks.map(t => t.collectionArtistName).find(Boolean) || artist; + if (albumArtistName !== artist) log(jobId, `👥 Album-Künstler: "${albumArtistName}" (iTunes)`); + const { done: dlDone, skipped: dlSkipped } = await downloadAlbumTracks({ jobId, artist: albumArtistName, albumTitle: album || title, tracks, artworkUrl }); const allSkipped = dlSkipped === tracks.length; const someSkipped = dlSkipped > 0 && !allSkipped; const msg = allSkipped