66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { IKaraokeWord, ILyric, ILyricLine, LyricType } from './declare'
|
|
import { genLyricTag, parseLyricTag } from './common'
|
|
|
|
/**
|
|
* 解析nrc歌词
|
|
* @param nrcxText nrc歌词文本内容
|
|
*/
|
|
export function parse(nrcxText: string) {
|
|
//结果
|
|
const result: ILyric = { type: LyricType.KARA, content: [] }
|
|
|
|
//逐行处理
|
|
nrcxText.split(/\r?\n/).forEach(line => {
|
|
line = line.trim()
|
|
const match = line.match(/^\[(\d+),(\d+)\]/)
|
|
if (match) {
|
|
const lyricLine: ILyricLine<IKaraokeWord[]> = {
|
|
start: parseInt(match[1]),
|
|
duration: parseInt(match[2]),
|
|
content: [],
|
|
}
|
|
line = line.substring(match[0].length)
|
|
while (line.length) {
|
|
const match = line.match(/^\((\d+),(\d+)(,(\d+))?\)([^\(]+)/)
|
|
if (!match) break
|
|
const start = parseInt(match[1])
|
|
const dur = parseInt(match[2])
|
|
const txt = match[5]
|
|
lyricLine.content.push({
|
|
start: start - lyricLine.start,
|
|
duration: dur,
|
|
content: txt,
|
|
})
|
|
line = line.substring(match[0].length)
|
|
}
|
|
if (lyricLine.content.length) result.content.push(lyricLine)
|
|
}
|
|
else parseLyricTag(result, line)
|
|
})
|
|
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* 将nrc歌词转换为文本
|
|
*
|
|
* @param lyric 歌词(只能是卡拉OK歌词)
|
|
*/
|
|
export function stringify(lyric: ILyric) {
|
|
if (lyric.type != LyricType.KARA) throw new Error(`lrc cannot stringify to nrc`)
|
|
|
|
const buffer: string[] = [...genLyricTag(lyric)]
|
|
|
|
|
|
lyric.content.forEach(line => {
|
|
if (typeof line.content === 'string') return
|
|
|
|
const text = line.content.map(word => {
|
|
return `(${word.start + line.start},${word.duration},${0})${word.content}`
|
|
}).join('')
|
|
buffer.push(`[${line.start},${line.duration}]${text}`)
|
|
})
|
|
|
|
return buffer.join('\n')
|
|
}
|