添加x源逐字歌词的支持
This commit is contained in:
parent
62330571a3
commit
ab1d18debe
@ -3,26 +3,54 @@ const fsPromises = require('fs').promises
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const { Arch } = require('electron-builder')
|
const { Arch } = require('electron-builder')
|
||||||
|
|
||||||
const fileNameMap = {
|
const better_sqlite3_fileNameMap = {
|
||||||
[Arch.arm64]: 'arm64.glibc27',
|
[Arch.arm64]: 'arm64.glibc27',
|
||||||
[Arch.armv7l]: 'armv7l',
|
[Arch.armv7l]: 'armv7l',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const qrc_decode_fileNameMap = {
|
||||||
|
win32: {
|
||||||
|
[Arch.x64]: 'windows.x64',
|
||||||
|
[Arch.ia32]: 'windows.x86',
|
||||||
|
[Arch.arm64]: 'windows.arm64',
|
||||||
|
},
|
||||||
|
linux: {
|
||||||
|
[Arch.x64]: 'linux.x64',
|
||||||
|
[Arch.arm64]: 'linux.arm64',
|
||||||
|
[Arch.armv7l]: 'linux.armv7l',
|
||||||
|
},
|
||||||
|
darwin: {
|
||||||
|
[Arch.x64]: 'mac.x86',
|
||||||
|
[Arch.arm64]: 'mac.arm64',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const replaceSqliteLib = async(arch) => {
|
const replaceSqliteLib = async(arch) => {
|
||||||
// console.log(await fs.readdir(path.join(context.appOutDir, './resources/')))
|
// console.log(await fs.readdir(path.join(context.appOutDir, './resources/')))
|
||||||
// if (context.electronPlatformName != 'linux' || context.arch != Arch.arm64) return
|
// if (context.electronPlatformName != 'linux' || context.arch != Arch.arm64) return
|
||||||
// https://github.com/lyswhut/lx-music-desktop/issues/1102
|
// https://github.com/lyswhut/lx-music-desktop/issues/1102
|
||||||
// https://github.com/lyswhut/lx-music-desktop/issues/1161
|
// https://github.com/lyswhut/lx-music-desktop/issues/1161
|
||||||
console.log('replace sqlite lib...')
|
console.log('replace sqlite lib...')
|
||||||
const filePath = path.join(__dirname, `./lib/better_sqlite3.linux.${fileNameMap[arch]}.node`)
|
const filePath = path.join(__dirname, `./lib/better_sqlite3.linux.${better_sqlite3_fileNameMap[arch]}.node`)
|
||||||
const targetPath = path.join(__dirname, '../node_modules/better-sqlite3/build/Release/better_sqlite3.node')
|
const targetPath = path.join(__dirname, '../node_modules/better-sqlite3/build/Release/better_sqlite3.node')
|
||||||
await fsPromises.unlink(targetPath).catch(_ => _)
|
await fsPromises.unlink(targetPath).catch(_ => _)
|
||||||
await fsPromises.copyFile(filePath, targetPath)
|
await fsPromises.copyFile(filePath, targetPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const replaceQrcDecodeLib = async(platform, arch) => {
|
||||||
|
console.log('replace qrc_decode lib...', platform, qrc_decode_fileNameMap[platform][arch])
|
||||||
|
const filePath = path.join(__dirname, `./lib/qrc_decode.${qrc_decode_fileNameMap[platform][arch]}.node`)
|
||||||
|
const targetPath = path.join(__dirname, '../build/Release/qrc_decode.node')
|
||||||
|
const targetDir = path.dirname(targetPath)
|
||||||
|
if (fs.existsSync(targetDir)) await fsPromises.unlink(targetPath).catch(_ => _)
|
||||||
|
else await fsPromises.mkdir(targetDir, { recursive: true })
|
||||||
|
await fsPromises.copyFile(filePath, targetPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
module.exports = async(context) => {
|
module.exports = async(context) => {
|
||||||
const { electronPlatformName, arch } = context
|
const { electronPlatformName, arch } = context
|
||||||
|
await replaceQrcDecodeLib(electronPlatformName, arch)
|
||||||
if (electronPlatformName !== 'linux') return
|
if (electronPlatformName !== 'linux') return
|
||||||
const bindingFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp')
|
const bindingFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp')
|
||||||
const bindingBakFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp.bak')
|
const bindingBakFilePath = path.join(__dirname, '../node_modules/better-sqlite3/binding.gyp.bak')
|
||||||
|
|||||||
BIN
build-config/lib/qrc_decode.linux.arm64.node
Normal file
BIN
build-config/lib/qrc_decode.linux.arm64.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.linux.armv7l.node
Normal file
BIN
build-config/lib/qrc_decode.linux.armv7l.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.linux.x64.node
Normal file
BIN
build-config/lib/qrc_decode.linux.x64.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.mac.arm64.node
Normal file
BIN
build-config/lib/qrc_decode.mac.arm64.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.mac.x86.node
Normal file
BIN
build-config/lib/qrc_decode.mac.x86.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.windows.arm64.node
Normal file
BIN
build-config/lib/qrc_decode.windows.arm64.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.windows.x64.node
Normal file
BIN
build-config/lib/qrc_decode.windows.x64.node
Normal file
Binary file not shown.
BIN
build-config/lib/qrc_decode.windows.x86.node
Normal file
BIN
build-config/lib/qrc_decode.windows.x86.node
Normal file
Binary file not shown.
@ -1,6 +1,8 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const ESLintPlugin = require('eslint-webpack-plugin')
|
const ESLintPlugin = require('eslint-webpack-plugin')
|
||||||
|
|
||||||
|
const isDev = process.env.NODE_ENV === 'development'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
target: 'electron-main',
|
target: 'electron-main',
|
||||||
output: {
|
output: {
|
||||||
@ -10,12 +12,13 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
path: path.join(__dirname, '../../dist'),
|
path: path.join(__dirname, '../../dist'),
|
||||||
},
|
},
|
||||||
externals: [
|
externals: {
|
||||||
'font-list',
|
'font-list': 'font-list',
|
||||||
'better-sqlite3',
|
'better-sqlite3': 'better-sqlite3',
|
||||||
'bufferutil',
|
bufferutil: 'bufferutil',
|
||||||
'utf-8-validate',
|
'utf-8-validate': 'utf-8-validate',
|
||||||
],
|
'qrc_decode.node': isDev ? path.join(__dirname, '../../build/Release/qrc_decode.node') : path.join('../build/Release/qrc_decode.node'),
|
||||||
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@main': path.join(__dirname, '../../src/main'),
|
'@main': path.join(__dirname, '../../src/main'),
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "lx-music-desktop",
|
"name": "lx-music-desktop",
|
||||||
"version": "2.1.0-beta.4",
|
"version": "2.1.0-beta.6",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lx-music-desktop",
|
"name": "lx-music-desktop",
|
||||||
"version": "2.1.0-beta.4",
|
"version": "2.1.0-beta.6",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lx-music-desktop",
|
"name": "lx-music-desktop",
|
||||||
"version": "2.1.0-beta.4",
|
"version": "2.1.0-beta.6",
|
||||||
"description": "一个免费的音乐查找助手",
|
"description": "一个免费的音乐查找助手",
|
||||||
"main": "./dist/main.js",
|
"main": "./dist/main.js",
|
||||||
"productName": "lx-music-desktop",
|
"productName": "lx-music-desktop",
|
||||||
@ -100,6 +100,7 @@
|
|||||||
"node_modules/node-gyp-build",
|
"node_modules/node-gyp-build",
|
||||||
"node_modules/bufferutil",
|
"node_modules/bufferutil",
|
||||||
"node_modules/utf-8-validate",
|
"node_modules/utf-8-validate",
|
||||||
|
"build/Release/qrc_decode.node",
|
||||||
"dist/**/*"
|
"dist/**/*"
|
||||||
],
|
],
|
||||||
"asar": {
|
"asar": {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
- 新增桌面歌词设置字体加粗设置,可以到设置-桌面歌词设置-加粗字体修改
|
- 新增桌面歌词设置字体加粗设置,可以到设置-桌面歌词设置-加粗字体修改
|
||||||
- 新增是否自动下载更新设置,默认开启,可以去设置-软件更新更改
|
- 新增是否自动下载更新设置,默认开启,可以去设置-软件更新更改
|
||||||
- 新增当前版本更新日志显示弹窗(建议大家阅读更新日志以了解当前版本的变化),在更新版本后将自动弹出
|
- 新增当前版本更新日志显示弹窗(建议大家阅读更新日志以了解当前版本的变化),在更新版本后将自动弹出
|
||||||
- 添加wy源逐字歌词的支持
|
- 添加wy、tx源逐字歌词的支持
|
||||||
|
|
||||||
### 优化
|
### 优化
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,7 @@ const modules = {
|
|||||||
// lang_s2t: 'lang_s2t',
|
// lang_s2t: 'lang_s2t',
|
||||||
|
|
||||||
handle_kw_decode_lyric: 'handle_kw_decode_lyric',
|
handle_kw_decode_lyric: 'handle_kw_decode_lyric',
|
||||||
|
handle_tx_decode_lyric: 'handle_tx_decode_lyric',
|
||||||
get_lyric_info: 'get_lyric_info',
|
get_lyric_info: 'get_lyric_info',
|
||||||
set_lyric_info: 'set_lyric_info',
|
set_lyric_info: 'set_lyric_info',
|
||||||
set_config: 'set_config',
|
set_config: 'set_config',
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { registerRendererEvents as list } from '@main/modules/commonRenderers/li
|
|||||||
import app, { sendConfigChange } from './app'
|
import app, { sendConfigChange } from './app'
|
||||||
import hotKey from './hotKey'
|
import hotKey from './hotKey'
|
||||||
import kw_decodeLyric from './kw_decodeLyric'
|
import kw_decodeLyric from './kw_decodeLyric'
|
||||||
|
import tx_decodeLyric from './tx_decodeLyric'
|
||||||
import userApi from './userApi'
|
import userApi from './userApi'
|
||||||
import sync from './sync'
|
import sync from './sync'
|
||||||
import data from './data'
|
import data from './data'
|
||||||
@ -26,6 +27,7 @@ export default () => {
|
|||||||
app()
|
app()
|
||||||
hotKey()
|
hotKey()
|
||||||
kw_decodeLyric()
|
kw_decodeLyric()
|
||||||
|
tx_decodeLyric()
|
||||||
userApi()
|
userApi()
|
||||||
sync()
|
sync()
|
||||||
data()
|
data()
|
||||||
|
|||||||
46
src/main/modules/winMain/rendererEvent/tx_decodeLyric.ts
Normal file
46
src/main/modules/winMain/rendererEvent/tx_decodeLyric.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { inflate } from 'zlib'
|
||||||
|
// import path from 'path'
|
||||||
|
import { mainHandle } from '@common/mainIpc'
|
||||||
|
import { WIN_MAIN_RENDERER_EVENT_NAME } from '@common/ipcNames'
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/dot-notation, @typescript-eslint/quotes
|
||||||
|
// const require = module[`require`].bind(module)
|
||||||
|
|
||||||
|
let qrc_decode: (buf: Buffer, len: number) => Buffer
|
||||||
|
|
||||||
|
const decode = async(str: string): Promise<string> => {
|
||||||
|
if (!str) return ''
|
||||||
|
const buf = Buffer.from(str, 'hex')
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
inflate(qrc_decode(buf, buf.length), (err, lrc) => {
|
||||||
|
if (err) reject(err)
|
||||||
|
else resolve(lrc.toString())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleDecode = async(lrc: string, tlrc: string, rlrc: string) => {
|
||||||
|
if (!qrc_decode) {
|
||||||
|
// const nativeBindingPath = path.join(__dirname, '../build/Release/qrc_decode.node')
|
||||||
|
// const nativeBindingPath = isDev ? path.join(__dirname, '../build/Release/qrc_decode.node')
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const addon = require('qrc_decode.node')
|
||||||
|
console.log(addon)
|
||||||
|
qrc_decode = addon.qrc_decode
|
||||||
|
}
|
||||||
|
|
||||||
|
const [lyric, tlyric, rlyric] = await Promise.all([decode(lrc), decode(tlrc), decode(rlrc)])
|
||||||
|
return {
|
||||||
|
lyric,
|
||||||
|
tlyric,
|
||||||
|
rlyric,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
mainHandle<{ lrc: string, tlrc: string, rlrc: string }, { lyric: string, tlyric: string, rlyric: string }>(WIN_MAIN_RENDERER_EVENT_NAME.handle_tx_decode_lyric, async({ params: { lrc, tlrc, rlrc } }) => {
|
||||||
|
return handleDecode(lrc, tlrc, rlrc)
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -18,7 +18,7 @@ const tx = {
|
|||||||
},
|
},
|
||||||
getLyric(songInfo) {
|
getLyric(songInfo) {
|
||||||
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
||||||
return lyric.getLyric(songInfo.songmid)
|
return lyric.getLyric(songInfo)
|
||||||
},
|
},
|
||||||
getPic(songInfo) {
|
getPic(songInfo) {
|
||||||
return apis('tx').getPic(songInfo)
|
return apis('tx').getPic(songInfo)
|
||||||
|
|||||||
@ -1,23 +1,283 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { b64DecodeUnicode, decodeName } from '../../index'
|
import getMusicInfo from './musicInfo'
|
||||||
|
import { rendererInvoke } from '@common/rendererIpc'
|
||||||
|
import { WIN_MAIN_RENDERER_EVENT_NAME } from '@common/ipcNames'
|
||||||
|
|
||||||
export default {
|
const songIdMap = new Map()
|
||||||
regexps: {
|
const promises = new Map()
|
||||||
matchLrc: /.+"lyric":"([\w=+/]*)".+/,
|
export const decodeLyric = (lrc, tlrc, rlrc) => rendererInvoke(WIN_MAIN_RENDERER_EVENT_NAME.handle_tx_decode_lyric, { lrc, tlrc, rlrc })
|
||||||
|
|
||||||
|
|
||||||
|
const parseTools = {
|
||||||
|
rxps: {
|
||||||
|
info: /^{"/,
|
||||||
|
lineTime: /^\[(\d+),\d+\]/,
|
||||||
|
wordTime: /\(\d+,\d+\)/,
|
||||||
|
wordTimeAll: /(\(\d+,\d+\))/g,
|
||||||
|
timeLabelFixRxp: /(?:\.0+|0+)$/,
|
||||||
},
|
},
|
||||||
getLyric(songmid) {
|
msFormat(timeMs) {
|
||||||
const requestObj = httpFetch(`https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid=${songmid}&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&platform=yqq`, {
|
if (Number.isNaN(timeMs)) return ''
|
||||||
headers: {
|
let ms = timeMs % 1000
|
||||||
Referer: 'https://y.qq.com/portal/player.html',
|
timeMs /= 1000
|
||||||
},
|
let m = parseInt(timeMs / 60).toString().padStart(2, '0')
|
||||||
})
|
timeMs %= 60
|
||||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
let s = parseInt(timeMs).toString().padStart(2, '0')
|
||||||
if (body.code != 0 || !body.lyric) return Promise.reject(new Error('Get lyric failed'))
|
return `[${m}:${s}.${String(ms).padStart(3, '0')}]`
|
||||||
return {
|
},
|
||||||
lyric: decodeName(b64DecodeUnicode(body.lyric)),
|
parseLyric(lrc) {
|
||||||
tlyric: decodeName(b64DecodeUnicode(body.trans)),
|
lrc = lrc.trim()
|
||||||
|
lrc = lrc.replace(/\r/g, '')
|
||||||
|
if (!lrc) return { lyric: '', lxlyric: '' }
|
||||||
|
const lines = lrc.split('\n')
|
||||||
|
|
||||||
|
const lxlrcLines = []
|
||||||
|
const lrcLines = []
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
line = line.trim()
|
||||||
|
let result = this.rxps.lineTime.exec(line)
|
||||||
|
if (!result) {
|
||||||
|
if (line.startsWith('[offset')) {
|
||||||
|
lxlrcLines.push(line)
|
||||||
|
lrcLines.push(line)
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startMsTime = parseInt(result[1])
|
||||||
|
const startTimeStr = this.msFormat(startMsTime)
|
||||||
|
if (!startTimeStr) continue
|
||||||
|
|
||||||
|
let words = line.replace(this.rxps.lineTime, '')
|
||||||
|
|
||||||
|
lrcLines.push(`${startTimeStr}${words.replace(this.rxps.wordTimeAll, '')}`)
|
||||||
|
|
||||||
|
let times = words.match(this.rxps.wordTimeAll)
|
||||||
|
if (!times) continue
|
||||||
|
times = times.map(time => {
|
||||||
|
const result = /\((\d+),(\d+)\)/.exec(time)
|
||||||
|
return `<${Math.max(parseInt(result[1]) - startMsTime, 0)},${result[2]}>`
|
||||||
|
})
|
||||||
|
const wordArr = words.split(this.rxps.wordTime)
|
||||||
|
const newWords = times.map((time, index) => `${time}${wordArr[index]}`).join('')
|
||||||
|
lxlrcLines.push(`${startTimeStr}${newWords}`)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
lyric: lrcLines.join('\n'),
|
||||||
|
lxlyric: lxlrcLines.join('\n'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseRlyric(lrc) {
|
||||||
|
lrc = lrc.trim()
|
||||||
|
lrc = lrc.replace(/\r/g, '')
|
||||||
|
if (!lrc) return { lyric: '', lxlyric: '' }
|
||||||
|
const lines = lrc.split('\n')
|
||||||
|
|
||||||
|
const lrcLines = []
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
line = line.trim()
|
||||||
|
let result = this.rxps.lineTime.exec(line)
|
||||||
|
if (!result) continue
|
||||||
|
|
||||||
|
const startMsTime = parseInt(result[1])
|
||||||
|
const startTimeStr = this.msFormat(startMsTime)
|
||||||
|
if (!startTimeStr) continue
|
||||||
|
|
||||||
|
let words = line.replace(this.rxps.lineTime, '')
|
||||||
|
|
||||||
|
lrcLines.push(`${startTimeStr}${words.replace(this.rxps.wordTimeAll, '')}`)
|
||||||
|
}
|
||||||
|
return lrcLines.join('\n')
|
||||||
|
},
|
||||||
|
removeTag(str) {
|
||||||
|
return str.replace(/^[\S\s]*?LyricContent="/, '').replace(/"\/>[\S\s]*?$/, '')
|
||||||
|
},
|
||||||
|
getIntv(interval) {
|
||||||
|
let [m, s, ms] = interval.split(/:|\./)
|
||||||
|
|
||||||
|
return parseInt(m) * 3600000 + parseInt(s) * 1000 + parseInt(ms)
|
||||||
|
},
|
||||||
|
fixRlrcTimeTag(rlrc, lrc) {
|
||||||
|
// console.log(lrc)
|
||||||
|
// console.log(rlrc)
|
||||||
|
const rlrcLines = rlrc.split('\n')
|
||||||
|
let lrcLines = lrc.split('\n')
|
||||||
|
// let temp = []
|
||||||
|
const timeTagRxp = /^\[([\d:.]+)\]/
|
||||||
|
let newLrc = []
|
||||||
|
rlrcLines.forEach((line) => {
|
||||||
|
const result = timeTagRxp.exec(line)
|
||||||
|
if (!result) return
|
||||||
|
const words = line.replace(timeTagRxp, '')
|
||||||
|
if (!words.trim()) return
|
||||||
|
const t1 = this.getIntv(result[1])
|
||||||
|
|
||||||
|
while (lrcLines.length) {
|
||||||
|
const lrcLine = lrcLines.shift()
|
||||||
|
const lrcLineResult = timeTagRxp.exec(lrcLine)
|
||||||
|
if (!lrcLineResult) continue
|
||||||
|
const t2 = this.getIntv(lrcLineResult[1])
|
||||||
|
if (Math.abs(t1 - t2) < 10) {
|
||||||
|
newLrc.push(line.replace(timeTagRxp, lrcLineResult[0]))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// temp.push(line)
|
||||||
|
}
|
||||||
|
// lrcLines = [...temp, ...lrcLines]
|
||||||
|
// temp = []
|
||||||
})
|
})
|
||||||
return requestObj
|
return newLrc.join('\n')
|
||||||
|
},
|
||||||
|
fixTlrcTimeTag(tlrc, lrc) {
|
||||||
|
// console.log(lrc)
|
||||||
|
// console.log(tlrc)
|
||||||
|
const tlrcLines = tlrc.split('\n')
|
||||||
|
let lrcLines = lrc.split('\n')
|
||||||
|
// let temp = []
|
||||||
|
const timeTagRxp = /^\[[\d:.]+\]/
|
||||||
|
let newLrc = []
|
||||||
|
tlrcLines.forEach((line) => {
|
||||||
|
const result = timeTagRxp.exec(line)
|
||||||
|
if (!result) return
|
||||||
|
const words = line.replace(timeTagRxp, '')
|
||||||
|
if (!words.trim()) return
|
||||||
|
const tag = result[0].replace(/\d]/, '').replace(this.rxps.timeLabelFixRxp, '')
|
||||||
|
|
||||||
|
while (lrcLines.length) {
|
||||||
|
const lrcLine = lrcLines.shift()
|
||||||
|
const lrcLineResult = timeTagRxp.exec(lrcLine)
|
||||||
|
if (!lrcLineResult) continue
|
||||||
|
if (lrcLineResult[0].includes(tag)) {
|
||||||
|
newLrc.push(line.replace(timeTagRxp, lrcLineResult[0]))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// temp.push(line)
|
||||||
|
}
|
||||||
|
// lrcLines = [...temp, ...lrcLines]
|
||||||
|
// temp = []
|
||||||
|
})
|
||||||
|
return newLrc.join('\n')
|
||||||
|
},
|
||||||
|
parse(lrc, tlrc, rlrc) {
|
||||||
|
const info = {
|
||||||
|
lyric: '',
|
||||||
|
tlyric: '',
|
||||||
|
rlyric: '',
|
||||||
|
lxlyric: '',
|
||||||
|
}
|
||||||
|
if (lrc) {
|
||||||
|
let { lyric, lxlyric } = this.parseLyric(this.removeTag(lrc))
|
||||||
|
info.lyric = lyric
|
||||||
|
info.lxlyric = lxlyric
|
||||||
|
// console.log(lyric)
|
||||||
|
// console.log(lxlyric)
|
||||||
|
}
|
||||||
|
if (rlrc) info.rlyric = this.fixRlrcTimeTag(this.parseRlyric(this.removeTag(rlrc)), info.lyric)
|
||||||
|
if (tlrc) info.tlyric = this.fixTlrcTimeTag(tlrc, info.lyric)
|
||||||
|
// console.log(info.lyric)
|
||||||
|
// console.log(info.tlyric)
|
||||||
|
// console.log(info.rlyric)
|
||||||
|
|
||||||
|
return info
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
successCode: 0,
|
||||||
|
async getSongId({ songId, songmid }) {
|
||||||
|
if (songId) return songId
|
||||||
|
if (songIdMap.has(songmid)) return songIdMap.get(songmid)
|
||||||
|
if (promises.has(songmid)) return (await promises.get(songmid)).songId
|
||||||
|
const promise = getMusicInfo(songmid)
|
||||||
|
promises.set(promise)
|
||||||
|
const info = await promise
|
||||||
|
songIdMap.set(songmid, info.songId)
|
||||||
|
promises.delete(songmid)
|
||||||
|
return info.songId
|
||||||
|
},
|
||||||
|
async parseLyric(lrc, tlrc, rlrc) {
|
||||||
|
const { lyric, tlyric, rlyric } = await decodeLyric(lrc, tlrc, rlrc)
|
||||||
|
// return {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// console.log(lyric)
|
||||||
|
// console.log(tlyric)
|
||||||
|
// console.log(rlyric)
|
||||||
|
return parseTools.parse(lyric, tlyric, rlyric)
|
||||||
|
},
|
||||||
|
getLyric(mInfo, retryNum = 0) {
|
||||||
|
if (retryNum > 3) return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
|
||||||
|
return {
|
||||||
|
cancelHttp() {
|
||||||
|
|
||||||
|
},
|
||||||
|
promise: this.getSongId(mInfo).then(songId => {
|
||||||
|
const requestObj = httpFetch('https://u.y.qq.com/cgi-bin/musicu.fcg', {
|
||||||
|
method: 'post',
|
||||||
|
headers: {
|
||||||
|
referer: 'https://y.qq.com',
|
||||||
|
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
comm: {
|
||||||
|
ct: '19',
|
||||||
|
cv: '1859',
|
||||||
|
uin: '0',
|
||||||
|
},
|
||||||
|
req: {
|
||||||
|
method: 'GetPlayLyricInfo',
|
||||||
|
module: 'music.musichallSong.PlayLyricInfo',
|
||||||
|
param: {
|
||||||
|
format: 'json',
|
||||||
|
crypt: 1,
|
||||||
|
ct: 19,
|
||||||
|
cv: 1873,
|
||||||
|
interval: 0,
|
||||||
|
lrc_t: 0,
|
||||||
|
qrc: 1,
|
||||||
|
qrc_t: 0,
|
||||||
|
roma: 1,
|
||||||
|
roma_t: 0,
|
||||||
|
songID: songId,
|
||||||
|
trans: 1,
|
||||||
|
trans_t: 0,
|
||||||
|
type: -1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return requestObj.promise.then(({ body }) => {
|
||||||
|
// console.log(body)
|
||||||
|
if (body.code != this.successCode || body.req.code != this.successCode) return this.getLyric(songId, ++retryNum)
|
||||||
|
const data = body.req.data
|
||||||
|
return this.parseLyric(data.lyric, data.trans, data.roma)
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// export default {
|
||||||
|
// regexps: {
|
||||||
|
// matchLrc: /.+"lyric":"([\w=+/]*)".+/,
|
||||||
|
// },
|
||||||
|
// getLyric(songmid) {
|
||||||
|
// const requestObj = httpFetch(`https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid=${songmid}&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&platform=yqq`, {
|
||||||
|
// headers: {
|
||||||
|
// Referer: 'https://y.qq.com/portal/player.html',
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
// if (body.code != 0 || !body.lyric) return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
// return {
|
||||||
|
// lyric: decodeName(b64DecodeUnicode(body.lyric)),
|
||||||
|
// tlyric: decodeName(b64DecodeUnicode(body.trans)),
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// return requestObj
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|||||||
@ -77,7 +77,13 @@ const parseTools = {
|
|||||||
for (let line of lines) {
|
for (let line of lines) {
|
||||||
line = line.trim()
|
line = line.trim()
|
||||||
let result = this.rxps.lineTime.exec(line)
|
let result = this.rxps.lineTime.exec(line)
|
||||||
if (!result) continue
|
if (!result) {
|
||||||
|
if (line.startsWith('[offset')) {
|
||||||
|
lxlrcLines.push(line)
|
||||||
|
lrcLines.push(line)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const startMsTime = parseInt(result[1])
|
const startMsTime = parseInt(result[1])
|
||||||
const startTimeStr = this.msFormat(startMsTime)
|
const startTimeStr = this.msFormat(startMsTime)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user