refactor(sdk): musicSdk 全量迁移至 TypeScript

This commit is contained in:
snowy-yang committed 2026-08-29 00:23:50 +08:00
1 parent f289df4cd7
commit 1dfb7a59ca
83 files changed
+924 -732

No files matched your search

@@ -1,6 +1,7 @@
import { httpFetch } from '../request.js'
import { decodeName } from '../index.js'
import { formatSinger, objStr2JSON } from './util.js'
import { httpFetch } from '../request.ts'
import { decodeName } from '../index.ts'
import { formatSinger, objStr2JSON } from './util.ts'
import type { Quality } from '../types.ts'
// let requestObj_list
export default {
@@ -11,8 +12,8 @@ export default {
// console.log(rawList.length, rawList2.length)
return rawList.map((item, inedx) => {
let formats = item.formats.split('|')
let types = []
let _types = {}
let types: Array<{ type: Quality; size: string | null }> = []
let _types: Partial<Record<Quality, { size: string | null }>> = {}
if (formats.includes('MP3128')) {
types.push({ type: '128k', size: null })
_types['128k'] = {
@@ -71,9 +72,9 @@ export default {
* 格式化播放数量
* @param {*} num
*/
formatPlayCount(num) {
if (num > 100000000) return parseInt(num / 10000000) / 10 + '亿'
if (num > 10000) return parseInt(num / 1000) / 10 + '万'
formatPlayCount(num: any) {
if (num > 100000000) return parseInt((num / 10000000) as any) / 10 + '亿'
if (num > 10000) return parseInt((num / 1000) as any) / 10 + '万'
return num
},
getAlbumListDetail(id, page, retryNum = 0) {
@@ -1,9 +1,10 @@
import { httpFetch } from '../request.js'
import { dateFormat2 } from '../index.js'
import { httpFetch } from '../request.ts'
import { dateFormat2 } from '../index.ts'
import type { HttpRequestObject } from '../types.ts'
export default {
_requestObj: null,
_requestObj2: null,
_requestObj: null as HttpRequestObject | null,
_requestObj2: null as HttpRequestObject | null,
async getComment({ songmid }, page = 1, limit = 20) {
if (this._requestObj) this._requestObj.cancelHttp()
@@ -1,7 +1,8 @@
import { httpFetch } from '../request.js'
import { httpFetch } from '../request.ts'
import type { HttpRequestObject } from '../types.ts'
export default {
_requestObj: null,
_requestObj: null as HttpRequestObject | null,
async getList(retryNum = 0) {
if (this._requestObj) this._requestObj.cancelHttp()
if (retryNum > 2) return Promise.reject(new Error('try max num'))
+17 -16
View File
@@ -1,19 +1,20 @@
import { httpFetch } from '../request.js'
import tipSearch from './tipSearch.js'
import musicSearch from './musicSearch.js'
import { formatSinger } from './util.js'
import leaderboard from './leaderboard.js'
import lyric from './lyric.js'
import pic from './pic.js'
import { apis } from '../api-source.js'
import songList from './songList.js'
import hotSearch from './hotSearch.js'
import comment from './comment.js'
import { httpFetch } from '../request.ts'
import tipSearch from './tipSearch.ts'
import musicSearch from './musicSearch.ts'
import { formatSinger } from './util.ts'
import leaderboard from './leaderboard.ts'
import lyric from './lyric.ts'
import pic from './pic.ts'
import { apis } from '../api-source.ts'
import songList from './songList.ts'
import hotSearch from './hotSearch.ts'
import comment from './comment.ts'
import type { HttpRequestObject } from '../types.ts'
const kw = {
_musicInfoRequestObj: null,
_musicInfoRequestObj: null as HttpRequestObject | null,
_musicInfoPromiseCancelFn: null,
_musicPicRequestObj: null,
_musicPicRequestObj: null as HttpRequestObject | null,
_musicPicPromiseCancelFn: null,
// context: null,
@@ -60,19 +61,19 @@ const kw = {
},
getMusicUrl(songInfo, type) {
return apis('kw').getMusicUrl(songInfo, type)
return apis('kw').getMusicUrl!(songInfo, type)
},
getMusicInfo(songInfo) {
if (this._musicInfoRequestObj) this._musicInfoRequestObj.cancelHttp()
this._musicInfoRequestObj = httpFetch(`http://www.kuwo.cn/api/www/music/musicInfo?mid=${songInfo.songmid}`)
return this._musicInfoRequestObj.promise.then(({ body }) => {
return this._musicInfoRequestObj!.promise.then(({ body }) => {
return body.code === 200 ? body.data : Promise.reject(new Error(body.msg))
})
},
getMusicUrls(musicInfo, cb) {
let tasks = []
let tasks: Array<Promise<any>> = []
let songId = musicInfo.songmid
musicInfo.types.forEach(type => {
tasks.push(kw.getMusicUrl(songId, type.type).promise)
@@ -1,19 +1,20 @@
import { httpFetch } from '../request.js'
import { formatPlayTime, decodeName } from '../index.js'
import { formatSinger, wbdCrypto } from './util.js'
import { httpFetch } from '../request.ts'
import { formatPlayTime, decodeName } from '../index.ts'
import { formatSinger, wbdCrypto } from './util.ts'
import type { HttpRequestObject, Quality, QualityInfo, SongType } from '../types.ts'
const boardList = [{ id: 'kw__93', name: '飙升榜', bangid: '93' }, { id: 'kw__17', name: '新歌榜', bangid: '17' }, { id: 'kw__16', name: '热歌榜', bangid: '16' }, { id: 'kw__158', name: '抖音热歌榜', bangid: '158' }, { id: 'kw__292', name: '铃声榜', bangid: '292' }, { id: 'kw__284', name: '热评榜', bangid: '284' }, { id: 'kw__290', name: 'ACG新歌榜', bangid: '290' }, { id: 'kw__286', name: '台湾KKBOX榜', bangid: '286' }, { id: 'kw__279', name: '冬日暖心榜', bangid: '279' }, { id: 'kw__281', name: '巴士随身听榜', bangid: '281' }, { id: 'kw__255', name: 'KTV点唱榜', bangid: '255' }, { id: 'kw__280', name: '家务进行曲榜', bangid: '280' }, { id: 'kw__282', name: '熬夜修仙榜', bangid: '282' }, { id: 'kw__283', name: '枕边轻音乐榜', bangid: '283' }, { id: 'kw__278', name: '古风音乐榜', bangid: '278' }, { id: 'kw__264', name: 'Vlog音乐榜', bangid: '264' }, { id: 'kw__242', name: '电音榜', bangid: '242' }, { id: 'kw__187', name: '流行趋势榜', bangid: '187' }, { id: 'kw__204', name: '现场音乐榜', bangid: '204' }, { id: 'kw__186', name: 'ACG神曲榜', bangid: '186' }, { id: 'kw__185', name: '最强翻唱榜', bangid: '185' }, { id: 'kw__26', name: '经典怀旧榜', bangid: '26' }, { id: 'kw__104', name: '华语榜', bangid: '104' }, { id: 'kw__182', name: '粤语榜', bangid: '182' }, { id: 'kw__22', name: '欧美榜', bangid: '22' }, { id: 'kw__184', name: '韩语榜', bangid: '184' }, { id: 'kw__183', name: '日语榜', bangid: '183' }, { id: 'kw__145', name: '会员畅听榜', bangid: '145' }, { id: 'kw__153', name: '网红新歌榜', bangid: '153' }, { id: 'kw__64', name: '影视金曲榜', bangid: '64' }, { id: 'kw__176', name: 'DJ嗨歌榜', bangid: '176' }, { id: 'kw__106', name: '真声音', bangid: '106' }, { id: 'kw__12', name: 'Billboard榜', bangid: '12' }, { id: 'kw__49', name: 'iTunes音乐榜', bangid: '49' }, { id: 'kw__180', name: 'beatport电音榜', bangid: '180' }, { id: 'kw__13', name: '英国UK榜', bangid: '13' }, { id: 'kw__164', name: '百大DJ榜', bangid: '164' }, { id: 'kw__246', name: 'YouTube音乐排行榜', bangid: '246' }, { id: 'kw__265', name: '韩国Genie榜', bangid: '265' }, { id: 'kw__14', name: '韩国M-net榜', bangid: '14' }, { id: 'kw__8', name: '香港电台榜', bangid: '8' }, { id: 'kw__15', name: '日本公信榜', bangid: '15' }, { id: 'kw__151', name: '腾讯音乐人原创榜', bangid: '151' }]
const sortQualityArray = array => {
const sortQualityArray = (array: SongType[]): SongType[] => {
const qualityMap = {
flac24bit: 4,
flac: 3,
'320k': 2,
'128k': 1,
}
const rawQualityArray = []
const newQualityArray = []
const rawQualityArray: Array<{ type: number; index: number }> = []
const newQualityArray: SongType[] = []
array.forEach((item, index) => {
const type = qualityMap[item.type]
@@ -30,6 +31,12 @@ const sortQualityArray = array => {
return newQualityArray
}
interface BoardItem {
id: string
name: string
bangid: number | string
}
export default {
list: [
{
@@ -87,27 +94,27 @@ export default {
name: '日语榜',
bangid: 183,
},
],
] as BoardItem[],
// getUrl: (p, l, id) => `http://kbangserver.kuwo.cn/ksong.s?from=pc&fmt=json&pn=${p - 1}&rn=${l}&type=bang&data=content&id=${id}&show_copyright_off=0&pcmp4=1&isbang=1`,
regExps: {
mInfo: /level:(\w+),bitrate:(\d+),format:(\w+),size:([\w.]+)/,
},
limit: 100,
_requestBoardsObj: null,
_requestBoardsObj: null as HttpRequestObject | null,
getBoardsData() {
if (this._requestBoardsObj) this._requestBoardsObj.cancelHttp()
this._requestBoardsObj = httpFetch('http://qukudata.kuwo.cn/q.k?op=query&cont=tree&node=2&pn=0&rn=1000&fmt=json&level=2')
return this._requestBoardsObj.promise
return this._requestBoardsObj!.promise
},
getData(url) {
getData(url: string) {
const requestDataObj = httpFetch(url)
return requestDataObj.promise
},
filterData(rawList) {
return rawList.map(item => {
let types = []
const _types = {}
let types: SongType[] = []
const _types: Partial<Record<Quality, QualityInfo>> = {}
const qualitys = new Set()
item.n_minfo.split(';').forEach(i => {
@@ -161,7 +168,7 @@ export default {
filterBoardsData(rawList) {
// console.log(rawList)
let list = []
let list: any[] = []
for (const board of rawList) {
if (board.source != '1') continue
list.push({
+10 -10
View File
@@ -1,6 +1,6 @@
import { httpFetch } from '../request.js'
import { decodeLyric, lrcTools } from './util.js'
import { decodeName } from '../index.js'
import { httpFetch } from '../request.ts'
import { decodeLyric, lrcTools } from './util.ts'
import { decodeName } from '../index.ts'
/*
export default {
@@ -69,7 +69,7 @@ export default {
const buf_key = Buffer.from('yeelion')
const buf_key_len = buf_key.length
const buildParams = (id, isGetLyricx) => {
const buildParams = (id: string, isGetLyricx: boolean): string => {
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)
@@ -148,8 +148,8 @@ export default {
}, */
sortLrcArr(arr) {
const lrcSet = new Set()
let lrc = []
let lrcT = []
let lrc: any[] = []
let lrcT: any[] = []
let isLyricx = false
for (const item of arr) {
@@ -186,10 +186,10 @@ export default {
transformLrc(tags, lrclist) {
return `${tags.join('\n')}\n${lrclist ? lrclist.map(l => `[${l.time}]${l.text}\n`).join('') : '暂无歌词'}`
},
parseLrc(lrc) {
parseLrc(lrc: string) {
const lines = lrc.split(/\r\n|\r|\n/)
let tags = []
let lrcArr = []
let tags: string[] = []
let lrcArr: Array<{ time: string; text: string }> = []
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim()
let result = timeExp.exec(line)
@@ -238,7 +238,7 @@ export default {
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 => {
return decodeLyric({ lrcBase64: raw!.toString('base64'), isGetLyricx }).then(base64Data => {
// let lrcInfo
// try {
// lrcInfo = this.parseLrc(Buffer.from(base64Data, 'base64').toString())
@@ -1,9 +1,10 @@
// import '../../polyfill/array.find.js'
import { httpFetch } from '../request.js'
import { formatPlayTime, decodeName } from '../index.js'
import { httpFetch } from '../request.ts'
import { formatPlayTime, decodeName } from '../index.ts'
// import { debug } from '../../utils/env.js'
import { formatSinger } from './util.js'
import { formatSinger } from './util.ts'
import type { Quality, QualityInfo, SongInfo, SongType } from '../types.ts'
export default {
regExps: {
@@ -14,7 +15,7 @@ export default {
page: 0,
allPage: 1,
// cancelFn: null,
musicSearch(str, page, limit) {
musicSearch(str: string, page: number, limit: number) {
const musicSearchRequestObj = httpFetch(`http://search.kuwo.cn/r.s?client=kt&all=${encodeURIComponent(str)}&pn=${page - 1}&rn=${limit}&uid=794762570&ver=kwplayer_ar_9.2.2.1&vipver=1&show_copyright_off=1&newver=1&ft=music&cluster=0&strategy=2012&encoding=utf8&rformat=json&vermerge=1&mobi=1&issubtitle=1`)
return musicSearchRequestObj.promise
},
@@ -24,8 +25,8 @@ export default {
// getLrc(songId) {
// return httpGet(`http://mobile.kuwo.cn/mpage/html5/songinfoandlrc?mid=${songId}&flag=0`)
// },
handleResult(rawData) {
const result = []
handleResult(rawData: any) {
const result: SongInfo[] = []
if (!rawData) return result
// console.log(rawData)
for (let i = 0; i < rawData.length; i++) {
@@ -38,8 +39,8 @@ export default {
return null
}
const types = []
const _types = {}
const types: SongType[] = []
const _types: Partial<Record<Quality, QualityInfo>> = {}
let infoArr = info.N_MINFO.split(';')
for (let info of infoArr) {
@@ -99,7 +100,7 @@ export default {
// console.log(result)
return result
},
search(str, page = 1, limit, retryNum = 0) {
search(str: string, page = 1, limit?: number, retryNum = 0) {
if (retryNum > 2) return Promise.reject(new Error('try max num'))
if (limit == null) limit = this.limit
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
+3 -2
View File
@@ -1,7 +1,8 @@
import { httpFetch } from '../request.js'
import { httpFetch } from '../request.ts'
import type { SongInfo } from '../types.ts'
export default {
getPic({ songmid }) {
getPic({ songmid }: SongInfo) {
const requestObj = httpFetch(`http://artistpicserver.kuwo.cn/pic.web?corp=kuwo&type=rid_pic&pictype=500&size=500&rid=${songmid}`)
requestObj.promise = requestObj.promise.then(({ body }) => /^http/.test(body) ? body : null)
return requestObj.promise
@@ -1,12 +1,13 @@
import { httpFetch } from '../request.js'
import { formatPlayTime, decodeName } from '../index.js'
import { formatSinger, objStr2JSON } from './util.js'
import album from './album.js'
import { httpFetch } from '../request.ts'
import { formatPlayTime, decodeName } from '../index.ts'
import { formatSinger, objStr2JSON } from './util.ts'
import album from './album.ts'
import type { HttpRequestObject, Quality, QualityInfo, SongType } from '../types.ts'
export default {
_requestObj_tags: null,
_requestObj_hotTags: null,
_requestObj_list: null,
_requestObj_tags: null as HttpRequestObject | null,
_requestObj_hotTags: null as HttpRequestObject | null,
_requestObj_list: null as HttpRequestObject | null,
limit_list: 36,
limit_song: 1000,
successCode: 200,
@@ -28,7 +29,7 @@ export default {
},
tagsUrl: 'http://wapi.kuwo.cn/api/pc/classify/playlist/getTagList?cmd=rcm_keyword_playlist&user=0&prod=kwplayer_pc_9.0.5.0&vipver=9.0.5.0&source=kwplayer_pc_9.0.5.0&loginUid=0&loginSid=0&appUid=76039576',
hotTagUrl: 'http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmTagList?loginUid=0&loginSid=0&appUid=76039576',
getListUrl({ sortId, id, type, page }) {
getListUrl({ sortId, id, type, page }: { sortId: string; id: string | null; type: string; page: number }) {
if (!id) return `http://wapi.kuwo.cn/api/pc/classify/playlist/getRcmPlayList?loginUid=0&loginSid=0&appUid=76039576&&pn=${page}&rn=${this.limit_list}&order=${sortId}`
switch (type) {
case '10000': return `http://wapi.kuwo.cn/api/pc/classify/playlist/getTagPlayList?loginUid=0&loginSid=0&appUid=76039576&pn=${page}&id=${id}&rn=${this.limit_list}`
@@ -36,7 +37,7 @@ export default {
}
// http://wapi.kuwo.cn/api/pc/classify/playlist/getTagPlayList?loginUid=0&loginSid=0&appUid=76039576&id=173&pn=1&rn=100
},
getListDetailUrl(id, page) {
getListDetailUrl(id: string, page: number) {
// http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=2858093057&pn=0&rn=100&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1
return `http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=${id}&pn=${page - 1}&rn=${this.limit_song}&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1`
// http://mobileinterfaces.kuwo.cn/er.s?type=get_pc_qz_data&f=web&id=140&prod=pc
@@ -48,7 +49,7 @@ export default {
if (this._requestObj_tags) this._requestObj_tags.cancelHttp()
if (tryNum > 2) return Promise.reject(new Error('try max num'))
this._requestObj_tags = httpFetch(this.tagsUrl)
return this._requestObj_tags.promise.then(({ body }) => {
return this._requestObj_tags!.promise.then(({ body }) => {
if (body.code !== this.successCode) return this.getTag(++tryNum)
return this.filterTagInfo(body.data)
})
@@ -58,7 +59,7 @@ export default {
if (this._requestObj_hotTags) this._requestObj_hotTags.cancelHttp()
if (tryNum > 2) return Promise.reject(new Error('try max num'))
this._requestObj_hotTags = httpFetch(this.hotTagUrl)
return this._requestObj_hotTags.promise.then(({ body }) => {
return this._requestObj_hotTags!.promise.then(({ body }) => {
if (body.code !== this.successCode) return this.getHotTag(++tryNum)
return this.filterInfoHotTag(body.data[0].data)
})
@@ -84,20 +85,21 @@ export default {
},
// 获取列表数据
getList(sortId, tagId, page, tryNum = 0) {
getList(sortId: string, tagId: string | undefined, page: number, tryNum = 0) {
if (this._requestObj_list) this._requestObj_list.cancelHttp()
if (tryNum > 2) return Promise.reject(new Error('try max num'))
let id
let type
let id: string | null
let type: string
if (tagId) {
let arr = tagId.split('-')
id = arr[0]
type = arr[1]
type = arr[1] ?? ''
} else {
id = null
type = ''
}
this._requestObj_list = httpFetch(this.getListUrl({ sortId, id, type, page }))
return this._requestObj_list.promise.then(({ body }) => {
this._requestObj_list = httpFetch(this.getListUrl({ sortId, id, type, page } as any) as any)
return this._requestObj_list!.promise.then(({ body }) => {
if (!id || type == '10000') {
if (body.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum)
return {
@@ -125,9 +127,9 @@ export default {
* 格式化播放数量
* @param {*} num
*/
formatPlayCount(num) {
if (num > 100000000) return parseInt(num / 10000000) / 10 + '亿'
if (num > 10000) return parseInt(num / 1000) / 10 + '万'
formatPlayCount(num: any) {
if (num > 100000000) return parseInt((num / 10000000) as any) / 10 + '亿'
if (num > 10000) return parseInt((num / 1000) as any) / 10 + '万'
return num
},
filterList(rawData) {
@@ -146,7 +148,7 @@ export default {
},
filterList2(rawData) {
// console.log(rawData)
const list = []
const list: any[] = []
rawData.forEach(item => {
if (!item.label) return
list.push(...item.list.map(item => ({
@@ -225,8 +227,8 @@ export default {
filterBDListDetail(rawList) {
return rawList.map(item => {
let types = []
let _types = {}
let types: SongType[] = []
let _types: Partial<Record<Quality, QualityInfo>> = {}
for (let info of item.audios) {
info.size = info.size?.toLocaleUpperCase()
switch (info.bitrate) {
@@ -288,7 +290,7 @@ export default {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
plat: 'h5',
},
}).promise.catch(() => ({ code: 0 }))
}).promise.catch(() => ({ code: 0 } as any))
if (infoData.code != 200) return null
@@ -306,7 +308,7 @@ export default {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
plat: 'h5',
},
}).promise.catch(() => ({ code: 0 }))
}).promise.catch(() => ({ code: 0 } as any))
if (infoData.code != 200) return null
@@ -346,7 +348,7 @@ export default {
const source = /source=(\d+)/.exec(id)?.[1]
if (!listId) return Promise.reject(new Error('failed'))
const task = [this.getListDetailMusicListByBDList(listId, source, page)]
const task: Array<Promise<any>> = [this.getListDetailMusicListByBDList(listId, source, page)]
switch (source) {
case '4':
task.push(this.getListDetailMusicListByBDListInfo(listId, source))
@@ -392,8 +394,8 @@ export default {
// console.log(rawData)
return rawData.map(item => {
let infoArr = item.N_MINFO.split(';')
let types = []
let _types = {}
let types: SongType[] = []
let _types: Partial<Record<Quality, QualityInfo>> = {}
for (let info of infoArr) {
info = info.match(this.regExps.mInfo)
if (info) {
@@ -1,32 +1,35 @@
// import { decodeName } from '../index.js'
// import { tokenRequest } from './util.js'
import { httpFetch } from '../request.js'
// import { decodeName } from '../index.ts'
// import { tokenRequest } from './util.ts'
import { httpFetch } from '../request.ts'
import type { HttpRequestObject } from '../types.ts'
export default {
regExps: {
relWord: /RELWORD=(.+)/,
},
requestObj: null,
async tipSearchBySong(str) {
requestObj: null as HttpRequestObject | null,
async tipSearchBySong(str: string) {
// 报错403,加了referer还是有问题(直接换一个
// this.requestObj = await tokenRequest(`http://www.kuwo.cn/api/www/search/searchKey?key=${encodeURIComponent(str)}`)
this.cancelTipSearch()
this.requestObj = httpFetch(`https://tips.kuwo.cn/t.s?corp=kuwo&newver=3&p2p=1&notrace=0&c=mbox&w=${encodeURIComponent(str)}&encoding=utf8&rformat=json`, {
Referer: 'http://www.kuwo.cn/',
headers: {
Referer: 'http://www.kuwo.cn/',
},
})
return this.requestObj.promise.then(({ body, statusCode }) => {
return this.requestObj!.promise.then(({ body, statusCode }) => {
if (statusCode != 200 || !body.WORDITEMS) return Promise.reject(new Error('请求失败'))
return body.WORDITEMS
})
},
handleResult(rawData) {
handleResult(rawData: any) {
return rawData.map(item => item.RELWORD)
},
cancelTipSearch() {
if (this.requestObj && this.requestObj.cancelHttp) this.requestObj.cancelHttp()
},
async search(str) {
async search(str: string) {
return this.tipSearchBySong(str).then(result => this.handleResult(result))
},
}
+26 -18
View File
@@ -1,8 +1,8 @@
// import { httpGet, httpFetch } from '../request.js'
// import { httpGet, httpFetch } from '../request.ts'
import { WIN_MAIN_RENDERER_EVENT_NAME } from '../../src/common/ipcNames.js'
import { rendererInvoke } from '../../src/common/rendererIpc.js'
import { createCipheriv, createDecipheriv } from 'crypto'
import { toMD5 } from '../utils.js'
import { toMD5 } from '../utils.ts'
// const kw_token = {
// token: null,
@@ -30,14 +30,14 @@ import { toMD5 } from '../utils.js'
// return JSON.parse(str.replace(/(^{'|'}\n$|'}$|':'|','|':\[{'|'}\],'|':{'|'},'|'},{'|':\['|':\[\],'|':{},'|'}]})/g, s => translationMap[s]))
// }
export const objStr2JSON = str => {
export const objStr2JSON = (str: string): any => {
return JSON.parse(str.replace(/('(?=(,\s*')))|('(?=:))|((?<=([:,]\s*))')|((?<={)')|('(?=}))/g, '"'))
}
export const formatSinger = rawData => rawData.replace(/&/g, '、')
export const formatSinger = (rawData: string): string => rawData.replace(/&/g, '、')
export const matchToken = headers => {
export const matchToken = (headers: Record<string, any>): string | null => {
try {
return headers['set-cookie'][0].match(/kw_token=(\w+)/)[1]
} catch (err) {
@@ -63,7 +63,8 @@ export const matchToken = headers => {
// })
// })
export const decodeLyric = base64Data => rendererInvoke(WIN_MAIN_RENDERER_EVENT_NAME.handle_kw_decode_lyric, base64Data)
export const decodeLyric = (base64Data: { lrcBase64: string; isGetLyricx: boolean }): Promise<any> =>
rendererInvoke(WIN_MAIN_RENDERER_EVENT_NAME.handle_kw_decode_lyric, base64Data)
// export const tokenRequest = async(url, options = {}) => {
// let token = kw_token.token
@@ -86,6 +87,13 @@ export const decodeLyric = base64Data => rendererInvoke(WIN_MAIN_RENDERER_EVENT_
// return requestObj
// }
interface LrcWordInfo {
startTime: number
endTime: number
timeStr: string
newTimeStr?: string
}
export const lrcTools = {
rxps: {
wordLine: /^(\[\d{1,2}:.*\d{1,4}\])\s*(\S+(?:\s+\S+)*)?\s*/,
@@ -96,9 +104,9 @@ export const lrcTools = {
offset: 1,
offset2: 1,
isOK: false,
lines: [],
tags: [],
getWordInfo(str, str2, prevWord) {
lines: [] as string[],
tags: [] as string[],
getWordInfo(str: string, str2: string, prevWord?: LrcWordInfo): LrcWordInfo {
const offset = parseInt(str)
const offset2 = parseInt(str2)
let startTime = Math.abs((offset + offset2) / (this.offset * 2))
@@ -120,7 +128,7 @@ export const lrcTools = {
timeStr: `<${startTime},${endTime - startTime}>`,
}
},
parseLine(line) {
parseLine(line: string): void {
if (line.length < 6) return
let result = this.rxps.wordLine.exec(line)
if (result) {
@@ -135,7 +143,7 @@ export const lrcTools = {
let preTimeInfo
for (const timeStr of wordTimes) {
const result = this.rxps.wordTime.exec(timeStr)
const wordInfo = this.getWordInfo(result[1], result[2], preTimeInfo)
const wordInfo = this.getWordInfo(result![1], result![2], preTimeInfo)
words = words.replace(timeStr, wordInfo.timeStr)
if (preTimeInfo?.newTimeStr) words = words.replace(preTimeInfo.timeStr, preTimeInfo.newTimeStr)
preTimeInfo = wordInfo
@@ -160,7 +168,7 @@ export const lrcTools = {
this.tags.push(line)
}
},
parse(lrc) {
parse(lrc: string): string {
// console.log(lrc)
const lines = lrc.split(/\r\n|\r|\n/)
const tools = Object.create(this)
@@ -183,30 +191,30 @@ export const lrcTools = {
}
const createAesEncrypt = (buffer, mode, key, iv) => {
const createAesEncrypt = (buffer: Buffer, mode: string, key: Buffer | string, iv: string | Buffer): Buffer => {
const cipher = createCipheriv(mode, key, iv)
return Buffer.concat([cipher.update(buffer), cipher.final()])
}
const createAesDecrypt = (buffer, mode, key, iv) => {
const createAesDecrypt = (buffer: Buffer, mode: string, key: Buffer | string, iv: string | Buffer): Buffer => {
const cipher = createDecipheriv(mode, key, iv)
return Buffer.concat([cipher.update(buffer), cipher.final()])
}
export const wbdCrypto = {
aesMode: 'aes-128-ecb',
aesKey: Buffer.from([112, 87, 39, 61, 199, 250, 41, 191, 57, 68, 45, 114, 221, 94, 140, 228], 'binary'),
aesKey: Buffer.from([112, 87, 39, 61, 199, 250, 41, 191, 57, 68, 45, 114, 221, 94, 140, 228] as any, 'binary'),
aesIv: '',
appId: 'y67sprxhhpws',
decodeData(base64Result) {
decodeData(base64Result: string): any {
const data = Buffer.from(decodeURIComponent(base64Result), 'base64')
return JSON.parse(createAesDecrypt(data, this.aesMode, this.aesKey, this.aesIv).toString())
},
createSign(data, time) {
createSign(data: string, time: number): string {
const str = `${this.appId}${data}${time}`
return toMD5(str).toUpperCase()
},
buildParam(jsonData) {
buildParam(jsonData: unknown): string {
const data = Buffer.from(JSON.stringify(jsonData))
const time = Date.now()