Initial commit: QZMusic Web version
This commit is contained in:
57
src/utils/lyricUtil.ts
Normal file
57
src/utils/lyricUtil.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import {LyricLine, parseLrc, parseQrc, parseTTML, parseYrc} from "@applemusic-like-lyrics/lyric";
|
||||
const sanitizeLyricLines = (lines: LyricLine[]): LyricLine[] => {
|
||||
const defaultLineDuration = 3000
|
||||
const toFiniteNumber = (v: any, fallback: number) => {
|
||||
const n = typeof v === 'number' ? v : Number(v)
|
||||
return Number.isFinite(n) ? n : fallback
|
||||
}
|
||||
const cleaned: LyricLine[] = []
|
||||
for (const rawLine of lines || []) {
|
||||
const rawWords = Array.isArray((rawLine as any).words) ? (rawLine as any).words : []
|
||||
const fixedWords: any[] = []
|
||||
let prevEnd = -1
|
||||
for (const rawWord of rawWords) {
|
||||
const rawStart = toFiniteNumber(rawWord?.startTime, Number.NaN)
|
||||
const rawEnd = toFiniteNumber(rawWord?.endTime, Number.NaN)
|
||||
if (!Number.isFinite(rawStart)) continue
|
||||
let startTime = Math.max(0, rawStart)
|
||||
if (startTime < prevEnd) startTime = prevEnd
|
||||
let endTime = Number.isFinite(rawEnd) ? rawEnd : startTime + 1
|
||||
if (endTime <= startTime) endTime = startTime + 1
|
||||
prevEnd = endTime
|
||||
fixedWords.push({ ...rawWord, startTime, endTime })
|
||||
}
|
||||
if (fixedWords.length === 0) continue
|
||||
|
||||
const firstWordStart = fixedWords[0].startTime
|
||||
const lastWordEnd = fixedWords[fixedWords.length - 1].endTime
|
||||
let startTime = toFiniteNumber((rawLine as any).startTime, firstWordStart)
|
||||
startTime = Math.max(0, startTime)
|
||||
let endTime = toFiniteNumber((rawLine as any).endTime, lastWordEnd)
|
||||
if (!Number.isFinite(endTime) || endTime <= startTime) endTime = startTime + defaultLineDuration
|
||||
if (endTime < lastWordEnd) endTime = lastWordEnd
|
||||
|
||||
cleaned.push({ ...(rawLine as any), startTime, endTime, words: fixedWords })
|
||||
}
|
||||
cleaned.sort((a: any, b: any) => (a?.startTime ?? 0) - (b?.startTime ?? 0))
|
||||
return cleaned
|
||||
}
|
||||
interface LyricData {
|
||||
ttml?: string,
|
||||
yrc?: string,
|
||||
lrc?: string,
|
||||
qrc?: string
|
||||
}
|
||||
export function parseLyric(lyric: LyricData):LyricLine[] {
|
||||
let parsed:LyricLine[] = []
|
||||
if (lyric.ttml != undefined) {
|
||||
parsed = parseTTML(lyric.ttml).lines;
|
||||
} else if (lyric.yrc != undefined) {
|
||||
parsed = parseYrc(lyric.yrc);
|
||||
} else if (lyric.lrc != undefined) {
|
||||
parsed = parseLrc(lyric.lrc);
|
||||
} else if (lyric.qrc != undefined) {
|
||||
parsed = parseQrc(lyric.qrc)
|
||||
}
|
||||
return sanitizeLyricLines(parsed);
|
||||
}
|
||||
Reference in New Issue
Block a user