mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-15 04:11:47 +00:00
feat(synced-lyrics): multiple lyric sources (#2383)
Co-authored-by: JellyBrick <shlee1503@naver.com>
This commit is contained in:
89
src/plugins/synced-lyrics/parsers/lrc.ts
Normal file
89
src/plugins/synced-lyrics/parsers/lrc.ts
Normal file
@ -0,0 +1,89 @@
|
||||
interface LRCTag {
|
||||
tag: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface LRCLine {
|
||||
time: string;
|
||||
timeInMs: number;
|
||||
duration: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface LRC {
|
||||
tags: LRCTag[];
|
||||
lines: LRCLine[];
|
||||
}
|
||||
|
||||
const tagRegex = /^\[(?<tag>\w+):\s*(?<value>.+?)\s*\]$/;
|
||||
// prettier-ignore
|
||||
const lyricRegex = /^\[(?<minutes>\d+):(?<seconds>\d+)\.(?<milliseconds>\d+)\](?<text>.+)$/;
|
||||
|
||||
export const LRC = {
|
||||
parse: (text: string): LRC => {
|
||||
const lrc: LRC = {
|
||||
tags: [],
|
||||
lines: [],
|
||||
};
|
||||
|
||||
let offset = 0;
|
||||
let previousLine: LRCLine | null = null;
|
||||
|
||||
for (const line of text.split('\n')) {
|
||||
if (!line.trim().startsWith('[')) continue;
|
||||
|
||||
const lyric = line.match(lyricRegex)?.groups;
|
||||
if (!lyric) {
|
||||
const tag = line.match(tagRegex)?.groups;
|
||||
if (tag) {
|
||||
if (tag.tag === 'offset') {
|
||||
offset = parseInt(tag.value);
|
||||
continue;
|
||||
}
|
||||
|
||||
lrc.tags.push({
|
||||
tag: tag.tag,
|
||||
value: tag.value,
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const { minutes, seconds, milliseconds, text } = lyric;
|
||||
const timeInMs =
|
||||
parseInt(minutes) * 60 * 1000 +
|
||||
parseInt(seconds) * 1000 +
|
||||
parseInt(milliseconds);
|
||||
|
||||
const currentLine: LRCLine = {
|
||||
time: `${minutes}:${seconds}:${milliseconds}`,
|
||||
timeInMs,
|
||||
text: text.trim(),
|
||||
duration: Infinity,
|
||||
};
|
||||
|
||||
if (previousLine) {
|
||||
previousLine.duration = timeInMs - previousLine.timeInMs;
|
||||
}
|
||||
|
||||
previousLine = currentLine;
|
||||
lrc.lines.push(currentLine);
|
||||
}
|
||||
|
||||
for (const line of lrc.lines) {
|
||||
line.timeInMs += offset;
|
||||
}
|
||||
|
||||
const first = lrc.lines.at(0);
|
||||
if (first && first.timeInMs > 300) {
|
||||
lrc.lines.unshift({
|
||||
time: '0:0:0',
|
||||
timeInMs: 0,
|
||||
duration: first.timeInMs,
|
||||
text: '',
|
||||
});
|
||||
}
|
||||
|
||||
return lrc;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user