Skip to content

Commit 2039431

Browse files
update (#1791)
- 支持kw排行榜显示大小 - 支持某些kg逐行歌词 - 修复mg歌单搜索
1 parent 15c9207 commit 2039431

File tree

8 files changed

+152
-70
lines changed

8 files changed

+152
-70
lines changed

publish/changeLog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
### 优化
2+
- 不再丢弃kg源逐行歌词
3+
- 支持kw源排行榜显示大小(revert @Folltoshe #1460
4+
15
### 修复
26

37
- 修复某些情况下歌曲加载时间过长时不会自动跳到下一首的问题
48
- 修复mg歌词在某些情况下获取失败的问题(#1783
9+
- 修复mg歌单搜索
510

611
### 其他
712

src/renderer/utils/musicSdk/kg/lyric.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export default {
8989
// return requestObj
9090
// },
9191
searchLyric(name, hash, time, tryNum = 0) {
92-
let requestObj = httpFetch(`http://lyrics.kugou.com/search?ver=1&man=yes&client=pc&keyword=${encodeURIComponent(name)}&hash=${hash}&timelength=${time}`, {
92+
let requestObj = httpFetch(`http://lyrics.kugou.com/search?ver=1&man=yes&client=pc&keyword=${encodeURIComponent(name)}&hash=${hash}&timelength=${time}&lrctxt=1`, {
9393
headers: {
9494
'KG-RC': 1,
9595
'KG-THash': 'expand_search_manager.cpp:852736169:451',
@@ -105,14 +105,14 @@ export default {
105105
}
106106
if (body.candidates.length) {
107107
let info = body.candidates[0]
108-
return { id: info.id, accessKey: info.accesskey }
108+
return { id: info.id, accessKey: info.accesskey, fmt: (info.krctype == 1 && info.contenttype != 1) ? 'krc' : 'lrc' }
109109
}
110110
return null
111111
})
112112
return requestObj
113113
},
114-
getLyricDownload(id, accessKey, tryNum = 0) {
115-
let requestObj = httpFetch(`http://lyrics.kugou.com/download?ver=1&client=pc&id=${id}&accesskey=${accessKey}&fmt=krc&charset=utf8`, {
114+
getLyricDownload(id, accessKey, fmt, tryNum = 0) {
115+
let requestObj = httpFetch(`http://lyrics.kugou.com/download?ver=1&client=pc&id=${id}&accesskey=${accessKey}&fmt=${fmt}&charset=utf8`, {
116116
headers: {
117117
'KG-RC': 1,
118118
'KG-THash': 'expand_search_manager.cpp:852736169:451',
@@ -122,13 +122,26 @@ export default {
122122
requestObj.promise = requestObj.promise.then(({ body, statusCode }) => {
123123
if (statusCode !== 200) {
124124
if (tryNum > 5) return Promise.reject(new Error('歌词获取失败'))
125-
let tryRequestObj = this.getLyric(id, accessKey, ++tryNum)
125+
let tryRequestObj = this.getLyric(id, accessKey, fmt, ++tryNum)
126126
requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
127127
return tryRequestObj.promise
128128
}
129129

130-
return decodeLyric(body.content).then(result => parseLyric(result))
130+
switch (body.fmt) {
131+
case 'krc':
132+
return decodeLyric(body.content).then(result => parseLyric(result))
133+
case 'lrc':
134+
return {
135+
lyric: Buffer.from(body.content, 'base64').toString('utf-8'),
136+
tlyric: '',
137+
rlyric: '',
138+
lxlyric: '',
139+
}
140+
default:
141+
return Promise.reject(new Error(`未知歌词格式: ${body.fmt}`))
142+
}
131143
})
144+
132145
return requestObj
133146
},
134147
getLyric(songInfo, tryNum = 0) {
@@ -137,7 +150,7 @@ export default {
137150
requestObj.promise = requestObj.promise.then(result => {
138151
if (!result) return Promise.reject(new Error('Get lyric failed'))
139152

140-
let requestObj2 = this.getLyricDownload(result.id, result.accessKey)
153+
let requestObj2 = this.getLyricDownload(result.id, result.accessKey, result.fmt)
141154

142155
requestObj.cancelHttp = requestObj2.cancelHttp.bind(requestObj2)
143156

src/renderer/utils/musicSdk/kg/songList.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ export default {
456456
total -= limit
457457
page += 1
458458
const params = 'appid=1058&global_specialid=' + id + '&specialid=0&plat=0&version=8000&page=' + page + '&pagesize=' + limit + '&srcappid=2919&clientver=20000&clienttime=1586163263991&mid=1586163263991&uuid=1586163263991&dfid=-'
459-
tasks.push(this.createHttp(`https://mobiles.kugou.com/api/v5/special/song_v2?${params}&signature=${signatureParams(params, 5)}`, {
459+
tasks.push(this.createHttp(`https://mobiles.kugou.com/api/v5/special/song_v2?${params}&signature=${signatureParams(params, 'web')}`, {
460460
headers: {
461461
mid: '1586163263991',
462462
Referer: 'https://m3ws.kugou.com/share/index.php',
@@ -472,7 +472,7 @@ export default {
472472
let id = global_collection_id
473473
if (id.length > 1000) throw new Error('get list error')
474474
const params = 'appid=1058&specialid=0&global_specialid=' + id + '&format=jsonp&srcappid=2919&clientver=20000&clienttime=1586163242519&mid=1586163242519&uuid=1586163242519&dfid=-'
475-
let info = await this.createHttp(`https://mobiles.kugou.com/api/v5/special/info_v2?${params}&signature=${signatureParams(params, 5)}`, {
475+
let info = await this.createHttp(`https://mobiles.kugou.com/api/v5/special/info_v2?${params}&signature=${signatureParams(params, 'web')}`, {
476476
headers: {
477477
mid: '1586163242519',
478478
Referer: 'https://m3ws.kugou.com/share/index.php',

src/renderer/utils/musicSdk/kg/temp/songList-new.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ export default {
254254
if (this.collectionIdListInfoCache.has(id)) return this.collectionIdListInfoCache.get(id)
255255

256256
const params = `appid=1058&specialid=0&global_specialid=${id}&format=jsonp&srcappid=2919&clientver=20000&clienttime=1586163242519&mid=1586163242519&uuid=1586163242519&dfid=-`
257-
return createHttpFetch(`https://mobiles.kugou.com/api/v5/special/info_v2?${params}&signature=${signatureParams(params, 5)}`, {
257+
return createHttpFetch(`https://mobiles.kugou.com/api/v5/special/info_v2?${params}&signature=${signatureParams(params, 'web')}`, {
258258
headers: {
259259
mid: '1586163242519',
260260
Referer: 'https://m3ws.kugou.com/share/index.php',
@@ -321,7 +321,7 @@ export default {
321321
const listInfo = await this.getUserListInfoByCollectionId(id)
322322

323323
const params = `need_sort=1&module=CloudMusic&clientver=11589&pagesize=${limit}&global_collection_id=${id}&userid=0&page=${page}&type=0&area_code=1&appid=1005`
324-
return createHttpFetch(`http://pubsongs.kugou.com/v2/get_other_list_file?${params}&signature=${signatureParams(params, 2)}`, {
324+
return createHttpFetch(`http://pubsongs.kugou.com/v2/get_other_list_file?${params}&signature=${signatureParams(params, 'android')}`, {
325325
headers: {
326326
'User-Agent': 'Android10-AndroidPhone-11589-201-0-playlist-wifi',
327327
},
@@ -539,7 +539,7 @@ export default {
539539
total -= limit
540540
page += 1
541541
const params = 'appid=1058&global_specialid=' + id + '&specialid=0&plat=0&version=8000&page=' + page + '&pagesize=' + limit + '&srcappid=2919&clientver=20000&clienttime=1586163263991&mid=1586163263991&uuid=1586163263991&dfid=-'
542-
tasks.push(createHttpFetch(`https://mobiles.kugou.com/api/v5/special/song_v2?${params}&signature=${signatureParams(params, 5)}`, {
542+
tasks.push(createHttpFetch(`https://mobiles.kugou.com/api/v5/special/song_v2?${params}&signature=${signatureParams(params, 'web')}`, {
543543
headers: {
544544
mid: '1586163263991',
545545
Referer: 'https://m3ws.kugou.com/share/index.php',
@@ -555,7 +555,7 @@ export default {
555555
let id = global_collection_id
556556
if (id.length > 1000) throw new Error('get list error')
557557
const params = 'appid=1058&specialid=0&global_specialid=' + id + '&format=jsonp&srcappid=2919&clientver=20000&clienttime=1586163242519&mid=1586163242519&uuid=1586163242519&dfid=-'
558-
let info = await createHttpFetch(`https://mobiles.kugou.com/api/v5/special/info_v2?${params}&signature=${signatureParams(params, 5)}`, {
558+
let info = await createHttpFetch(`https://mobiles.kugou.com/api/v5/special/info_v2?${params}&signature=${signatureParams(params, 'web')}`, {
559559
headers: {
560560
mid: '1586163242519',
561561
Referer: 'https://m3ws.kugou.com/share/index.php',
@@ -760,7 +760,7 @@ export default {
760760

761761
search(text, page, limit = 20) {
762762
const params = `userid=1384394652&req_custom=1&appid=1005&req_multi=1&version=11589&page=${page}&filter=0&pagesize=${limit}&order=0&clienttime=1681779443&iscorrection=1&searchsong=0&keyword=${text}&mid=288799920684148686226285199951543865551&dfid=3eSBsO1u97EY1zeIZd40hH4p&clientver=11589&platform=AndroidFilter`
763-
const url = encodeURI(`http://complexsearchretry.kugou.com/v1/search/special?${params}&signature=${signatureParams(params, 1)}`)
763+
const url = encodeURI(`http://complexsearchretry.kugou.com/v1/search/special?${params}&signature=${signatureParams(params, 'android')}`)
764764
return createHttpFetch(url).then(body => {
765765
// console.log(body)
766766
return {

src/renderer/utils/musicSdk/kg/util.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ export const decodeLyric = str => new Promise((resolve, reject) => {
2525
* @param {*} params
2626
* @param {*} apiver
2727
*/
28-
export const signatureParams = (params, apiver = 9) => {
28+
export const signatureParams = (params, platform = 'android', body = '') => {
2929
let keyparam = 'OIlwieks28dk2k092lksi2UIkp'
30-
if (apiver === 5) keyparam = 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'
30+
if (platform === 'web') keyparam = 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'
3131
let param_list = params.split('&')
3232
param_list.sort()
33-
let sign_params = `${keyparam}${param_list.join('')}${keyparam}`
33+
let sign_params = `${keyparam}${param_list.join('')}${body}${keyparam}`
3434
return toMD5(sign_params)
3535
}
3636

src/renderer/utils/musicSdk/kw/leaderboard.js

Lines changed: 79 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,35 @@
11
import { httpFetch } from '../../request'
22
import { formatPlayTime, decodeName } from '../../index'
3-
import { formatSinger } from './util'
3+
import { formatSinger, wbdCrypto } from './util'
4+
45

56
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' }]
67

8+
const sortQualityArray = array => {
9+
const qualityMap = {
10+
flac24bit: 4,
11+
flac: 3,
12+
'320k': 2,
13+
'128k': 1,
14+
}
15+
const rawQualityArray = []
16+
const newQualityArray = []
17+
18+
array.forEach((item, index) => {
19+
const type = qualityMap[item.type]
20+
if (!type) return
21+
rawQualityArray.push({ type, index })
22+
})
23+
24+
rawQualityArray.sort((a, b) => a.type - b.type)
25+
26+
rawQualityArray.forEach(item => {
27+
newQualityArray.push(array[item.index])
28+
})
29+
30+
return newQualityArray
31+
}
32+
733
export default {
834
list: [
935
{
@@ -62,9 +88,9 @@ export default {
6288
bangid: 183,
6389
},
6490
],
65-
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`,
91+
// 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`,
6692
regExps: {
67-
93+
mInfo: /level:(\w+),bitrate:(\d+),format:(\w+),size:([\w.]+)/,
6894
},
6995
limit: 100,
7096
_requestBoardsObj: null,
@@ -79,57 +105,50 @@ export default {
79105
return requestDataObj.promise
80106
},
81107
filterData(rawList) {
82-
// console.log(rawList)
83-
// console.log(rawList.length, rawList2.length)
84-
return rawList.map((item, inedx) => {
85-
let formats = item.formats.split('|')
108+
return rawList.map(item => {
86109
let types = []
87-
let _types = {}
88-
if (formats.includes('MP3128')) {
89-
types.push({ type: '128k', size: null })
90-
_types['128k'] = {
91-
size: null,
92-
}
93-
}
94-
// if (formats.includes('MP3192')) {
95-
// types.push({ type: '192k', size: null })
96-
// _types['192k'] = {
97-
// size: null,
98-
// }
99-
// }
100-
if (formats.includes('MP3H')) {
101-
types.push({ type: '320k', size: null })
102-
_types['320k'] = {
103-
size: null,
104-
}
105-
}
106-
// if (formats.includes('AL')) {
107-
// types.push({ type: 'ape', size: null })
108-
// _types.ape = {
109-
// size: null,
110-
// }
111-
// }
112-
if (formats.includes('ALFLAC')) {
113-
types.push({ type: 'flac', size: null })
114-
_types.flac = {
115-
size: null,
116-
}
117-
}
118-
if (formats.includes('HIRFLAC')) {
119-
types.push({ type: 'flac24bit', size: null })
120-
_types.flac24bit = {
121-
size: null,
110+
const _types = {}
111+
const qualitys = new Set()
112+
113+
item.n_minfo.split(';').forEach(i => {
114+
const info = i.match(this.regExps.mInfo)
115+
if (!info) return
116+
117+
const quality = info[2]
118+
const size = info[4].toLocaleUpperCase()
119+
120+
if (qualitys.has(quality)) return
121+
qualitys.add(quality)
122+
123+
switch (quality) {
124+
case '4000':
125+
types.push({ type: 'flac24bit', size })
126+
_types.flac24bit = { size }
127+
break
128+
case '2000':
129+
types.push({ type: 'flac', size })
130+
_types.flac = { size }
131+
break
132+
case '320':
133+
types.push({ type: '320k', size })
134+
_types['320k'] = { size }
135+
break
136+
case '128':
137+
types.push({ type: '128k', size })
138+
_types['128k'] = { size }
139+
break
122140
}
123-
}
124-
// types.reverse()
141+
})
142+
types = sortQualityArray(types)
143+
125144
return {
126145
singer: formatSinger(decodeName(item.artist)),
127146
name: decodeName(item.name),
128147
albumName: decodeName(item.album),
129-
albumId: item.albumid,
148+
albumId: item.albumId,
130149
songmid: item.id,
131150
source: 'kw',
132-
interval: formatPlayTime(parseInt(item.song_duration)),
151+
interval: formatPlayTime(parseInt(item.duration)),
133152
img: item.pic,
134153
lrc: null,
135154
otherSource: null,
@@ -180,12 +199,20 @@ export default {
180199

181200
getList(id, page, retryNum = 0) {
182201
if (++retryNum > 3) return Promise.reject(new Error('try max num'))
183-
return this.getData(this.getUrl(page, this.limit, id)).then(({ statusCode, body }) => {
184-
// console.log(body)
185-
if (statusCode !== 200 || !body.musiclist) return this.getList(id, page, retryNum)
186-
// console.log(data1.musiclist, data2.data)
187-
let total = parseInt(body.num)
188-
let list = this.filterData(body.musiclist)
202+
203+
const requestBody = { uid: '', devId: '', sFrom: 'kuwo_sdk', user_type: 'AP', carSource: 'kwplayercar_ar_6.0.1.0_apk_keluze.apk', id, pn: page - 1, rn: this.limit }
204+
const requestUrl = `https://wbd.kuwo.cn/api/bd/bang/bang_info?${wbdCrypto.buildParam(requestBody)}`
205+
const request = httpFetch(requestUrl).promise
206+
207+
return request.then(({ statusCode, body }) => {
208+
const rawData = wbdCrypto.decodeData(body)
209+
// console.log(rawData)
210+
const data = rawData.data
211+
if (statusCode !== 200 || rawData.code != 200 || !data.musiclist) return this.getList(id, page, retryNum)
212+
213+
const total = parseInt(data.total)
214+
const list = this.filterData(data.musiclist)
215+
189216
return {
190217
total,
191218
list,

src/renderer/utils/musicSdk/kw/util.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// import { httpGet, httpFetch } from '../../request'
22
import { WIN_MAIN_RENDERER_EVENT_NAME } from '@common/ipcNames'
33
import { rendererInvoke } from '@common/rendererIpc'
4+
import { createCipheriv, createDecipheriv } from 'crypto'
5+
import { toMD5 } from '../utils'
46

57
// const kw_token = {
68
// token: null,
@@ -179,3 +181,38 @@ export const lrcTools = {
179181
return lrcs
180182
},
181183
}
184+
185+
186+
const createAesEncrypt = (buffer, mode, key, iv) => {
187+
const cipher = createCipheriv(mode, key, iv)
188+
return Buffer.concat([cipher.update(buffer), cipher.final()])
189+
}
190+
191+
const createAesDecrypt = (buffer, mode, key, iv) => {
192+
const cipher = createDecipheriv(mode, key, iv)
193+
return Buffer.concat([cipher.update(buffer), cipher.final()])
194+
}
195+
196+
export const wbdCrypto = {
197+
aesMode: 'aes-128-ecb',
198+
aesKey: Buffer.from([112, 87, 39, 61, 199, 250, 41, 191, 57, 68, 45, 114, 221, 94, 140, 228], 'binary'),
199+
aesIv: '',
200+
appId: 'y67sprxhhpws',
201+
decodeData(base64Result) {
202+
const data = Buffer.from(decodeURIComponent(base64Result), 'base64')
203+
return JSON.parse(createAesDecrypt(data, this.aesMode, this.aesKey, this.aesIv).toString())
204+
},
205+
createSign(data, time) {
206+
const str = `${this.appId}${data}${time}`
207+
return toMD5(str).toUpperCase()
208+
},
209+
buildParam(jsonData) {
210+
const data = Buffer.from(JSON.stringify(jsonData))
211+
const time = Date.now()
212+
213+
const encodeData = createAesEncrypt(data, this.aesMode, this.aesKey, this.aesIv).toString('base64')
214+
const sign = this.createSign(encodeData, time)
215+
216+
return `data=${encodeURIComponent(encodeData)}&time=${time}&appId=${this.appId}&sign=${sign}`
217+
},
218+
}

src/renderer/utils/musicSdk/mg/songList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export default {
308308
search(text, page, limit = 20) {
309309
const timeStr = Date.now().toString()
310310
const signResult = createSignature(timeStr, text)
311-
return createHttpFetch(`https://jadeite.migu.cn/music_search/v3/search/searchAll?isCorrect=1&isCopyright=1&searchSwitch=%7B%22song%22%3A0%2C%22album%22%3A0%2C%22singer%22%3A0%2C%22tagSong%22%3A0%2C%22mvSong%22%3A0%2C%22bestShow%22%3A0%2C%22songlist%22%3A1%2C%22lyricSong%22%3A0%7D&pageSize=${limit}&text=${encodeURIComponent(text)}&pageNo=${page}&sort=0`, {
311+
return createHttpFetch(`https://jadeite.migu.cn/music_search/v3/search/searchAll?isCorrect=1&isCopyright=1&searchSwitch=%7B%22song%22%3A0%2C%22album%22%3A0%2C%22singer%22%3A0%2C%22tagSong%22%3A0%2C%22mvSong%22%3A0%2C%22bestShow%22%3A0%2C%22songlist%22%3A1%2C%22lyricSong%22%3A0%7D&pageSize=${limit}&text=${encodeURIComponent(text)}&pageNo=${page}&sort=0&sid=USS`, {
312312
headers: {
313313
uiVersion: 'A_music_3.6.1',
314314
deviceId: signResult.deviceId,

0 commit comments

Comments
 (0)