Files
smart-lyric/src/lyric/nrc.ts
2023-02-07 08:57:53 +08:00

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')
}