添加wy源逐字歌词的支持

pull/1168/head
lyswhut 2023-01-31 23:40:25 +08:00
parent 4e3356ccb2
commit 7e27ec488b
3 changed files with 171 additions and 25 deletions

View File

@ -3,6 +3,7 @@
- 新增桌面歌词设置字体加粗设置,可以到设置-桌面歌词设置-加粗字体修改
- 新增是否自动下载更新设置,默认开启,可以去设置-软件更新更改
- 新增当前版本更新日志显示弹窗(建议大家阅读更新日志以了解当前版本的变化),在更新版本后将自动弹出
- 添加wy源逐字歌词的支持
### 优化

View File

@ -119,15 +119,17 @@ export const getCachedLyricInfo = async(musicInfo: LX.Music.MusicInfo): Promise<
// }
if (lrcInfo.lxlyric == null) {
switch (musicInfo.source) {
switch (musicInfo.source) { // 以下源支持lxlyric 重新获取
case 'kg':
case 'kw':
case 'mg':
case 'wy':
break
default:
return lrcInfo
}
} else if (lrcInfo.rlyric == null) {
// 以下源支持 rlyric 重新获取
if (!['wy', 'kg'].includes(musicInfo.source)) return lrcInfo
} else return lrcInfo
}

View File

@ -1,5 +1,5 @@
import { httpFetch } from '../../request'
import { linuxapi } from './utils/crypto'
import { eapi } from './utils/crypto'
// import { decodeName } from '../..'
// const parseLyric = (str, lrc) => {
@ -34,33 +34,176 @@ import { linuxapi } from './utils/crypto'
// return lxlyric.trim()
// }
// https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1523/files
export default songmid => {
const requestObj = httpFetch('https://music.163.com/api/linux/forward', {
const eapiRequest = (url, data) => {
return httpFetch('https://interface3.music.163.com/eapi/song/lyric/v1', {
method: 'post',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
form: linuxapi({
method: 'POST',
url: 'https://music.163.com/api/song/lyric?_nmclfl=1',
params: {
id: songmid,
tv: -1,
lv: -1,
rv: -1,
kv: -1,
},
}),
headers: {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
origin: 'https://music.163.com',
// cookie: 'os=pc; deviceId=A9C064BB4584D038B1565B58CB05F95290998EE8B025AA2D07AE; osver=Microsoft-Windows-10-Home-China-build-19043-64bit; appver=2.5.2.197409; channel=netease; MUSIC_A=37a11f2eb9de9930cad479b2ad495b0e4c982367fb6f909d9a3f18f876c6b49faddb3081250c4980dd7e19d4bd9bf384e004602712cf2b2b8efaafaab164268a00b47359f85f22705cc95cb6180f3aee40f5be1ebf3148d888aa2d90636647d0c3061cd18d77b7a0; __csrf=05b50d54082694f945d7de75c210ef94; mode=Z7M-KP5(7)GZ; NMTID=00OZLp2VVgq9QdwokUgq3XNfOddQyIAAAF_6i8eJg; ntes_kaola_ad=1',
},
form: eapi(url, data),
})
// requestObj.promise = requestObj.promise.then(({ body }) => {
// // console.log(raw)
// console.log(body)
// // console.log(eapiDecrypt(raw))
// // return eapiDecrypt(raw)
// return body
// })
// return requestObj
}
const parseTools = {
rxps: {
info: /^{"/,
lineTime: /^\[(\d+),\d+\]/,
wordTime: /\(\d+,\d+,\d+\)/,
wordTimeAll: /(\(\d+,\d+,\d+\))/g,
},
msFormat(timeMs) {
if (Number.isNaN(timeMs)) return ''
let ms = timeMs % 1000
timeMs /= 1000
let m = parseInt(timeMs / 60).toString().padStart(2, '0')
timeMs %= 60
let s = parseInt(timeMs).toString().padStart(2, '0')
return `[${m}:${s}.${ms}]`
},
parseLyric(lines) {
const lxlrcLines = []
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, '')}`)
let times = words.match(this.rxps.wordTimeAll)
if (!times) continue
times = times.map(time => {
const result = /\((\d+),(\d+),\d+\)/.exec(time)
return `<${Math.max(parseInt(result[1]) - startMsTime, 0)},${result[2]}>`
})
const wordArr = words.split(this.rxps.wordTime)
wordArr.shift()
const newWords = times.map((time, index) => `${time}${wordArr[index]}`).join('')
lxlrcLines.push(`${startTimeStr}${newWords}`)
}
return {
lyric: lrcLines.join('\n'),
lxlyric: lxlrcLines.join('\n'),
}
},
parseHeaderInfo(str) {
str = str.trim()
str = str.replace(/\r/g, '')
if (!str) return null
const lines = str.split('\n')
return lines.map(line => {
if (!this.rxps.info.test(line)) return line
try {
const info = JSON.parse(line)
const timeTag = this.msFormat(info.t)
return timeTag ? `${timeTag}${info.c.map(t => t.tx).join('')}` : ''
} catch {
return ''
}
})
},
parse(ylrc, lrc, tlrc, rlrc) {
const info = {
lyric: '',
tlyric: '',
rlyric: '',
lxlyric: '',
}
if (ylrc) {
let lines = this.parseHeaderInfo(ylrc)
if (lines) {
const timeRxp = /^\[[\d:.]+\]/
const headers = lines.filter(l => timeRxp.test(l)).join('\n')
const result = this.parseLyric(lines)
info.lxlyric = result.lxlyric
info.lyric = `${headers}\n${result.lyric}`
} else if (lrc) {
lines = this.parseHeaderInfo(lrc)
if (lines) info.lyric = lines.join('\n')
}
} else if (lrc) {
const lines = this.parseHeaderInfo(lrc)
if (lines) info.lyric = lines.join('\n')
}
if (tlrc) {
const lines = this.parseHeaderInfo(tlrc)
if (lines) info.tlyric = lines.join('\n')
}
if (rlrc) {
const lines = this.parseHeaderInfo(rlrc)
if (lines) info.rlyric = lines.join('\n')
}
return info
},
}
// https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1523/files
// export default songmid => {
// const requestObj = httpFetch('https://music.163.com/api/linux/forward', {
// method: 'post',
// 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
// form: linuxapi({
// method: 'POST',
// url: 'https://music.163.com/api/song/lyric?_nmclfl=1',
// params: {
// id: songmid,
// tv: -1,
// lv: -1,
// rv: -1,
// kv: -1,
// },
// }),
// })
// requestObj.promise = requestObj.promise.then(({ body }) => {
// if (body.code !== 200 || !body?.lrc?.lyric) return Promise.reject(new Error('Get lyric failed'))
// // console.log(body)
// return {
// lyric: body.lrc.lyric,
// tlyric: body.tlyric?.lyric ?? '',
// rlyric: body.romalrc?.lyric ?? '',
// // lxlyric: parseLyric(body.klyric.lyric),
// }
// })
// return requestObj
// }
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/lyric_new.js
export default songmid => {
const requestObj = eapiRequest('/api/song/lyric/v1', {
id: songmid,
cp: false,
tv: 0,
lv: 0,
rv: 0,
kv: 0,
yv: 0,
ytv: 0,
yrv: 0,
})
requestObj.promise = requestObj.promise.then(({ body }) => {
if (body.code !== 200 || !body?.lrc?.lyric) return Promise.reject(new Error('Get lyric failed'))
// console.log(body)
return {
lyric: body.lrc.lyric,
tlyric: body.tlyric?.lyric ?? '',
rlyric: body.romalrc?.lyric ?? '',
// lxlyric: parseLyric(body.klyric.lyric),
}
if (body.code !== 200 || !body?.lrc?.lyric) return Promise.reject(new Error('Get lyric failed'))
return parseTools.parse(body.yrc?.lyric, body.lrc.lyric, body.tlyric?.lyric, body.romalrc?.lyric)
})
return requestObj
}