增加kg歌单flac24bit显示&更新kg歌单api

This commit is contained in:
Folltoshe 2023-04-02 04:02:01 +08:00
parent 19549209d0
commit 01effc6691
3 changed files with 147 additions and 25 deletions

View File

@ -74,7 +74,7 @@ export default {
_requestBoardsObj: null, _requestBoardsObj: null,
getBoardsData() { getBoardsData() {
if (this._requestBoardsObj) this._requestBoardsObj.cancelHttp() if (this._requestBoardsObj) this._requestBoardsObj.cancelHttp()
this._requestBoardsObj = httpFetch('http://mobilecdnbj.kugou.com/api/v3/rank/list?version=9108&plat=0&showtype=2&parentid=0&apiver=6&area_code=1&withsong=1') this._requestBoardsObj = httpFetch('http://mobilecdnbj.kugou.com/api/v5/rank/list?version=9108&plat=0&showtype=2&parentid=0&apiver=6&area_code=1&withsong=1')
return this._requestBoardsObj.promise return this._requestBoardsObj.promise
}, },
getData(url) { getData(url) {

View File

@ -2,6 +2,7 @@ import { httpFetch } from '../../request'
import { decodeName, formatPlayTime, sizeFormate, dateFormat } from '../../index' import { decodeName, formatPlayTime, sizeFormate, dateFormat } from '../../index'
import { toMD5 } from '../utils' import { toMD5 } from '../utils'
import infSign from './vendors/infSign.min' import infSign from './vendors/infSign.min'
import { signatureWithUrl } from './util'
const handleSignature = (id, page, limit) => new Promise((resolve, reject) => { const handleSignature = (id, page, limit) => new Promise((resolve, reject) => {
infSign({ appid: 1058, type: 0, module: 'playlist', page, pagesize: limit, specialid: id }, null, { infSign({ appid: 1058, type: 0, module: 'playlist', page, pagesize: limit, specialid: id }, null, {
@ -52,6 +53,42 @@ export default {
// https://www.kugou.com/yy/special/single/1067062.html // https://www.kugou.com/yy/special/single/1067062.html
listDetailLink: /^.+\/(\d+)\.html(?:\?.*|&.*$|#.*$|$)/, listDetailLink: /^.+\/(\d+)\.html(?:\?.*|&.*$|#.*$|$)/,
}, },
async getGlobalSpecialID(special_id) {
return httpFetch(`https://m.kugou.com/plist/list/${special_id}/?json=true`, {
headers: {
'User-Agent': 'Mozilla/5.0 (Linux; Android 10; HLK-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Mobile Safari/537.36 EdgA/104.0.1293.70',
},
follow_max: 2,
}).promise.then(({ body }) => {
// console.log(body)
if (!body.info.list.global_specialid) Promise.reject(new Error('Failed to get global collection id.'))
return body.info.list.global_specialid
})
},
async getSpecialListInfo(special_id) {
return httpFetch(`https://m.kugou.com/plist/list/${special_id}/?json=true`, {
headers: {
'User-Agent': 'Mozilla/5.0 (Linux; Android 10; HLK-AL00) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Mobile Safari/537.36 EdgA/104.0.1293.70',
},
follow_max: 2,
}).promise.then(({ body }) => {
// console.log(body)
if (!body.info.list) Promise.reject(new Error('Failed to get list info.'))
let listinfo = body.info.list
return {
name: listinfo.specialname,
image: listinfo.imgurl.replace('{size}', '150'),
intro: listinfo.intro,
author: listinfo.nickname,
playcount: listinfo.playcount,
total: listinfo.songcount,
}
})
},
async getSongListDetailUrl(id, page, limit = 100) {
let gcid = await this.getGlobalSpecialID(id)
return signatureWithUrl(`http://pubsongscdn.tx.kugou.com/v2/get_other_list_file?specialid=0&need_sort=1&module=CloudMusic&clientver=11409&pagesize=${limit}&global_collection_id=${gcid}&userid=0&page=${page}&type=0&area_code=1&appid=1005`)
},
getInfoUrl(tagId) { getInfoUrl(tagId) {
return tagId return tagId
? `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_smarty=1&cdn=cdn&t=5&c=${tagId}` ? `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_smarty=1&cdn=cdn&t=5&c=${tagId}`
@ -61,9 +98,9 @@ export default {
if (tagId == null) tagId = '' if (tagId == null) tagId = ''
return `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_ajax=1&cdn=cdn&t=${sortId}&c=${tagId}&p=${page}` return `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_ajax=1&cdn=cdn&t=${sortId}&c=${tagId}&p=${page}`
}, },
getSongListDetailUrl(id) { // getSongListDetailUrl(id) {
return `http://www2.kugou.kugou.com/yueku/v9/special/single/${id}-5-9999.html` // return `http://www2.kugou.kugou.com/yueku/v9/special/single/${id}-5-9999.html`
}, // },
/** /**
* 格式化播放数量 * 格式化播放数量
@ -511,7 +548,7 @@ export default {
return this.getUserListDetailByLink(body, link) return this.getUserListDetailByLink(body, link)
}, },
getListDetail(id, page, tryNum = 0) { // 获取歌曲列表内的音乐 async getListDetail(id, page, tryNum = 0) { // 获取歌曲列表内的音乐
if (tryNum > 2) return Promise.reject(new Error('try max num')) if (tryNum > 2) return Promise.reject(new Error('try max num'))
id = id.toString() id = id.toString()
@ -525,33 +562,27 @@ export default {
} else if (id.startsWith('id_')) { } else if (id.startsWith('id_')) {
id = id.replace('id_', '') id = id.replace('id_', '')
} }
// if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1') // if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1')
const requestObj_listDetail = httpFetch(this.getSongListDetailUrl(id)) let link = await this.getSongListDetailUrl(id, page)
return requestObj_listDetail.promise.then(({ body }) => { const requestObj_listDetail = httpFetch(link)
let listData = body.match(this.regExps.listData) return requestObj_listDetail.promise.then(async({ body }) => {
let listInfo = body.match(this.regExps.listInfo) if (!body.data.info) return this.getListDetail(id, page, ++tryNum)
if (!listData) return this.getListDetail(id, page, ++tryNum) let listData = body.data.info
listData = this.filterData(JSON.parse(listData[1])) let listInfo = await this.getSpecialListInfo(id)
let name listData = this.filterDatav9(listData)
let pic
if (listInfo) {
name = listInfo[1]
pic = listInfo[2]
}
return { return {
list: listData, list: listData,
page: 1, page: 1,
limit: 10000, limit: 100,
total: listData.length, total: listData.total,
source: 'kg', source: 'kg',
info: { info: {
name, name: listInfo.name,
img: pic, img: listInfo.image,
// desc: body.result.info.list_desc, desc: listInfo.intro,
// author: body.result.info.userinfo.username, author: listInfo.author,
// play_count: this.formatPlayCount(body.result.listen_num), play_count: this.formatPlayCount(listInfo.playcount),
}, },
} }
}) })
@ -610,6 +641,67 @@ export default {
} }
}) })
}, },
getSinger(singers) {
let arr = []
singers.forEach(singer => {
arr.push(singer.name)
})
return arr.join('、')
},
// v9 API
filterDatav9(rawList) {
// console.log(rawList)
return rawList.map(item => {
const types = []
const _types = {}
item.relate_goods.forEach(qualityObj => {
if (qualityObj.level === 2) {
let size = sizeFormate(qualityObj.size)
types.push({ type: '128k', size, hash: qualityObj.hash })
_types['128k'] = {
size,
hash: qualityObj.hash,
}
} else if (qualityObj.level === 4) {
let size = sizeFormate(qualityObj.size)
types.push({ type: '320k', size, hash: qualityObj.hash })
_types['320k'] = {
size,
hash: qualityObj.hash,
}
} else if (qualityObj.level === 5) {
let size = sizeFormate(qualityObj.size)
types.push({ type: 'flac', size, hash: qualityObj.hash })
_types.flac = {
size,
hash: qualityObj.hash,
}
} else if (qualityObj.level === 6) {
let size = sizeFormate(qualityObj.size)
types.push({ type: 'flac24bit', size, hash: qualityObj.hash })
_types.flac24bit = {
size,
hash: qualityObj.hash,
}
}
})
return {
singer: this.getSinger(item.singerinfo),
name: decodeName(item.name.replace(this.getSinger(item.singerinfo) + ' - ', '')),
albumName: decodeName(item.albuminfo.name),
albumId: item.albuminfo.id,
songmid: item.audio_id,
source: 'kg',
interval: formatPlayTime(item.timelen / 1000),
img: null,
lrc: null,
hash: item.hash,
types,
_types,
typeUrl: {},
}
})
},
// hash list filter // hash list filter
filterData2(rawList) { filterData2(rawList) {

View File

@ -1,4 +1,5 @@
import { inflate } from 'zlib' import { inflate } from 'zlib'
import { toMD5 } from '../utils'
// https://github.com/lyswhut/lx-music-desktop/issues/296#issuecomment-683285784 // https://github.com/lyswhut/lx-music-desktop/issues/296#issuecomment-683285784
const enc_key = Buffer.from([0x40, 0x47, 0x61, 0x77, 0x5e, 0x32, 0x74, 0x47, 0x51, 0x36, 0x31, 0x2d, 0xce, 0xd2, 0x6e, 0x69], 'binary') const enc_key = Buffer.from([0x40, 0x47, 0x61, 0x77, 0x5e, 0x32, 0x74, 0x47, 0x51, 0x36, 0x31, 0x2d, 0xce, 0xd2, 0x6e, 0x69], 'binary')
@ -17,3 +18,32 @@ export const decodeLyric = str => new Promise((resolve, reject) => {
// s.content[0].lyricContent.forEach(([str]) => { // s.content[0].lyricContent.forEach(([str]) => {
// console.log(str) // console.log(str)
// }) // })
export const signature = (params, apiver = 9) => {
let keyparam = 'OIlwieks28dk2k092lksi2UIkp'
if (apiver === 5) keyparam = 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'
let param_list = params.split('&')
param_list.sort()
let sign_params = `${keyparam}${param_list.join('')}${keyparam}`
return toMD5(sign_params)
}
export const signatureWithParams = (params, apiver = 9) => {
let keyparam = 'OIlwieks28dk2k092lksi2UIkp'
if (apiver === 5) keyparam = 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'
let param_list = params.split('&')
param_list.sort()
let sign_params = `${keyparam}${param_list.join('')}${keyparam}`
return `${params}&signature=${toMD5(sign_params)}`
}
export const signatureWithUrl = (url, apiver = 9) => {
let keyparam = 'OIlwieks28dk2k092lksi2UIkp'
if (apiver === 5) keyparam = 'NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt'
let burl = url.split('?')[0]
let params = url.replace(burl, '').substring(1)
let param_list = params.split('&')
param_list.sort()
let sign_params = `${keyparam}${param_list.join('')}${keyparam}`
return `${url}&signature=${toMD5(sign_params)}`
}