fix: skip iTunes album/duration enrichment for Japanese Spotify tracks to prevent wrong-song downloads

This commit is contained in:
Honey committed 2026-05-27 15:15:45 +02:00
1 parent b5ffb1e73d
commit 8f14d013b3
1 file changed
+14 -5
+14 -5
View File
@@ -287,17 +287,26 @@ async function _loadSpotifyTrackArtwork(tracks, listEl) {
const results = await itunesSearch(`${t.trackName} ${firstArtist}`, 'musicTrack', 1); const results = await itunesSearch(`${t.trackName} ${firstArtist}`, 'musicTrack', 1);
const match = results[0]; const match = results[0];
if (!match) return; if (!match) return;
// Enrich track object so downloads get correct metadata // Always safe to enrich: artwork, preview, explicit, iTunes artist name
if (match.artworkUrl100) t.artworkUrl100 = match.artworkUrl100; if (match.artworkUrl100) t.artworkUrl100 = match.artworkUrl100;
if (match.collectionName) t.collectionName = match.collectionName;
if (match.releaseDate) t.releaseDate = match.releaseDate;
if (match.trackNumber) t.trackNumber = match.trackNumber;
if (match.trackExplicitness) t.trackExplicitness = match.trackExplicitness; if (match.trackExplicitness) t.trackExplicitness = match.trackExplicitness;
if (match.previewUrl) t.previewUrl = match.previewUrl; if (match.previewUrl) t.previewUrl = match.previewUrl;
if (match.trackTimeMillis) t.durationMs = match.trackTimeMillis;
// Store iTunes canonical name separately — keeps original Spotify/Japanese in artistName // Store iTunes canonical name separately — keeps original Spotify/Japanese in artistName
// so the UI shows the original and YTM search uses the original channel name. // so the UI shows the original and YTM search uses the original channel name.
if (match.artistName) t.itunesArtistName = match.artistName; if (match.artistName) t.itunesArtistName = match.artistName;
// Only enrich album/duration if we're confident the iTunes match is the correct song.
// For Japanese titles we can't word-match, so we skip — the backend's lookupItunesTrackMeta
// handles it with better matching. For ASCII titles, require at least one shared word.
const JP_RE = /[ぁ-んァ-ン一-龯]/;
const isJapanese = JP_RE.test(t.trackName);
const _norm = s => new Set((s||'').toLowerCase().replace(/[^a-z0-9]/g,' ').split(/\s+/).filter(Boolean));
const titleMatch = !isJapanese && [..._norm(t.trackName)].some(w => _norm(match.trackName).has(w));
if (titleMatch) {
if (match.collectionName) t.collectionName = match.collectionName;
if (match.releaseDate) t.releaseDate = match.releaseDate;
if (match.trackNumber) t.trackNumber = match.trackNumber;
if (match.trackTimeMillis) t.durationMs = match.trackTimeMillis;
}
if (window._spotifyResolved?.tracks?.[idx]) Object.assign(window._spotifyResolved.tracks[idx], t); if (window._spotifyResolved?.tracks?.[idx]) Object.assign(window._spotifyResolved.tracks[idx], t);
const url = match.artworkUrl100 || match.artworkUrl60 || ''; const url = match.artworkUrl100 || match.artworkUrl60 || '';
if (url) _setArt(artEls[idx], url); if (url) _setArt(artEls[idx], url);