修复lrcx下载和解析问题

This commit is contained in:
2023-02-10 13:16:59 +08:00
parent b436abe33d
commit 935dff81f9
4 changed files with 59 additions and 12 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "smart-lyric", "name": "smart-lyric",
"version": "1.0.1", "version": "1.0.2",
"description": "", "description": "",
"main": "dist/index.js", "main": "dist/index.js",
"types": "typing/index.d.ts", "types": "typing/index.d.ts",

View File

@ -2,6 +2,7 @@ import zlib from 'zlib'
import iconv from 'iconv-lite' import iconv from 'iconv-lite'
import { IKaraokeWord, ILyric, ILyricLine, LyricType } from './declare' import { IKaraokeWord, ILyric, ILyricLine, LyricType } from './declare'
import { genLyricTag, parseLyricTag } from './common' import { genLyricTag, parseLyricTag } from './common'
import { parse as parseLrc } from './lrc'
const KUWO_LYRIC_KEY = Buffer.from('yeelion') const KUWO_LYRIC_KEY = Buffer.from('yeelion')
@ -22,13 +23,20 @@ function cryptLRCX(buffer: Buffer) {
export function decrypt(buffer: Buffer) { export function decrypt(buffer: Buffer) {
try { try {
//解压 //解压
const b64Str = zlib.inflateSync(buffer).toString() const b64Buffer = zlib.inflateSync(buffer)
const b64Str = b64Buffer.toString()
//不需要解码
if (/\s*\[[a-z0-9A-z]+:/.test(b64Str)) return iconv.decode(b64Buffer, 'gb18030')
//进行解码
else {
//取得内容 //取得内容
const content = Buffer.from(b64Str, 'base64') const content = Buffer.from(b64Str, 'base64')
//解密 //解密
cryptLRCX(content) cryptLRCX(content)
//完成 //return
return iconv.decode(content, 'gb18030') return iconv.decode(content, 'gb18030')
}
//完成
} catch (err) { } catch (err) {
return null return null
} }
@ -54,6 +62,9 @@ export function encrypt(content: string | Buffer) {
* @param lrcxText LRCX歌词文本内容 * @param lrcxText LRCX歌词文本内容
*/ */
export function parse(lrcxText: string) { export function parse(lrcxText: string) {
//如果不是lrcx则按照lrc解析
if (!/^\[kuwo:\d+\]$/im.test(lrcxText)) return parseLrc(lrcxText)
//结果 //结果
const result: ILyric = { type: LyricType.KARA, content: [] } const result: ILyric = { type: LyricType.KARA, content: [] }

View File

@ -149,8 +149,18 @@ export async function downloadKugouLyric(option: IKugouLyricDownloadOption) {
/** 酷我音乐歌词下载选项 */ /** 酷我音乐歌词下载选项 */
interface IKuwoLyricDownloadOption { interface IKuwoLyricDownloadOption {
/** 歌词KEY */ /**
key: string * 歌曲ID
*
* 可以是数字组成的ID也可以是`MUSIC_\d+`
*/
musicID: string | number
/**
* 是否加载lrcx歌词 默认`true`
*
* 如果没有lrcx歌词返回的将是lrc歌词可以通过判断歌词中是否有`[kuwo:\d+]`来检测是不是lrcx歌词
*/
lrcx?: boolean
} }
/** /**
@ -158,8 +168,34 @@ interface IKuwoLyricDownloadOption {
* @param option 下载选项 * @param option 下载选项
*/ */
export async function downloadKuwoLyric(option: IKuwoLyricDownloadOption) { export async function downloadKuwoLyric(option: IKuwoLyricDownloadOption) {
const KUWO_KEY = Buffer.from('yeelion')
//加密歌词参数
const buildParams = (id: string | number, lrcx: boolean) => {
const rid = (typeof id == 'number' || /^\d+$/.test(id)) ? `MUSIC_${id}` : id
let params = `user=313928,MUSIC_9.1.1.8_W6,kwmusic_web_6 (1).exe,KwMusic&requester=localhost&req=1&rid=${rid}`
if (lrcx) params += '&lrcx=1&olrc=1'
const pBuffer = Buffer.from(params)
const output = new Uint16Array(pBuffer.byteLength)
for (let i = 0; i < pBuffer.byteLength; ++i) {
output[i] = KUWO_KEY[i % KUWO_KEY.length] ^ pBuffer[i]
}
return Buffer.from(output).toString('base64')
}
//测试解码
// const test = (buf: Buffer) => {
// const src = Uint16Array.from(buf)
// const out = Buffer.alloc(src.length)
// for (let i = 0; i < src.length; ++i) {
// out[i] = KUWO_KEY[i % KUWO_KEY.length] ^ src[i]
// }
// console.log(out + '')
// }
// test(Buffer.from(option.key, 'base64'))
//请求歌词 //请求歌词
let buffer = await request<Buffer>({ url: `http://newlyric.kuwo.cn/newlyric.lrc?${option.key}`, method: 'get' }) let buffer = await request<Buffer>({ url: `http://newlyric.kuwo.cn/newlyric.lrc?${buildParams(option.musicID, option.lrcx ?? true)}`, method: 'get' })
//读取基本信息(其实没有用),并得到歌词内容 //读取基本信息(其实没有用),并得到歌词内容
const baseInfo: any = {} const baseInfo: any = {}

View File

@ -13,7 +13,6 @@ async function test() {
// } // }
console.log('==============================测试qrc==========================================') console.log('==============================测试qrc==========================================')
await utils.downloadQQMusicLyric({ songID: 102878776 }).then(data => { await utils.downloadQQMusicLyric({ songID: 102878776 }).then(data => {
const lyric = qrc.parse(data!) const lyric = qrc.parse(data!)
console.log(lyric) console.log(lyric)
@ -29,7 +28,8 @@ async function test() {
console.log('==============================测试lrcx==========================================') console.log('==============================测试lrcx==========================================')
await utils.downloadKuwoLyric({ await utils.downloadKuwoLyric({
key: 'DBYAHlRcX0pcV1RFIjsqLCYzUEFfV1RLVDY4WFUOEgEcHAcaOhIJCzBYWU1URUcKFhxJLhskGh0QBkMeDB4bHBYRCRtSAhYGBAABAB0NQxcJGFJfWUMWAwcIABgIAFG9ra+40Z/dhKG8zKG1qE8OHA0MFhhU2qW5k9uRTx0HHVgoOTomLSZTUl9dX1tJU0MAGwwWRFRDAwUdDURU', musicID: 'MUSIC_67340506',
lrcx: true,
}).then(txt => { }).then(txt => {
const lyric = lrcx.parse(txt!) const lyric = lrcx.parse(txt!)
console.log(lyric) console.log(lyric)