diff --git a/src/ui.js b/src/ui.js index d48e5b8..bea733b 100644 --- a/src/ui.js +++ b/src/ui.js @@ -474,12 +474,19 @@ export function switchNpTab(tab) { let _lyricsLines = []; let _lyricsSongId = null; +const LYRICS_LOOKAHEAD_MS = 200; // highlight line this many ms before its timestamp + function _parseLrc(text) { + let offsetMs = 0; const lines = []; for(const raw of text.split('\n')) { + const offM = raw.match(/^\[offset:\s*([+-]?\d+)\s*\]/i); + if(offM) { offsetMs = parseInt(offM[1]); continue; } const m = raw.match(/^\[(\d+):(\d+(?:\.\d+)?)\](.*)/); if(m) lines.push({ start: Math.round((parseInt(m[1])*60 + parseFloat(m[2]))*1000), value: m[3].trim() }); } + // [offset:N] shifts all timestamps by N ms (positive = lines appear later) + if(offsetMs) lines.forEach(l => l.start = Math.max(0, l.start + offsetMs)); return lines.sort((a,b) => a.start - b.start).filter(l => l.value); } @@ -559,9 +566,10 @@ async function _loadNpLyrics(songId) { export function updateLyricsHighlight(currentMs) { if(!_lyricsLines.length || !S.npLyricsMode) return; + const adjusted = currentMs + LYRICS_LOOKAHEAD_MS; let activeIdx = -1; for(let i = 0; i < _lyricsLines.length; i++) { - if(_lyricsLines[i].start <= currentMs) activeIdx = i; + if(_lyricsLines[i].start <= adjusted) activeIdx = i; else break; } _lyricsLines.forEach((line, i) => {