修复MG源歌单加载失败

This commit is contained in:
lyswhut
2025-11-26 13:41:22 +08:00
parent d54bc21441
commit 0c71772953
4 changed files with 139 additions and 90 deletions
+1
View File
@@ -16,6 +16,7 @@
- 尝试修复进度为0时仍然显示下载完成的问题 (#2471) - 尝试修复进度为0时仍然显示下载完成的问题 (#2471)
- 修复TX源搜索失败 (#2575 @Folltoshe) - 修复TX源搜索失败 (#2575 @Folltoshe)
- 修复MG源歌单加载失败
### 变更 ### 变更
-44
View File
@@ -96,52 +96,8 @@ const mrcTools = {
} }
export default { 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) { getLyric(songInfo) {
let requestObj = mrcTools.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 return requestObj
}, },
} }
+67 -1
View File
@@ -1,4 +1,4 @@
import { sizeFormate } from '../../index' import { sizeFormate, formatPlayTime } from '../../index'
import { createHttpFetch } from './utils' import { createHttpFetch } from './utils'
import { formatSingerName } from '../utils' import { formatSingerName } from '../utils'
@@ -87,6 +87,72 @@ export const filterMusicInfoList = (rawList) => {
return list 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) => { export const getMusicInfo = async(copyrightId) => {
return getMusicInfos([copyrightId]).then(data => data[0]) return getMusicInfos([copyrightId]).then(data => data[0])
} }
+71 -45
View File
@@ -1,6 +1,6 @@
import { httpFetch } from '../../request' import { httpFetch } from '../../request'
import { dateFormat, formatPlayCount } from '../../index' import { formatPlayCount } from '../../index'
import { filterMusicInfoList } from './musicInfo' import { filterMusicInfoListV5 } from './musicInfo'
import { createSignature } from './musicSearch' import { createSignature } from './musicSearch'
import { createHttpFetch } from './utils/index' import { createHttpFetch } from './utils/index'
@@ -9,7 +9,7 @@ import { createHttpFetch } from './utils/index'
export default { export default {
_requestObj_tags: null, _requestObj_tags: null,
_requestObj_list: null, _requestObj_list: null,
limit_list: 10, limit_list: 30,
limit_song: 50, limit_song: 50,
successCode: '000000', successCode: '000000',
cachedDetailInfo: {}, cachedDetailInfo: {},
@@ -20,11 +20,11 @@ export default {
id: '15127315', id: '15127315',
// id: '1', // id: '1',
}, },
{ // {
name: '最新', // name: '最新',
id: '15127272', // id: '15127272',
// id: '2', // // id: '2',
}, // },
], ],
regExps: { regExps: {
list: /<li><div class="thumb">.+?<\/li>/g, list: /<li><div class="thumb">.+?<\/li>/g,
@@ -33,7 +33,7 @@ export default {
// https://music.migu.cn/v3/music/playlist/161044573?page=1 // https://music.migu.cn/v3/music/playlist/161044573?page=1
listDetailLink: /^.+\/playlist\/(\d+)(?:\?.*|&.*$|#.*$|$)/, 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', // tagsUrl: 'https://app.c.nf.migu.cn/MIGUM2.0/v1.0/content/indexTagPage.do?needAll=0',
getSongListUrl(sortId, tagId, page) { getSongListUrl(sortId, tagId, page) {
// if (tagId == null) { // if (tagId == null) {
@@ -42,17 +42,20 @@ export default {
// : `https://music.migu.cn/v3/music/playlist?sort=${sortId}&page=${page}&from=migu` // : `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` // 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://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}` // 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 // 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://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) { 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: { 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', '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')) 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 // https://h5.nf.migu.cn/app/v4/p/share/playlist/index.html?id=184187437&channel=0146921
if (/playlist\/index\.html\?/.test(id)) { // if (/playlist\/index\.html\?/.test(id)) {
id = id.replace(/.*(?:\?|&)id=(\d+)(?:&.*|$)/, '$1') // id = id.replace(/.*(?:\?|&)id=(\d+)(?:&.*|$)/, '$1')
} else if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1') // } else if ((/[?&:/]/.test(id))) id = id.replace(this.regExps.listDetailLink, '$1')
const requestObj_listDetail = httpFetch(this.getSongListDetailUrl(id, page), { headers: this.defaultHeaders }) const requestObj_listDetail = httpFetch(this.getSongListDetailUrl(id, page), { headers: this.defaultHeaders })
return requestObj_listDetail.promise.then(({ body }) => { 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(JSON.stringify(body))
// console.log(body) // console.log(body)
return { return {
list: filterMusicInfoList(body.list), list: filterMusicInfoListV5(body.data.songList),
page, page,
limit: this.limit_song, limit: this.limit_song,
total: body.totalCount, total: body.data.totalCount,
source: 'mg', source: 'mg',
} }
}) })
@@ -130,8 +133,10 @@ export default {
getListDetail(id, page, retryNum = 0) { // 获取歌曲列表内的音乐 getListDetail(id, page, retryNum = 0) { // 获取歌曲列表内的音乐
// https://h5.nf.migu.cn/app/v4/p/share/playlist/index.html?id=184187437&channel=0146921 // https://h5.nf.migu.cn/app/v4/p/share/playlist/index.html?id=184187437&channel=0146921
// http://c.migu.cn/00bTY6?ifrom=babddaadfde4ebeda289d671ab62f236 // http://c.migu.cn/00bTY6?ifrom=babddaadfde4ebeda289d671ab62f236
if (/playlist\/index\.html\?/.test(id)) { // https://music.migu.cn/v5/#/playlist?playlistId=221573417
id = id.replace(/.*(?:\?|&)id=(\d+)(?:&.*|$)/, '$1') 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)) { } else if (this.regExps.listDetailLink.test(id)) {
id = id.replace(this.regExps.listDetailLink, '$1') id = id.replace(this.regExps.listDetailLink, '$1')
} else if ((/[?&:/]/.test(id))) { } 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 }) => { return this._requestObj_list.promise.then(({ body }) => {
// console.log(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 { return {
list: this.filterList(body.retMsg.playlist), list,
total: parseInt(body.retMsg.countSize), total: 99999,
page, page,
limit: this.limit_list, limit: this.limit_list,
source: 'mg', source: 'mg',
} }
}) })
// return this._requestObj_list.promise.then(({ body }) => { },
// if (body.retCode !== '100000') return this.getList(sortId, tagId, page, ++tryNum) filterList2(listData, list = [], ids = new Set()) {
// // if (body.code !== '000000') return this.getList(sortId, tagId, page, ++tryNum) for (const item of listData) {
// console.log(body) if (item.contents) this.filterList2(item.contents, list, ids)
// // return { else if (item.resType == '2021' && !ids.has(item.resId)) {
// // list: this.filterList(body.data.contentItemList[0].itemList), ids.add(item.resId)
// // total: parseInt(body.retMsg.countSize), list.push({
// // page, id: String(item.resId),
// // limit: this.limit_list, author: '',
// // source: 'mg', 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) { filterList(rawData) {
// console.log(rawData) // console.log(rawData)
return rawData.map(item => ({ return rawData.map(item => ({
play_count: formatPlayCount(item.playCount), play_count: item.barList[0]?.title,
id: String(item.playListId), id: String(item.logEvent.contentId),
author: item.createName, author: '',
name: item.playListName, name: item.title,
time: dateFormat(item.createTime, 'Y-M-D'), // time: dateFormat(item.createTime, 'Y-M-D'),
img: item.image, img: item.imageUrl,
grade: item.grade, // grade: item.grade,
total: item.contentCount, // total: item.contentCount,
desc: item.summary, desc: '',
source: 'mg', source: 'mg',
})) }))
}, },