diff --git a/backend/lib/metadata.js b/backend/lib/metadata.js index 1b75840..038ce76 100644 --- a/backend/lib/metadata.js +++ b/backend/lib/metadata.js @@ -112,15 +112,14 @@ async function lookupItunesTrackMeta(artist, title) { ); const titleOnlyMatch = results => results.find(t => normalizeTitle(t.trackName) === normT); - // Strategy: JP strict → US strict → US title-only (never JP title-only to avoid - // false positives where JP returns a different Japanese song with the same English title) - const jpResults = await fetchItunes('jp'); + // Fetch both in parallel — JP for correct Japanese titles/artwork, US for English genre names + const [jpResults, usResults] = await Promise.all([fetchItunes('jp'), fetchItunes('us')]); let match = strictMatch(jpResults); - if (!match) { - const usResults = await fetchItunes('us'); - match = strictMatch(usResults) || titleOnlyMatch(usResults); - } + let usMatch = strictMatch(usResults) || titleOnlyMatch(usResults); + if (!match) match = usMatch; if (!match) return {}; + // JP genre names are localized (e.g. イージーリスニング); always prefer US genre + const genre = (usMatch || match).primaryGenreName; return { album: match.collectionName || '', year: match.releaseDate ? new Date(match.releaseDate).getFullYear() : undefined, @@ -128,7 +127,7 @@ async function lookupItunesTrackMeta(artist, title) { totalTracks: match.trackCount || undefined, discNum: match.discNumber || undefined, discTotal: match.discCount || undefined, - genre: match.primaryGenreName || undefined, + genre: genre || undefined, artworkUrl: (match.artworkUrl100 || '').replace('100x100bb', '1000x1000bb'), durationMs: match.trackTimeMillis || undefined, itunesArtistName: match.artistName || undefined,