新增 Any Listen 歌词标签数据嵌入、下载、读取播放(#2485)
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
### 新增
|
### 新增
|
||||||
|
|
||||||
- 新增「设置 → 其他设置 → 主窗口使用软件内置的圆角及阴影」选项(#2360)
|
- 新增「设置 → 其他设置 → 主窗口使用软件内置的圆角及阴影」选项(#2360)
|
||||||
*默认启用,关闭后将使用系统原生的窗口样式,该选项重启软件后生效*
|
*默认启用,关闭后将使用系统原生的窗口样式,该选项重启软件后生效*
|
||||||
- 开放 API 新增播放器声音大小、静音、播放进度控制,详情看接入文档(#2386)
|
- 开放 API 新增播放器声音大小、静音、播放进度控制,详情看接入文档(#2386)
|
||||||
- 新增「设置 → 播放设置 → 调换歌词翻译与歌词罗马音位置」选项,默认关闭(#2451)
|
- 新增「设置 → 播放设置 → 调换歌词翻译与歌词罗马音位置」选项,默认关闭(#2451)
|
||||||
- 新增启动参数 `-hidden`,在启动时将软件最小化到系统托盘(#2459)
|
- 新增启动参数 `-hidden`,在启动时将软件最小化到系统托盘(#2459)
|
||||||
|
- 新增 Any Listen 歌词标签数据读取与播放(#2485)
|
||||||
|
- 新增 Any Listen 歌词(包含逐字歌词、翻译、罗马音歌词,如果有)嵌入与下载,默认启用
|
||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
|
|
||||||
@@ -12,7 +14,7 @@
|
|||||||
|
|
||||||
### 变更
|
### 变更
|
||||||
|
|
||||||
- 调换「歌词翻译」与「歌词罗马音」的位置,现在歌词罗马音在歌词翻译的上方展示
|
- 调换「歌词翻译」与「歌词罗马音」的位置,现在歌词罗马音在歌词翻译的上方展示
|
||||||
*若你想要恢复以前的行为,可以开启「调换歌词翻译与歌词罗马音位置」选项*
|
*若你想要恢复以前的行为,可以开启「调换歌词翻译与歌词罗马音位置」选项*
|
||||||
- 更新代理配置规则,现在不启用代理时,图片、音频加载将不再走系统代理(#2382 @Folltoshe)
|
- 更新代理配置规则,现在不启用代理时,图片、音频加载将不再走系统代理(#2382 @Folltoshe)
|
||||||
|
|
||||||
|
|||||||
@@ -116,11 +116,13 @@ const defaultSetting: LX.AppSetting = {
|
|||||||
'download.maxDownloadNum': 3,
|
'download.maxDownloadNum': 3,
|
||||||
'download.skipExistFile': true,
|
'download.skipExistFile': true,
|
||||||
'download.isDownloadLrc': false,
|
'download.isDownloadLrc': false,
|
||||||
|
'download.isDownloadLxLrc': true,
|
||||||
'download.isDownloadTLrc': false,
|
'download.isDownloadTLrc': false,
|
||||||
'download.isDownloadRLrc': false,
|
'download.isDownloadRLrc': false,
|
||||||
'download.lrcFormat': 'utf8',
|
'download.lrcFormat': 'utf8',
|
||||||
'download.isEmbedPic': true,
|
'download.isEmbedPic': true,
|
||||||
'download.isEmbedLyric': false,
|
'download.isEmbedLyric': false,
|
||||||
|
'download.isEmbedLyricLx': true,
|
||||||
'download.isEmbedLyricT': false,
|
'download.isEmbedLyricT': false,
|
||||||
'download.isEmbedLyricR': false,
|
'download.isEmbedLyricR': false,
|
||||||
'download.isUseOtherSource': false,
|
'download.isUseOtherSource': false,
|
||||||
|
|||||||
Vendored
+10
@@ -530,6 +530,11 @@ declare global {
|
|||||||
*/
|
*/
|
||||||
'download.isDownloadLrc': boolean
|
'download.isDownloadLrc': boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否在下载 lx 歌词
|
||||||
|
*/
|
||||||
|
'download.isDownloadLxLrc': boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否下载翻译歌词文件
|
* 是否下载翻译歌词文件
|
||||||
*/
|
*/
|
||||||
@@ -550,6 +555,11 @@ declare global {
|
|||||||
*/
|
*/
|
||||||
'download.isEmbedPic': boolean
|
'download.isEmbedPic': boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否在音频文件中嵌入 lx 歌词
|
||||||
|
*/
|
||||||
|
'download.isEmbedLyricLx': boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否在音频文件中嵌入歌词
|
* 是否在音频文件中嵌入歌词
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -407,11 +407,13 @@
|
|||||||
"setting__dislike_list_title": "Disliked Song Rule List",
|
"setting__dislike_list_title": "Disliked Song Rule List",
|
||||||
"setting__download": "Download",
|
"setting__download": "Download",
|
||||||
"setting__download_data_embed": "Embed the Following into Audio File",
|
"setting__download_data_embed": "Embed the Following into Audio File",
|
||||||
|
"setting__download_embed_lxlyric": "Embed LX Music lyrics at the same time (if any, verbatim lyrics can be supported when playing with LX Music)",
|
||||||
"setting__download_embed_lyric": "Embed lyrics",
|
"setting__download_embed_lyric": "Embed lyrics",
|
||||||
"setting__download_embed_pic": "Embed cover",
|
"setting__download_embed_pic": "Embed cover",
|
||||||
"setting__download_embed_rlyric": "Also embed romanized lyrics if available",
|
"setting__download_embed_rlyric": "Also embed romanized lyrics if available",
|
||||||
"setting__download_embed_tlyric": "Also embed translated lyrics if available",
|
"setting__download_embed_tlyric": "Also embed translated lyrics if available",
|
||||||
"setting__download_enable": "Enable Download",
|
"setting__download_enable": "Enable Download",
|
||||||
|
"setting__download_lxlyric": "Also write LX Music lyrics into the lyrics file (if any, verbatim lyrics can be supported when playing with LX Music)",
|
||||||
"setting__download_lyric": "Lyric Download",
|
"setting__download_lyric": "Lyric Download",
|
||||||
"setting__download_lyric_format": "Encoding Format of Downloaded Lyric Files",
|
"setting__download_lyric_format": "Encoding Format of Downloaded Lyric Files",
|
||||||
"setting__download_lyric_format_gbk": "GBK",
|
"setting__download_lyric_format_gbk": "GBK",
|
||||||
|
|||||||
@@ -407,11 +407,13 @@
|
|||||||
"setting__dislike_list_title": "「不喜欢的歌曲」规则列表",
|
"setting__dislike_list_title": "「不喜欢的歌曲」规则列表",
|
||||||
"setting__download": "下载设置",
|
"setting__download": "下载设置",
|
||||||
"setting__download_data_embed": "嵌入到音频文件中的内容",
|
"setting__download_data_embed": "嵌入到音频文件中的内容",
|
||||||
|
"setting__download_embed_lxlyric": "同时嵌入 LX Music 歌词(如果有,使用 LX Music 播放时可支持逐字歌词)",
|
||||||
"setting__download_embed_lyric": "嵌入歌词",
|
"setting__download_embed_lyric": "嵌入歌词",
|
||||||
"setting__download_embed_pic": "嵌入封面",
|
"setting__download_embed_pic": "嵌入封面",
|
||||||
"setting__download_embed_rlyric": "同时嵌入罗马音歌词(如果有)",
|
"setting__download_embed_rlyric": "同时嵌入罗马音歌词(如果有)",
|
||||||
"setting__download_embed_tlyric": "同时嵌入翻译歌词(如果有)",
|
"setting__download_embed_tlyric": "同时嵌入翻译歌词(如果有)",
|
||||||
"setting__download_enable": "启用下载功能",
|
"setting__download_enable": "启用下载功能",
|
||||||
|
"setting__download_lxlyric": "同时将 LX Music 歌词写入歌词文件中(如果有,使用 LX Music 播放时可支持逐字歌词)",
|
||||||
"setting__download_lyric": "歌词下载",
|
"setting__download_lyric": "歌词下载",
|
||||||
"setting__download_lyric_format": "下载的歌词文件编码格式",
|
"setting__download_lyric_format": "下载的歌词文件编码格式",
|
||||||
"setting__download_lyric_format_gbk": "GBK",
|
"setting__download_lyric_format_gbk": "GBK",
|
||||||
|
|||||||
@@ -407,11 +407,13 @@
|
|||||||
"setting__dislike_list_title": "「不喜歡的歌曲」規則清單",
|
"setting__dislike_list_title": "「不喜歡的歌曲」規則清單",
|
||||||
"setting__download": "下載設定",
|
"setting__download": "下載設定",
|
||||||
"setting__download_data_embed": "嵌入到音訊檔案中的內容",
|
"setting__download_data_embed": "嵌入到音訊檔案中的內容",
|
||||||
|
"setting__download_embed_lxlyric": "同時嵌入 LX Music 歌詞(如果有,使用 LX Music 播放時可支持逐字歌詞)",
|
||||||
"setting__download_embed_lyric": "嵌入歌詞",
|
"setting__download_embed_lyric": "嵌入歌詞",
|
||||||
"setting__download_embed_pic": "嵌入封面",
|
"setting__download_embed_pic": "嵌入封面",
|
||||||
"setting__download_embed_rlyric": "同時嵌入羅馬音歌詞(如果有)",
|
"setting__download_embed_rlyric": "同時嵌入羅馬音歌詞(如果有)",
|
||||||
"setting__download_embed_tlyric": "同時嵌入翻譯歌詞(如果有)",
|
"setting__download_embed_tlyric": "同時嵌入翻譯歌詞(如果有)",
|
||||||
"setting__download_enable": "啟用下載功能",
|
"setting__download_enable": "啟用下載功能",
|
||||||
|
"setting__download_lxlyric": "同時將 LX Music 歌詞寫入歌詞文件中(如果有,使用 LX Music 播放時可支持逐字歌詞)",
|
||||||
"setting__download_lyric": "歌詞下載",
|
"setting__download_lyric": "歌詞下載",
|
||||||
"setting__download_lyric_format": "下載的歌詞檔案編碼格式",
|
"setting__download_lyric_format": "下載的歌詞檔案編碼格式",
|
||||||
"setting__download_lyric_format_gbk": "GBK",
|
"setting__download_lyric_format_gbk": "GBK",
|
||||||
|
|||||||
@@ -166,22 +166,17 @@ const saveMeta = (downloadInfo: LX.Download.ListItem) => {
|
|||||||
: Promise.resolve(null),
|
: Promise.resolve(null),
|
||||||
]
|
]
|
||||||
void Promise.all(tasks).then(([imgUrl, lyrics]) => {
|
void Promise.all(tasks).then(([imgUrl, lyrics]) => {
|
||||||
const lrcData = {
|
const info = {
|
||||||
lrc: '',
|
filePath: downloadInfo.metadata.filePath,
|
||||||
tlrc: null as string | null,
|
isEmbedLyricLx: appSetting['download.isEmbedLyricLx'],
|
||||||
rlrc: null as string | null,
|
isEmbedLyricT: appSetting['download.isEmbedLyricT'],
|
||||||
}
|
isEmbedLyricR: appSetting['download.isEmbedLyricR'],
|
||||||
if (lyrics) {
|
|
||||||
lrcData.lrc = lyrics.lyric
|
|
||||||
if (appSetting['download.isEmbedLyricT'] && lyrics.tlyric) lrcData.tlrc = lyrics.tlyric
|
|
||||||
if (appSetting['download.isEmbedLyricR'] && lyrics.rlyric) lrcData.rlrc = lyrics.rlyric
|
|
||||||
}
|
|
||||||
void window.lx.worker.download.writeMeta(downloadInfo.metadata.filePath, {
|
|
||||||
title: downloadInfo.metadata.musicInfo.name,
|
title: downloadInfo.metadata.musicInfo.name,
|
||||||
artist: downloadInfo.metadata.musicInfo.singer?.replaceAll('、', ';'),
|
artist: downloadInfo.metadata.musicInfo.singer?.replaceAll('、', ';'),
|
||||||
album: downloadInfo.metadata.musicInfo.meta.albumName,
|
album: downloadInfo.metadata.musicInfo.meta.albumName,
|
||||||
APIC: imgUrl,
|
APIC: imgUrl,
|
||||||
}, lrcData, getProxy())
|
}
|
||||||
|
void window.lx.worker.download.writeMeta(info, lyrics ?? { lyric: '' }, getProxy())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,14 +193,14 @@ const downloadLyric = (downloadInfo: LX.Download.ListItem) => {
|
|||||||
}).then(lrcs => {
|
}).then(lrcs => {
|
||||||
if (lrcs.lyric) {
|
if (lrcs.lyric) {
|
||||||
lrcs.lyric = fixKgLyric(lrcs.lyric)
|
lrcs.lyric = fixKgLyric(lrcs.lyric)
|
||||||
const lrcData = {
|
const info = {
|
||||||
lrc: lrcs.lyric,
|
filePath: downloadInfo.metadata.filePath.substring(0, downloadInfo.metadata.filePath.lastIndexOf('.')) + '.lrc',
|
||||||
tlrc: appSetting['download.isDownloadTLrc'] && lrcs.tlyric ? lrcs.tlyric : null,
|
format: appSetting['download.lrcFormat'],
|
||||||
rlrc: appSetting['download.isDownloadRLrc'] && lrcs.rlyric ? lrcs.rlyric : null,
|
downloadLxlrc: appSetting['download.isDownloadLxLrc'],
|
||||||
|
downloadTlrc: appSetting['download.isDownloadTLrc'],
|
||||||
|
downloadRlrc: appSetting['download.isDownloadRLrc'],
|
||||||
}
|
}
|
||||||
void window.lx.worker.download.saveLrc(lrcData,
|
void window.lx.worker.download.saveLrc(lrcs, info)
|
||||||
downloadInfo.metadata.filePath.substring(0, downloadInfo.metadata.filePath.lastIndexOf('.')) + '.lrc',
|
|
||||||
appSetting['download.lrcFormat'])
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
import { setMeta } from '@common/utils/musicMeta'
|
import { setMeta } from '@common/utils/musicMeta'
|
||||||
import { mergeLyrics } from './lrcTool'
|
import { buildLyrics } from './lrcTool'
|
||||||
|
|
||||||
export const writeMeta = (filePath: string, meta: Omit<LX.Music.MusicFileMeta, 'lyrics'>, lyricData: { lrc: string, tlrc: string | null, rlrc: string | null }, proxy?: { host: string, port: number }) => {
|
export const writeMeta = ({ filePath, isEmbedLyricLx, isEmbedLyricT, isEmbedLyricR, ...meta }: {
|
||||||
setMeta(filePath, { ...meta, lyrics: mergeLyrics(lyricData.lrc, lyricData.tlrc, lyricData.rlrc) || null }, proxy)
|
filePath: string
|
||||||
|
isEmbedLyricLx: boolean
|
||||||
|
isEmbedLyricT: boolean
|
||||||
|
isEmbedLyricR: boolean
|
||||||
|
title: string
|
||||||
|
artist: string
|
||||||
|
album: string
|
||||||
|
APIC: string | null
|
||||||
|
}, lyric: LX.Music.LyricInfo, proxy?: { host: string, port: number }) => {
|
||||||
|
setMeta(filePath, { ...meta, lyrics: buildLyrics(lyric, isEmbedLyricLx, isEmbedLyricT, isEmbedLyricR) }, proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { saveLrc } from './utils'
|
export { saveLrc } from './utils'
|
||||||
|
|||||||
@@ -61,14 +61,38 @@ const parseLrcTimeLabel = (lrc: string) => {
|
|||||||
return linesSet
|
return linesSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buildAwlyric = (lrcData: LX.Music.LyricInfo) => {
|
||||||
|
let lrc: string[] = []
|
||||||
|
if (lrcData.lyric) {
|
||||||
|
lrc.push(`lrc:${Buffer.from(lrcData.lyric.trim(), 'utf-8').toString('base64')}`)
|
||||||
|
}
|
||||||
|
if (lrcData.tlyric) {
|
||||||
|
lrc.push(`tlrc:${Buffer.from(lrcData.tlyric.trim(), 'utf-8').toString('base64')}`)
|
||||||
|
}
|
||||||
|
if (lrcData.rlyric) {
|
||||||
|
lrc.push(`rlrc:${Buffer.from(lrcData.rlyric.trim(), 'utf-8').toString('base64')}`)
|
||||||
|
}
|
||||||
|
if (lrcData.lxlyric) {
|
||||||
|
lrc.push(`awlrc:${Buffer.from(lrcData.lxlyric.trim(), 'utf-8').toString('base64')}`)
|
||||||
|
}
|
||||||
|
return lrc.length ? `[awlrc:${lrc.join(',')}]` : ''
|
||||||
|
}
|
||||||
|
|
||||||
export const mergeLyrics = (lrc: string, tlrc: string | null, rlrc: string | null) => {
|
export const buildLyrics = (lrcData: LX.Music.LyricInfo, downloadAwlrc: boolean, downloadTlrc: boolean, downloadRlrc: boolean) => {
|
||||||
if (!tlrc && !rlrc) return lrc
|
if (!lrcData.tlyric && !lrcData.rlyric && !lrcData.lxlyric) return lrcData.lyric
|
||||||
|
|
||||||
const lrcTimeLabels = parseLrcTimeLabel(lrc)
|
const lrcTimeLabels = parseLrcTimeLabel(lrcData.lyric)
|
||||||
// console.log(lrcTimeLabels)
|
|
||||||
if (tlrc) lrc += `\n\n${filterExtendedLyricLabel(lrcTimeLabels, tlrc)}\n`
|
let lrc = lrcData.lyric
|
||||||
if (rlrc) lrc += `\n\n${filterExtendedLyricLabel(lrcTimeLabels, rlrc)}\n`
|
if (downloadTlrc && lrcData.tlyric) {
|
||||||
// console.log(lrc)
|
lrc = lrc.trim() + `\n\n${filterExtendedLyricLabel(lrcTimeLabels, lrcData.tlyric)}\n`
|
||||||
|
}
|
||||||
|
if (downloadRlrc && lrcData.rlyric) {
|
||||||
|
lrc = lrc.trim() + `\n\n${filterExtendedLyricLabel(lrcTimeLabels, lrcData.rlyric)}\n`
|
||||||
|
}
|
||||||
|
if (downloadAwlrc) {
|
||||||
|
const awlrc = buildAwlyric(lrcData)
|
||||||
|
if (awlrc) lrc = lrc.trim() + `\n\n${awlrc}\n`
|
||||||
|
}
|
||||||
return lrc
|
return lrc
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,30 @@
|
|||||||
import { DOWNLOAD_STATUS, QUALITYS } from '@common/constants'
|
import { DOWNLOAD_STATUS, QUALITYS } from '@common/constants'
|
||||||
import { filterFileName } from '@common/utils/common'
|
import { filterFileName } from '@common/utils/common'
|
||||||
import { mergeLyrics } from './lrcTool'
|
import { buildLyrics } from './lrcTool'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { clipFileNameLength, clipNameLength } from '@common/utils/tools'
|
import { clipFileNameLength, clipNameLength } from '@common/utils/tools'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存歌词文件
|
* 保存歌词文件
|
||||||
* @param {*} filePath
|
|
||||||
* @param {*} lrc
|
|
||||||
* @param {*} format
|
|
||||||
*/
|
*/
|
||||||
export const saveLrc = async(lrcData: { lrc: string, tlrc: string | null, rlrc: string | null }, filePath: string, format: LX.LyricFormat) => {
|
export const saveLrc = async(lrcData: LX.Music.LyricInfo, info: {
|
||||||
|
filePath: string
|
||||||
|
format: LX.LyricFormat
|
||||||
|
downloadLxlrc: boolean
|
||||||
|
downloadTlrc: boolean
|
||||||
|
downloadRlrc: boolean
|
||||||
|
}) => {
|
||||||
const iconv = await import('iconv-lite')
|
const iconv = await import('iconv-lite')
|
||||||
const lrc = mergeLyrics(lrcData.lrc, lrcData.tlrc, lrcData.rlrc)
|
const lrc = buildLyrics(lrcData, info.downloadLxlrc, info.downloadTlrc, info.downloadRlrc)
|
||||||
switch (format) {
|
switch (info.format) {
|
||||||
case 'gbk':
|
case 'gbk':
|
||||||
fs.writeFile(filePath, iconv.encode(lrc, 'gbk', { addBOM: true }), err => {
|
fs.writeFile(info.filePath, iconv.encode(lrc, 'gbk', { addBOM: true }), err => {
|
||||||
if (err) console.log(err)
|
if (err) console.log(err)
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
case 'utf8':
|
case 'utf8':
|
||||||
default:
|
default:
|
||||||
fs.writeFile(filePath, iconv.encode(lrc, 'utf8', { addBOM: true }), err => {
|
fs.writeFile(info.filePath, iconv.encode(lrc, 'utf8', { addBOM: true }), err => {
|
||||||
if (err) console.log(err)
|
if (err) console.log(err)
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -29,8 +29,57 @@ export const getMusicFilePic = async(filePath: string) => {
|
|||||||
return `data:${picture.format};base64,${Buffer.from(picture.data).toString('base64')}`
|
return `data:${picture.format};base64,${Buffer.from(picture.data).toString('base64')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const parseLyric = (lrc: string): LX.Music.LyricInfo => {
|
||||||
|
const verifyAwlrc = (lrc: string) => {
|
||||||
|
return /(?:^|\s*)\[\d+:\d+(?:\.\d+)]<\d+,\d+>.+$/m.test(lrc)
|
||||||
|
}
|
||||||
|
const verifylrc = (lrc: string) => {
|
||||||
|
return /(?:^|\s*)\[\d+:\d+(?:\.\d+)].+$/m.test(lrc)
|
||||||
|
}
|
||||||
|
const lrcTags = {
|
||||||
|
awlrc: {
|
||||||
|
name: 'lxlyric',
|
||||||
|
verify: verifyAwlrc,
|
||||||
|
},
|
||||||
|
lrc: {
|
||||||
|
name: 'lyric',
|
||||||
|
verify: verifylrc,
|
||||||
|
},
|
||||||
|
tlrc: {
|
||||||
|
name: 'tlyric',
|
||||||
|
verify: verifylrc,
|
||||||
|
},
|
||||||
|
rlrc: {
|
||||||
|
name: 'rlyric',
|
||||||
|
verify: verifylrc,
|
||||||
|
},
|
||||||
|
rxp: /(?:^|\n\s*)\[(?:awlrc):([^\]]+)]/i,
|
||||||
|
rxp2: /^(lrc|awlrc|tlrc|rlrc):([^,]+)$/i,
|
||||||
|
} as const
|
||||||
|
const parse = (content: string) => {
|
||||||
|
const lyricInfo: Partial<LX.Music.LyricInfo> = {}
|
||||||
|
const lrcs = content.trim().split(',')
|
||||||
|
for (const lrc of lrcs) {
|
||||||
|
const result = lrcTags.rxp2.exec(lrc.trim())
|
||||||
|
if (!result) continue
|
||||||
|
const target = lrcTags[result[1].toLowerCase() as 'tlrc' | 'rlrc' | 'lrc' | 'awlrc']
|
||||||
|
if (!target) continue
|
||||||
|
const data = Buffer.from(result[2], 'base64').toString('utf-8').trim()
|
||||||
|
if (target.verify(data)) lyricInfo[target.name] = data
|
||||||
|
}
|
||||||
|
return lyricInfo
|
||||||
|
}
|
||||||
|
let parsedInfo: Partial<LX.Music.LyricInfo> = {}
|
||||||
|
let lyric = lrc.replace(lrcTags.rxp, (_: string, p1: string) => {
|
||||||
|
parsedInfo = parse(p1)
|
||||||
|
return ''
|
||||||
|
}).trim()
|
||||||
|
return { lyric, ...parsedInfo }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getMusicFileLyric = async(filePath: string): Promise<LX.Music.LyricInfo | null> => {
|
export const getMusicFileLyric = async(filePath: string): Promise<LX.Music.LyricInfo | null> => {
|
||||||
const lyric = await getLocalMusicFileLyric(filePath)
|
const lyric = await getLocalMusicFileLyric(filePath)
|
||||||
if (!lyric) return null
|
if (!lyric) return null
|
||||||
return lyric
|
return parseLyric(lyric.lyric)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user