diff --git a/src/nowplaying.js b/src/nowplaying.js index 4d8786b..fc37bdc 100644 --- a/src/nowplaying.js +++ b/src/nowplaying.js @@ -137,13 +137,26 @@ async function _loadNpLyrics(songId) { return; } - // 2. Fallback: fetch synced lyrics from LRCLIB + // 2. Fallback: fetch lyrics from LRCLIB + // Use only first artist (multi-artist strings like "A / B" break lookup) + const firstArtist = (s?.artist||'').split(/[/,]/)[0].trim(); let lrcText = null; + let lrclibPlain = null; try { - const p = new URLSearchParams({ artist_name: s?.artist||'', track_name: s?.title||'' }); - if(s?.album) p.set('album_name', s.album); - const r = await fetch(`https://lrclib.net/api/get?${p}`, { signal: AbortSignal.timeout(8000) }); - if(r.ok) { const d = await r.json(); lrcText = d.syncedLyrics || null; } + // Try with album first, then without (album mismatch causes 404) + const attempts = [ + new URLSearchParams({ artist_name: firstArtist, track_name: s?.title||'', ...(s?.album ? { album_name: s.album } : {}) }), + ...(s?.album ? [new URLSearchParams({ artist_name: firstArtist, track_name: s?.title||'' })] : []), + ]; + for(const p of attempts) { + const r = await fetch(`https://lrclib.net/api/get?${p}`, { signal: AbortSignal.timeout(6000) }); + if(r.ok) { + const d = await r.json(); + lrcText = d.syncedLyrics || null; + lrclibPlain = d.plainLyrics || null; + break; + } + } } catch {} content.innerHTML = ''; @@ -152,10 +165,9 @@ async function _loadNpLyrics(songId) { if(parsed.length) { _renderSyncedLines(content, parsed); return; } } - // 3. Plain text fallback - const plain = track?.line?.length - ? track.line.map(l => l.value).join('\n') - : null; + // 3. Plain text — prefer LRCLIB plain over Navidrome plain (usually better quality) + const plain = lrclibPlain + || (track?.line?.length ? track.line.map(l => l.value).join('\n') : null); if(plain) { const el = document.createElement('div'); el.className = 'lyrics-plain';