From 1f77b3dd4b8f35c1a0acccca66e9527c923cc834 Mon Sep 17 00:00:00 2001 From: lyswhut Date: Mon, 30 Sep 2019 13:04:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EQQ=E9=9F=B3=E4=B9=90=E6=BA=90?= =?UTF-8?q?=E6=AD=8C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 4 + src/renderer/utils/music/tx/index.js | 2 + src/renderer/utils/music/tx/songList.js | 259 ++++++++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 src/renderer/utils/music/tx/songList.js diff --git a/publish/changeLog.md b/publish/changeLog.md index ffd26909..f9beeeed 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,3 +1,7 @@ +#### 新增 + +- 新增QQ音乐源歌单 + #### 修复 - 修正火影皮肤名字 diff --git a/src/renderer/utils/music/tx/index.js b/src/renderer/utils/music/tx/index.js index 54959c8f..88bce30a 100644 --- a/src/renderer/utils/music/tx/index.js +++ b/src/renderer/utils/music/tx/index.js @@ -1,9 +1,11 @@ import leaderboard from './leaderboard' import lyric from './lyric' +import songList from './songList' import api_source from '../api-source' const tx = { leaderboard, + songList, getMusicUrl(songInfo, type) { return api_source('tx').getMusicUrl(songInfo, type) diff --git a/src/renderer/utils/music/tx/songList.js b/src/renderer/utils/music/tx/songList.js new file mode 100644 index 00000000..3d3d74cd --- /dev/null +++ b/src/renderer/utils/music/tx/songList.js @@ -0,0 +1,259 @@ +import { httpFetch } from '../../request' +import { formatPlayTime, sizeFormate } from '../../index' + +export default { + _requestObj_tags: null, + _requestObj_hotTags: null, + _requestObj_list: null, + _requestObj_listDetail: null, + limit_list: 36, + limit_song: 10000000, + successCode: 0, + sortList: [ + { + name: '最热', + id: 5, + }, + { + name: '最新', + id: 2, + }, + ], + regexps: { + hotTagHtml: /class="c_bg_link js_tag_item" data-id="\w+">.+?<\/a>/g, + hotTag: /data-id="(\w+)">(.+?)<\/a>/, + }, + tagsUrl: 'https://u.y.qq.com/cgi-bin/musicu.fcg?loginUin=0&hostUin=0&format=json&inCharset=utf-8&outCharset=utf-8¬ice=0&platform=wk_v15.json&needNewCode=0&data=%7B%22tags%22%3A%7B%22method%22%3A%22get_all_categories%22%2C%22param%22%3A%7B%22qq%22%3A%22%22%7D%2C%22module%22%3A%22playlist.PlaylistAllCategoriesServer%22%7D%7D', + hotTagUrl: 'https://c.y.qq.com/node/pc/wk_v15/category_playlist.html', + getListUrl(sortId, id, page) { + return id ? `https://u.y.qq.com/cgi-bin/musicu.fcg?loginUin=0&hostUin=0&format=json&inCharset=utf-8&outCharset=utf-8¬ice=0&platform=wk_v15.json&needNewCode=0&data=${encodeURIComponent(JSON.stringify({ + comm: { cv: 1602, ct: 20 }, + playlist: { + method: 'get_category_content', + param: { + titleid: id, + caller: '0', + category_id: id, + size: this.limit_list, + page: page - 1, + use_page: page - 1, + }, + module: 'playlist.PlayListCategoryServer', + }, + }))}` : `https://u.y.qq.com/cgi-bin/musicu.fcg?loginUin=0&hostUin=0&format=json&inCharset=utf-8&outCharset=utf-8¬ice=0&platform=wk_v15.json&needNewCode=0&data=${encodeURIComponent(JSON.stringify({ + comm: { cv: 1602, ct: 20 }, + playlist: { + method: 'get_playlist_by_tag', + param: { id: 10000000, sin: 0, size: this.limit_list, order: sortId, cur_page: page }, + module: 'playlist.PlayListPlazaServer', + }, + }))}` + }, + getListDetailUrl(id) { + return `https://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?type=1&json=1&utf8=1&onlysong=0&new_format=1&disstid=${id}&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0` + }, + + // http://nplserver.kuwo.cn/pl.svc?op=getlistinfo&pid=2849349915&pn=0&rn=100&encode=utf8&keyset=pl2012&identity=kuwo&pcmp4=1&vipver=MUSIC_9.0.5.0_W1&newver=1 + // 获取标签 + getTag() { + if (this._requestObj_tags) this._requestObj_tags.cancelHttp() + this._requestObj_tags = httpFetch(this.tagsUrl) + return this._requestObj_tags.promise.then(({ body }) => { + if (body.code !== this.successCode) return this.getTag() + return this.filterTagInfo(body.tags.data.v_group) + }) + }, + // 获取标签 + getHotTag() { + if (this._requestObj_hotTags) this._requestObj_hotTags.cancelHttp() + this._requestObj_hotTags = httpFetch(this.hotTagUrl) + return this._requestObj_hotTags.promise.then(({ statusCode, body }) => { + if (statusCode !== 200) return this.getHotTag() + return this.filterInfoHotTag(body) + }) + }, + filterInfoHotTag(html) { + let hotTag = html.match(this.regexps.hotTagHtml) + const hotTags = [] + if (!hotTag) return hotTags + + hotTag.forEach(tagHtml => { + let result = tagHtml.match(this.regexps.hotTag) + if (!result) return + hotTags.push({ + id: result[1], + name: result[2], + source: 'tx', + }) + }) + return hotTags + }, + filterTagInfo(rawList) { + return rawList.map(type => ({ + name: type.group_name, + list: type.v_item.map(item => ({ + parent_id: type.group_id, + parent_name: type.group_name, + id: item.id, + name: item.name, + source: 'tx', + })), + })) + }, + + // 获取列表数据 + getList(sortId, tagId, page) { + if (this._requestObj_list) this._requestObj_list.cancelHttp() + this._requestObj_list = httpFetch( + this.getListUrl(sortId, tagId, page) + ) + return this._requestObj_list.promise.then(({ body }) => { + if (body.code !== this.successCode) return this.getList(sortId, tagId, page) + return tagId ? this.filterList2(body.playlist.data, page) : this.filterList(body.playlist.data, page) + }) + }, + + + /** + * 格式化播放数量 + * @param {*} num + */ + formatPlayCount(num) { + if (num > 100000000) return parseInt(num / 10000000) / 10 + '亿' + if (num > 10000) return parseInt(num / 1000) / 10 + '万' + return num + }, + filterList(data, page) { + return { + list: data.v_playlist.map(item => ({ + play_count: this.formatPlayCount(item.access_num), + id: item.tid, + author: item.creator_info.nick, + name: item.title, + // time: item.publish_time, + img: item.cover_url_medium, + // grade: item.favorcnt / 10, + desc: item.desc, + source: 'tx', + })), + total: data.total, + page, + limit: this.limit_list, + source: 'tx', + } + }, + filterList2({ content }, page) { + // console.log(content.v_item) + return { + list: content.v_item.map(({ basic }) => ({ + play_count: this.formatPlayCount(basic.play_cnt), + id: basic.tid, + author: basic.creator.nick, + name: basic.title, + // time: basic.publish_time, + img: basic.cover.medium_url || basic.cover.default_url, + // grade: basic.favorcnt / 10, + desc: basic.desc.replace(/
/g, '\n'), + source: 'tx', + })), + total: content.total_cnt, + page, + limit: this.limit_list, + source: 'tx', + } + }, + + // 获取歌曲列表内的音乐 + getListDetail(id) { + if (this._requestObj_listDetail) { + this._requestObj_listDetail.cancelHttp() + } + this._requestObj_listDetail = httpFetch(this.getListDetailUrl(id), { + headers: { + Origin: 'https://y.qq.com', + Referer: `https://y.qq.com/n/yqq/playsquare/${id}.html`, + }, + }) + return this._requestObj_listDetail.promise.then(({ body }) => { + if (body.code !== this.successCode) return this.getListDetail(id) + const cdlist = body.cdlist[0] + return { + list: this.filterListDetail(cdlist.songlist), + page: 1, + limit: cdlist.songlist.length + 1, + total: cdlist.songlist.length, + desc: cdlist.desc.replace(/
/g, '\n'), + source: 'tx', + } + }) + }, + getSinger(singers) { + let arr = [] + singers.forEach(singer => { + arr.push(singer.name) + }) + return arr.join('、') + }, + filterListDetail(rawList) { + // console.log(rawList) + return rawList.map(item => { + let types = [] + let _types = {} + if (item.file.size_128mp3 !== 0) { + let size = sizeFormate(item.file.size_128mp3) + types.push({ type: '128k', size }) + _types['128k'] = { + size, + } + } + if (item.file.size_320mp3 !== 0) { + let size = sizeFormate(item.file.size_320mp3) + types.push({ type: '320k', size }) + _types['320k'] = { + size, + } + } + if (item.file.size_ape !== 0) { + let size = sizeFormate(item.file.size_ape) + types.push({ type: 'ape', size }) + _types.ape = { + size, + } + } + if (item.file.size_flac !== 0) { + let size = sizeFormate(item.file.size_flac) + types.push({ type: 'flac', size }) + _types.flac = { + size, + } + } + // types.reverse() + return { + singer: this.getSinger(item.singer), + name: item.title, + albumName: item.album.title, + albumId: item.album.mid, + source: 'tx', + interval: formatPlayTime(item.interval), + songId: item.id, + albumMid: item.album.mid, + strMediaMid: item.file.media_mid, + songmid: item.mid, + img: (item.album.name === '' || item.album.name === '空') + ? `https://y.gtimg.cn/music/photo_new/T001R500x500M000${item.singer[0].mid}.jpg` + : `https://y.gtimg.cn/music/photo_new/T002R500x500M000${item.album.mid}.jpg`, + lrc: null, + types, + _types, + typeUrl: {}, + } + }) + }, + getTags() { + return Promise.all([this.getTag(), this.getHotTag()]).then(([tags, hotTag]) => ({ tags, hotTag })) + }, +} + +// getList +// getTags +// getListDetail