From 1fd3e6c9fa902fc763b895457bcccaeda4886f5c Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 13 Mar 2022 15:00:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=8D=A2kw=E6=AD=8C=E8=AF=8D=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/rendererEvents/index.js | 2 +- src/renderer/utils/music/kw/index.js | 2 +- src/renderer/utils/music/kw/lyric.js | 110 ++++++++++++++++++++++----- src/renderer/utils/music/kw/util.js | 4 +- 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/src/main/rendererEvents/index.js b/src/main/rendererEvents/index.js index 76ab96a1..0ead3981 100644 --- a/src/main/rendererEvents/index.js +++ b/src/main/rendererEvents/index.js @@ -26,7 +26,7 @@ require('./nativeTheme') if (isWin) require('./taskbar') -// require('./kw_decodeLyric') +require('./kw_decodeLyric') require('./userApi') require('./sync') diff --git a/src/renderer/utils/music/kw/index.js b/src/renderer/utils/music/kw/index.js index 27c88171..b943f18a 100644 --- a/src/renderer/utils/music/kw/index.js +++ b/src/renderer/utils/music/kw/index.js @@ -40,7 +40,7 @@ const kw = { comment, getLyric(songInfo, isGetLyricx) { // let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer - return lyric.getLyric(songInfo.songmid, isGetLyricx) + return lyric.getLyric(songInfo, isGetLyricx) }, handleMusicInfo(songInfo) { return this.getMusicInfo(songInfo).then(info => { diff --git a/src/renderer/utils/music/kw/lyric.js b/src/renderer/utils/music/kw/lyric.js index a6ce8346..81d4c7ae 100644 --- a/src/renderer/utils/music/kw/lyric.js +++ b/src/renderer/utils/music/kw/lyric.js @@ -1,6 +1,8 @@ import { httpFetch } from '../../request' +import { decodeLyric } from './util' import { decodeName } from '../../index' +/* export default { formatTime(time) { let m = parseInt(time / 60) @@ -63,33 +65,99 @@ export default { return requestObj }, } + */ +const buf_key = Buffer.from('yeelion') +const buf_key_len = buf_key.length +const buildParams = (id, isGetLyricx) => { + let params = `user=12345,web,web,web&requester=localhost&req=1&rid=MUSIC_${id}` + if (isGetLyricx) params += '&lrcx=1' + const buf_str = Buffer.from(params) + const buf_str_len = buf_str.length + const output = new Uint16Array(buf_str_len) + let i = 0 + while (i < buf_str_len) { + let j = 0 + while (j < buf_key_len && i < buf_str_len) { + output[i] = buf_key[j] ^ buf_str[i] + i++ + j++ + } + } + return Buffer.from(output).toString('base64') +} -/* export default { - lrcInfoRxp: /(.+?)<\/lyric>[\s\S]+(.+?)<\/lyric_zz>/, - parseLyricInfo(str) { - let result = str.match(this.lrcInfoRxp) - return result ? { lyric: result[1], lyric_zz: result[2] } : null +// console.log(buildParams('207527604', false)) +// console.log(buildParams('207527604', true)) + +const timeExp = /^\[([\d:.]*)\]{1}/g +export default { + sortLrcArr(arr) { + const lrcSet = new Set() + let lrc = [] + let lrcT = [] + + for (const item of arr) { + if (lrcSet.has(item.time)) { + const tItem = lrc.pop() + tItem.time = lrc[lrc.length - 1].time + lrcT.push(tItem) + lrc.push(item) + } else { + lrc.push(item) + lrcSet.add(item.time) + } + } + + if (lrcT.length && lrc.length > lrcT.length) { + const tItem = lrc.pop() + tItem.time = lrc[lrc.length - 1].time + lrcT.push(tItem) + } + + return { + lrc, + lrcT, + } }, - getLyric(songId, isGetLyricx = false) { - const requestObj = httpFetch(`http://player.kuwo.cn/webmusic/st/getNewMuiseByRid?rid=MUSIC_${songId}`) - requestObj.promise = requestObj.promise.then(({ statusCode, body }) => { - console.log(body) - if (statusCode != 200) return Promise.reject(new Error(JSON.stringify(body))) - let info = this.parseLyricInfo(body) - if (!info) return Promise.reject(new Error(JSON.stringify(body))) - Object.assign(requestObj, httpFetch(`http://newlyric.kuwo.cn/newlyric.lrc?${isGetLyricx ? info.lyric_zz : info.lyric}`)) - return requestObj.promise.then(({ statusCode, body, raw }) => { - if (statusCode != 200) return Promise.reject(new Error(JSON.stringify(body))) - return decodeLyric({ lrcBase64: raw.toString('base64'), isGetLyricx }).then(base64Data => { - return { - lyric: Buffer.from(base64Data, 'base64').toString(), - tlyric: '', - } + transformLrc(songinfo, lrclist) { + return `[ti:${songinfo.name ?? ''}]\n[ar:${songinfo.singer ?? ''}]\n[al:${songinfo.albumName ?? ''}]\n[by:]\n[offset:0]\n${lrclist ? lrclist.map(l => `[${l.time}]${l.text}\n`).join('') : '暂无歌词'}` + }, + parseLrc(musicInfo, lrc) { + const lines = lrc.split(/\r\n|\r|\n/) + let lrcArr = [] + for (let i = 0; i < lines.length; i++) { + const line = lines[i].trim() + let result = timeExp.exec(line) + if (result) { + const text = line.replace(timeExp, '').trim() + lrcArr.push({ + time: RegExp.$1, + text, }) + } + } + const lrcInfo = this.sortLrcArr(lrcArr) + return { + lyric: decodeName(this.transformLrc(musicInfo, lrcInfo.lrc)), + tlyric: lrcInfo.lrcT.length ? decodeName(this.transformLrc(musicInfo, lrcInfo.lrcT)) : '', + } + }, + getLyric(musicInfo, isGetLyricx = false) { + const requestObj = httpFetch(`http://newlyric.kuwo.cn/newlyric.lrc?${buildParams(musicInfo.songmid, isGetLyricx)}`) + requestObj.promise = requestObj.promise.then(({ statusCode, body, raw }) => { + if (statusCode != 200) return Promise.reject(new Error(JSON.stringify(body))) + return decodeLyric({ lrcBase64: raw.toString('base64'), isGetLyricx }).then(base64Data => { + let lrcInfo + try { + lrcInfo = this.parseLrc(musicInfo, Buffer.from(base64Data, 'base64').toString()) + } catch { + return Promise.reject(new Error('Get lyric failed')) + } + // console.log(lrcInfo) + return lrcInfo }) }) return requestObj }, } - */ diff --git a/src/renderer/utils/music/kw/util.js b/src/renderer/utils/music/kw/util.js index aa7f42c3..a8b86c70 100644 --- a/src/renderer/utils/music/kw/util.js +++ b/src/renderer/utils/music/kw/util.js @@ -1,5 +1,5 @@ import { httpGet, httpFetch } from '../../request' -// import { rendererInvoke, NAMES } from '../../../../common/ipc' +import { rendererInvoke, NAMES } from '@common/ipc' const kw_token = { token: null, @@ -54,7 +54,7 @@ export const getToken = (retryNum = 0) => new Promise((resolve, reject) => { }) }) -// export const decodeLyric = base64Data => rendererInvoke(NAMES.mainWindow.handle_kw_decode_lyric, base64Data) +export const decodeLyric = base64Data => rendererInvoke(NAMES.mainWindow.handle_kw_decode_lyric, base64Data) export const tokenRequest = async(url, options = {}) => { let token = kw_token.token