diff --git a/publish/changeLog.md b/publish/changeLog.md index e42d4b0e..986aad14 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -16,6 +16,7 @@ - 尝试修复进度为0时仍然显示下载完成的问题 (#2471) - 修复TX源搜索失败 (#2575 @Folltoshe) +- 修复MG源歌单加载失败 ### 变更 diff --git a/src/renderer/utils/musicSdk/mg/lyric.js b/src/renderer/utils/musicSdk/mg/lyric.js index a93e62f5..55e27a56 100644 --- a/src/renderer/utils/musicSdk/mg/lyric.js +++ b/src/renderer/utils/musicSdk/mg/lyric.js @@ -96,52 +96,8 @@ const mrcTools = { } export default { - getLyricWeb(songInfo, tryNum = 0) { - // console.log(songInfo.copyrightId) - if (songInfo.lrcUrl) { - let requestObj = httpFetch(songInfo.lrcUrl) - requestObj.promise = requestObj.promise.then(({ body, statusCode }) => { - if (statusCode !== 200) { - if (tryNum > 5) return Promise.reject(new Error('歌词获取失败')) - let tryRequestObj = this.getLyricWeb(songInfo, ++tryNum) - requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj) - return tryRequestObj.promise - } - return { - lyric: body, - tlyric: '', - } - }) - return requestObj - } else { - let requestObj = httpFetch(`https://music.migu.cn/v3/api/music/audioPlayer/getLyric?copyrightId=${songInfo.copyrightId}`, { - headers: { - Referer: 'https://music.migu.cn/v3/music/player/audio?from=migu', - }, - }) - requestObj.promise = requestObj.promise.then(({ body }) => { - if (body.returnCode !== '000000' || !body.lyric) { - if (tryNum > 5) return Promise.reject(new Error('Get lyric failed')) - let tryRequestObj = this.getLyricWeb(songInfo, ++tryNum) - requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj) - return tryRequestObj.promise - } - return { - lyric: body.lyric, - tlyric: '', - } - }) - return requestObj - } - }, - getLyric(songInfo) { let requestObj = mrcTools.getLyric(songInfo) - requestObj.promise = requestObj.promise.catch(() => { - let webRequestObj = this.getLyricWeb(songInfo) - requestObj.cancelHttp = webRequestObj.cancelHttp.bind(webRequestObj) - return webRequestObj.promise - }) return requestObj }, } diff --git a/src/renderer/utils/musicSdk/mg/musicInfo.js b/src/renderer/utils/musicSdk/mg/musicInfo.js index 99aeeebc..4c2d9284 100644 --- a/src/renderer/utils/musicSdk/mg/musicInfo.js +++ b/src/renderer/utils/musicSdk/mg/musicInfo.js @@ -1,4 +1,4 @@ -import { sizeFormate } from '../../index' +import { sizeFormate, formatPlayTime } from '../../index' import { createHttpFetch } from './utils' import { formatSingerName } from '../utils' @@ -87,6 +87,72 @@ export const filterMusicInfoList = (rawList) => { return list } +export const filterMusicInfoListV5 = (rawList) => { + // console.log(rawList) + let ids = new Set() + const list = [] + rawList.forEach(item => { + if (!item.songId || ids.has(item.songId)) return + ids.add(item.songId) + const types = [] + const _types = {} + item.audioFormats?.forEach(type => { + let size + switch (type.formatType) { + case 'PQ': + size = sizeFormate(type.size ?? type.androidSize) + types.push({ type: '128k', size }) + _types['128k'] = { + size, + } + break + case 'HQ': + size = sizeFormate(type.size ?? type.androidSize) + types.push({ type: '320k', size }) + _types['320k'] = { + size, + } + break + case 'SQ': + size = sizeFormate(type.size ?? type.androidSize) + types.push({ type: 'flac', size }) + _types.flac = { + size, + } + break + case 'ZQ': + size = sizeFormate(type.size ?? type.androidSize) + types.push({ type: 'flac24bit', size }) + _types.flac24bit = { + size, + } + break + } + }) + + list.push({ + singer: formatSingerName(item.singerList, 'name'), + name: item.songName, + albumName: item.album, + albumId: item.albumId, + songmid: item.songId, + copyrightId: item.copyrightId, + source: 'mg', + interval: formatPlayTime(item.duration), + img: item.img3 || item.img2 || item.img1 || null, + lrc: null, + lrcUrl: item.lrcUrl, + mrcUrl: item.mrcUrl, + trcUrl: item.trcUrl, + otherSource: null, + types, + _types, + typeUrl: {}, + }) + }) + return list +} + export const getMusicInfo = async(copyrightId) => { return getMusicInfos([copyrightId]).then(data => data[0]) } diff --git a/src/renderer/utils/musicSdk/mg/songList.js b/src/renderer/utils/musicSdk/mg/songList.js index 71eeb1f4..67928171 100644 --- a/src/renderer/utils/musicSdk/mg/songList.js +++ b/src/renderer/utils/musicSdk/mg/songList.js @@ -1,6 +1,6 @@ import { httpFetch } from '../../request' -import { dateFormat, formatPlayCount } from '../../index' -import { filterMusicInfoList } from './musicInfo' +import { formatPlayCount } from '../../index' +import { filterMusicInfoListV5 } from './musicInfo' import { createSignature } from './musicSearch' import { createHttpFetch } from './utils/index' @@ -9,7 +9,7 @@ import { createHttpFetch } from './utils/index' export default { _requestObj_tags: null, _requestObj_list: null, - limit_list: 10, + limit_list: 30, limit_song: 50, successCode: '000000', cachedDetailInfo: {}, @@ -20,11 +20,11 @@ export default { id: '15127315', // id: '1', }, - { - name: '最新', - id: '15127272', - // id: '2', - }, + // { + // name: '最新', + // id: '15127272', + // // id: '2', + // }, ], regExps: { list: /
  • .+?<\/li>/g, @@ -33,7 +33,7 @@ export default { // https://music.migu.cn/v3/music/playlist/161044573?page=1 listDetailLink: /^.+\/playlist\/(\d+)(?:\?.*|&.*$|#.*$|$)/, }, - tagsUrl: 'https://app.c.nf.migu.cn/MIGUM3.0/v1.0/template/musiclistplaza-taglist/release', + tagsUrl: 'https://app.c.nf.migu.cn/pc/v1.0/template/musiclistplaza-taglist/release', // tagsUrl: 'https://app.c.nf.migu.cn/MIGUM2.0/v1.0/content/indexTagPage.do?needAll=0', getSongListUrl(sortId, tagId, page) { // if (tagId == null) { @@ -42,17 +42,20 @@ export default { // : `https://music.migu.cn/v3/music/playlist?sort=${sortId}&page=${page}&from=migu` // } // return `https://music.migu.cn/v3/music/playlist?tagId=${tagId}&page=${page}&from=migu` - if (tagId == null) { + if (!tagId) { // return `https://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=${this.limit_list}&start=${page}&templateVersion=5&type=1` // return `https://c.musicapp.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=${this.limit_list}&start=${page}&templateVersion=5&type=${sortId}` // https://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?count=50&start=2&templateVersion=5&type=1 - return `https://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&columnId=${sortId}&startIndex=${(page - 1) * 10}` + // return `https://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&columnId=${sortId}&startIndex=${(page - 1) * 10}` + return `https://app.c.nf.migu.cn/pc/bmw/page-data/playlist-square-recommend/v1.0?templateVersion=2&pageNo=${page}` } // return `https://app.c.nf.migu.cn/MIGUM2.0/v2.0/content/getMusicData.do?area=2&count=${this.limit_list}&start=${page}&tags=${tagId}&templateVersion=5&type=3` - return `https://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&tagId=${tagId}&startIndex=${(page - 1) * 10}` + return `https://app.c.nf.migu.cn/pc/v1.0/template/musiclistplaza-listbytag/release?pageNumber=${page}&templateVersion=2&tagId=${tagId}` + // return `https://m.music.migu.cn/migu/remoting/playlist_bycolumnid_tag?playListType=2&type=1&tagId=${tagId}&startIndex=${(page - 1) * 10}` }, getSongListDetailUrl(id, page) { - return `https://app.c.nf.migu.cn/MIGUM2.0/v1.0/user/queryMusicListSongs.do?musicListId=${id}&pageNo=${page}&pageSize=${this.limit_song}` + return `https://app.c.nf.migu.cn/MIGUM3.0/resource/playlist/song/v2.0?pageNo=${page}&pageSize=${this.limit_song}&playlistId=${id}` + // return `https://app.c.nf.migu.cn/MIGUM2.0/v1.0/user/queryMusicListSongs.do?musicListId=${id}&pageNo=${page}&pageSize=${this.limit_song}` }, defaultHeaders: { 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1', @@ -67,20 +70,20 @@ export default { if (tryNum > 2) return Promise.reject(new Error('try max num')) // https://h5.nf.migu.cn/app/v4/p/share/playlist/index.html?id=184187437&channel=0146921 - if (/playlist\/index\.html\?/.test(id)) { - id = id.replace(/.*(?:\?|&)id=(\d+)(?:&.*|$)/, '$1') - } else if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1') + // if (/playlist\/index\.html\?/.test(id)) { + // id = id.replace(/.*(?:\?|&)id=(\d+)(?:&.*|$)/, '$1') + // } else if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1') const requestObj_listDetail = httpFetch(this.getSongListDetailUrl(id, page), { headers: this.defaultHeaders }) return requestObj_listDetail.promise.then(({ body }) => { - if (body.code !== this.successCode) return this.getListDetail(id, page, ++tryNum) + if (body.code !== this.successCode) return this.getListDetailList(id, page, ++tryNum) // console.log(JSON.stringify(body)) // console.log(body) return { - list: filterMusicInfoList(body.list), + list: filterMusicInfoListV5(body.data.songList), page, limit: this.limit_song, - total: body.totalCount, + total: body.data.totalCount, source: 'mg', } }) @@ -130,8 +133,10 @@ export default { getListDetail(id, page, retryNum = 0) { // 获取歌曲列表内的音乐 // https://h5.nf.migu.cn/app/v4/p/share/playlist/index.html?id=184187437&channel=0146921 // http://c.migu.cn/00bTY6?ifrom=babddaadfde4ebeda289d671ab62f236 - if (/playlist\/index\.html\?/.test(id)) { - id = id.replace(/.*(?:\?|&)id=(\d+)(?:&.*|$)/, '$1') + // https://music.migu.cn/v5/#/playlist?playlistId=221573417 + if (/\/playlist[/?]/.test(id)) { + id = /(?:playlistId|id)=(\d+)/.exec(id)?.[1] + if (!id) throw new Error('list detail id parse failed') } else if (this.regExps.listDetailLink.test(id)) { id = id.replace(this.regExps.listDetailLink, '$1') } else if ((/[?&:/]/.test(id))) { @@ -184,42 +189,63 @@ export default { // } // }) // }) + // return this._requestObj_list.promise.then(({ body }) => { + // console.log(body) + // if (body.retCode !== '100000' || body.retMsg.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum) + // return { + // list: this.filterList(body.retMsg.playlist), + // total: parseInt(body.retMsg.countSize), + // page, + // limit: this.limit_list, + // source: 'mg', + // } + // }) return this._requestObj_list.promise.then(({ body }) => { // console.log(body) - if (body.retCode !== '100000' || body.retMsg.code !== this.successCode) return this.getList(sortId, tagId, page, ++tryNum) + // if (body.retCode !== '000000') return this.getList(sortId, tagId, page, ++tryNum) + if (body.code !== '000000') return this.getList(sortId, tagId, page, ++tryNum) + const list = body.data.contents ? this.filterList2(body.data.contents) : this.filterList(body.data.contentItemList[1].itemList) return { - list: this.filterList(body.retMsg.playlist), - total: parseInt(body.retMsg.countSize), + list, + total: 99999, page, limit: this.limit_list, source: 'mg', } }) - // return this._requestObj_list.promise.then(({ body }) => { - // if (body.retCode !== '100000') return this.getList(sortId, tagId, page, ++tryNum) - // // if (body.code !== '000000') return this.getList(sortId, tagId, page, ++tryNum) - // console.log(body) - // // return { - // // list: this.filterList(body.data.contentItemList[0].itemList), - // // total: parseInt(body.retMsg.countSize), - // // page, - // // limit: this.limit_list, - // // source: 'mg', - // // } - // }) + }, + filterList2(listData, list = [], ids = new Set()) { + for (const item of listData) { + if (item.contents) this.filterList2(item.contents, list, ids) + else if (item.resType == '2021' && !ids.has(item.resId)) { + ids.add(item.resId) + list.push({ + id: String(item.resId), + author: '', + name: item.txt, + // time: dateFormat(item.createTime, 'Y-M-D'), + img: item.img, + // grade: item.grade, + // total: item.contentCount, + desc: item.txt2, + source: 'mg', + }) + } + } + return list }, filterList(rawData) { // console.log(rawData) return rawData.map(item => ({ - play_count: formatPlayCount(item.playCount), - id: String(item.playListId), - author: item.createName, - name: item.playListName, - time: dateFormat(item.createTime, 'Y-M-D'), - img: item.image, - grade: item.grade, - total: item.contentCount, - desc: item.summary, + play_count: item.barList[0]?.title, + id: String(item.logEvent.contentId), + author: '', + name: item.title, + // time: dateFormat(item.createTime, 'Y-M-D'), + img: item.imageUrl, + // grade: item.grade, + // total: item.contentCount, + desc: '', source: 'mg', })) },