fix(backend): album_artist from iTunes collectionArtistName, not the lead single's artist

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 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 4.8 committed 2026-07-25 00:02:35 +02:00
1 parent 4d44a476a5
commit 48a13fbccb
1 file changed
+7 -1
+7 -1
View File
@@ -623,7 +623,13 @@ app.post('/api/download', async (req, res) => {
if (!tracks.length) { if (!tracks.length) {
throw new Error(`Keine einzelnen Tracks für "${album || title}" gefunden. Bitte über iTunes Global-Suche herunterladen.`); 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 allSkipped = dlSkipped === tracks.length;
const someSkipped = dlSkipped > 0 && !allSkipped; const someSkipped = dlSkipped > 0 && !allSkipped;
const msg = allSkipped const msg = allSkipped