mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-03 20:42:09 +08:00
同步PC musicSdk代码
This commit is contained in:
parent
a152028a48
commit
fe7179d242
@ -11,7 +11,6 @@ module.exports = [
|
|||||||
tx: ['128k'],
|
tx: ['128k'],
|
||||||
wy: ['128k'],
|
wy: ['128k'],
|
||||||
mg: ['128k'],
|
mg: ['128k'],
|
||||||
// xm: ['128k'],
|
|
||||||
// bd: ['128k'],
|
// bd: ['128k'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
// import { formatPlayTime } from '../../index'
|
// import { formatPlayTime } from '../../index'
|
||||||
// import jshtmlencode from 'js-htmlencode'
|
|
||||||
|
|
||||||
const boardList = [
|
const boardList = [
|
||||||
// { id: 'bd__601', name: '歌单榜', bangid: '601' },
|
// { id: 'bd__601', name: '歌单榜', bangid: '601' },
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// import '../../polyfill/array.find'
|
// import '../../polyfill/array.find'
|
||||||
// import jshtmlencode from 'js-htmlencode'
|
|
||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { formatPlayTime } from '../../index'
|
import { formatPlayTime } from '../../index'
|
||||||
// import { debug } from '../../utils/env'
|
// import { debug } from '../../utils/env'
|
||||||
@ -62,15 +62,15 @@ export default {
|
|||||||
})
|
})
|
||||||
return list
|
return list
|
||||||
},
|
},
|
||||||
search(str, page = 1, { limit } = {}, retryNum = 0) {
|
search(str, page = 1, limit, retryNum = 0) {
|
||||||
if (++retryNum > 3) return Promise.reject(new Error('try max num'))
|
if (++retryNum > 3) return Promise.reject(new Error('try max num'))
|
||||||
if (limit == null) limit = this.limit
|
if (limit == null) limit = this.limit
|
||||||
|
|
||||||
return this.musicSearch(str, page, limit).then(result => {
|
return this.musicSearch(str, page, limit).then(result => {
|
||||||
if (!result || result.error_code !== 22000) return this.search(str, page, { limit }, retryNum)
|
if (!result || result.error_code !== 22000) return this.search(str, page, limit, retryNum)
|
||||||
let list = this.handleResult(result.result.song_info.song_list)
|
let list = this.handleResult(result.result.song_info.song_list)
|
||||||
|
|
||||||
if (list == null) return this.search(str, page, { limit }, retryNum)
|
if (list == null) return this.search(str, page, limit, retryNum)
|
||||||
|
|
||||||
this.total = result.result.song_info.total
|
this.total = result.result.song_info.total
|
||||||
this.page = page
|
this.page = page
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { decodeName } from '../..'
|
import { decodeName } from '../../index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
_requestObj: null,
|
_requestObj: null,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { decodeLyric } from './util'
|
import { decodeLyric } from './util'
|
||||||
import { decodeName } from '../..'
|
import { decodeName } from '../../index'
|
||||||
|
|
||||||
const headExp = /^.*\[id:\$\w+\]\n/
|
const headExp = /^.*\[id:\$\w+\]\n/
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// import '../../polyfill/array.find'
|
// import '../../polyfill/array.find'
|
||||||
// import jshtmlencode from 'js-htmlencode'
|
|
||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { decodeName, formatPlayTime, sizeFormate } from '../../index'
|
import { decodeName, formatPlayTime, sizeFormate } from '../../index'
|
||||||
// import { debug } from '../../utils/env'
|
// import { debug } from '../../utils/env'
|
||||||
@ -82,10 +82,10 @@ export default {
|
|||||||
if (limit == null) limit = this.limit
|
if (limit == null) limit = this.limit
|
||||||
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
|
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
|
||||||
return this.musicSearch(str, page, limit).then(result => {
|
return this.musicSearch(str, page, limit).then(result => {
|
||||||
if (!result || result.errcode !== 0) return this.search(str, page, { limit }, retryNum)
|
if (!result || result.errcode !== 0) return this.search(str, page, limit, retryNum)
|
||||||
let list = this.handleResult(result.data.info)
|
let list = this.handleResult(result.data.info)
|
||||||
|
|
||||||
if (list == null) return this.search(str, page, { limit }, retryNum)
|
if (list == null) return this.search(str, page, limit, retryNum)
|
||||||
|
|
||||||
this.total = result.data.total
|
this.total = result.data.total
|
||||||
this.page = page
|
this.page = page
|
||||||
|
@ -38,7 +38,6 @@ export default {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
// console.log(body)
|
|
||||||
if (body.error_code !== 0) return Promise.reject('图片获取失败')
|
if (body.error_code !== 0) return Promise.reject('图片获取失败')
|
||||||
let info = body.data[0].info
|
let info = body.data[0].info
|
||||||
const img = info.imgsize ? info.image.replace('{size}', info.imgsize[0]) : info.image
|
const img = info.imgsize ? info.image.replace('{size}', info.imgsize[0]) : info.image
|
||||||
|
@ -44,8 +44,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (formats.includes('HIRFLAC')) {
|
if (formats.includes('HIRFLAC')) {
|
||||||
types.push({ type: 'flac32bit', size: null })
|
types.push({ type: 'flac24bit', size: null })
|
||||||
_types.flac32bit = {
|
_types.flac24bit = {
|
||||||
size: null,
|
size: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,6 +84,7 @@ export default {
|
|||||||
body = objStr2JSON(body)
|
body = objStr2JSON(body)
|
||||||
// console.log(body)
|
// console.log(body)
|
||||||
if (!body.musiclist) return this.getAlbumListDetail(id, page, ++retryNum)
|
if (!body.musiclist) return this.getAlbumListDetail(id, page, ++retryNum)
|
||||||
|
body.name = decodeName(body.name)
|
||||||
return {
|
return {
|
||||||
list: this.filterListDetail(body.musiclist, body.name, body.albumid),
|
list: this.filterListDetail(body.musiclist, body.name, body.albumid),
|
||||||
page,
|
page,
|
||||||
@ -93,11 +94,38 @@ export default {
|
|||||||
info: {
|
info: {
|
||||||
name: body.name,
|
name: body.name,
|
||||||
img: body.img || body.hts_img,
|
img: body.img || body.hts_img,
|
||||||
desc: body.info,
|
desc: decodeName(body.info),
|
||||||
author: body.artist,
|
author: decodeName(body.artist),
|
||||||
// play_count: this.formatPlayCount(body.playnum),
|
// play_count: this.formatPlayCount(body.playnum),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// getAlbumListDetail(id, page, retryNum = 0) {
|
||||||
|
// if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
||||||
|
// return tokenRequest(`http://www.kuwo.cn/api/www/album/albumInfo?albumId=${id}&pn=${page}&rn=${this.limit_song}&httpsStatus=1`).then((resp) => {
|
||||||
|
// return resp.promise.then(({ statusCode, body }) => {
|
||||||
|
// console.log(body)
|
||||||
|
// return Promise.reject(new Error('failed'))
|
||||||
|
// // if (statusCode !== 200) return this.getAlbumListDetail(id, page, ++retryNum)
|
||||||
|
// // const data = body.data
|
||||||
|
// // console.log(data)
|
||||||
|
// // if (!data.musicList) return this.getAlbumListDetail(id, page, ++retryNum)
|
||||||
|
// // return {
|
||||||
|
// // list: this.filterListDetail(data.musiclist),
|
||||||
|
// // page,
|
||||||
|
// // limit: this.limit_song,
|
||||||
|
// // total: data.total,
|
||||||
|
// // source: 'kw',
|
||||||
|
// // info: {
|
||||||
|
// // name: data.album,
|
||||||
|
// // img: data.pic,
|
||||||
|
// // desc: data.albuminfo,
|
||||||
|
// // author: data.artist,
|
||||||
|
// // play_count: this.formatPlayCount(data.playCnt),
|
||||||
|
// // },
|
||||||
|
// // }
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// },
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { dateFormat2 } from '../../'
|
import { dateFormat2 } from '../../index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
_requestObj: null,
|
_requestObj: null,
|
||||||
|
@ -34,7 +34,8 @@ const decodeLyric = async(buf, isGetLyricx) => {
|
|||||||
|
|
||||||
return iconv.decode(Buffer.from(output), 'gb18030')
|
return iconv.decode(Buffer.from(output), 'gb18030')
|
||||||
}
|
}
|
||||||
export default async({ lrcBase64, isGetLyricx }) => {
|
export default async({ lrcBuffer, isGetLyricx }) => {
|
||||||
const lrc = await decodeLyric(Buffer.from(lrcBase64, 'base64'), isGetLyricx)
|
const lrc = await decodeLyric(lrcBuffer, isGetLyricx)
|
||||||
|
// console.log(lrc)
|
||||||
return Buffer.from(lrc).toString('base64')
|
return Buffer.from(lrc).toString('base64')
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ const kw = {
|
|||||||
comment,
|
comment,
|
||||||
getLyric(songInfo, isGetLyricx) {
|
getLyric(songInfo, isGetLyricx) {
|
||||||
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
||||||
return lyric.getLyric(songInfo.songmid, isGetLyricx)
|
return lyric.getLyric(songInfo, isGetLyricx)
|
||||||
},
|
},
|
||||||
handleMusicInfo(songInfo) {
|
handleMusicInfo(songInfo) {
|
||||||
return this.getMusicInfo(songInfo).then(info => {
|
return this.getMusicInfo(songInfo).then(info => {
|
||||||
|
@ -116,8 +116,8 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (formats.includes('HIRFLAC')) {
|
if (formats.includes('HIRFLAC')) {
|
||||||
types.push({ type: 'flac32bit', size: null })
|
types.push({ type: 'flac24bit', size: null })
|
||||||
_types.flac32bit = {
|
_types.flac24bit = {
|
||||||
size: null,
|
size: null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
|
import { decodeLyric, lrcTools } from './util'
|
||||||
import { decodeName } from '../../index'
|
import { decodeName } from '../../index'
|
||||||
|
|
||||||
|
/*
|
||||||
export default {
|
export default {
|
||||||
formatTime(time) {
|
formatTime(time) {
|
||||||
let m = parseInt(time / 60)
|
let m = parseInt(time / 60)
|
||||||
@ -12,6 +14,142 @@ export default {
|
|||||||
let lrc = []
|
let lrc = []
|
||||||
let lrcT = []
|
let lrcT = []
|
||||||
|
|
||||||
|
for (const item of arr) {
|
||||||
|
if (lrcSet.has(item.time)) {
|
||||||
|
const tItem = lrc.pop()
|
||||||
|
tItem.time = lrc[lrc.length - 1].time
|
||||||
|
lrcT.push(tItem)
|
||||||
|
lrc.push(item)
|
||||||
|
} else {
|
||||||
|
lrc.push(item)
|
||||||
|
lrcSet.add(item.time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lrcT.length && lrc.length > lrcT.length) {
|
||||||
|
const tItem = lrc.pop()
|
||||||
|
tItem.time = lrc[lrc.length - 1].time
|
||||||
|
lrcT.push(tItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
lrc,
|
||||||
|
lrcT,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
transformLrc(songinfo, lrclist) {
|
||||||
|
return `[ti:${songinfo.songName}]\n[ar:${songinfo.artist}]\n[al:${songinfo.album}]\n[by:]\n[offset:0]\n${lrclist ? lrclist.map(l => `[${this.formatTime(l.time)}]${l.lineLyric}\n`).join('') : '暂无歌词'}`
|
||||||
|
},
|
||||||
|
getLyric(songId) {
|
||||||
|
const requestObj = httpFetch(`http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=${songId}`)
|
||||||
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
// console.log(body)
|
||||||
|
if (!body.data?.lrclist?.length) return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
let lrcInfo
|
||||||
|
try {
|
||||||
|
lrcInfo = this.sortLrcArr(body.data.lrclist)
|
||||||
|
} catch {
|
||||||
|
return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
}
|
||||||
|
// console.log(body.data.lrclist)
|
||||||
|
// console.log(lrcInfo.lrc, lrcInfo.lrcT)
|
||||||
|
// console.log({
|
||||||
|
// lyric: decodeName(this.transformLrc(body.data.songinfo, lrc)),
|
||||||
|
// tlyric: decodeName(this.transformLrc(body.data.songinfo, lrcT)),
|
||||||
|
// })
|
||||||
|
return {
|
||||||
|
lyric: decodeName(this.transformLrc(body.data.songinfo, lrcInfo.lrc)),
|
||||||
|
tlyric: lrcInfo.lrcT.length ? decodeName(this.transformLrc(body.data.songinfo, lrcInfo.lrcT)) : '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
|
},
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const buf_key = Buffer.from('yeelion')
|
||||||
|
const buf_key_len = buf_key.length
|
||||||
|
const buildParams = (id, isGetLyricx) => {
|
||||||
|
let params = `user=12345,web,web,web&requester=localhost&req=1&rid=MUSIC_${id}`
|
||||||
|
if (isGetLyricx) params += '&lrcx=1'
|
||||||
|
const buf_str = Buffer.from(params)
|
||||||
|
const buf_str_len = buf_str.length
|
||||||
|
const output = new Uint16Array(buf_str_len)
|
||||||
|
let i = 0
|
||||||
|
while (i < buf_str_len) {
|
||||||
|
let j = 0
|
||||||
|
while (j < buf_key_len && i < buf_str_len) {
|
||||||
|
output[i] = buf_key[j] ^ buf_str[i]
|
||||||
|
i++
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Buffer.from(output).toString('base64')
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(buildParams('207527604', false))
|
||||||
|
// console.log(buildParams('207527604', true))
|
||||||
|
|
||||||
|
const timeExp = /^\[([\d:.]*)\]{1}/g
|
||||||
|
const existTimeExp = /\[\d{1,2}:.*\d{1,4}\]/
|
||||||
|
export default {
|
||||||
|
/* sortLrcArr(arr) {
|
||||||
|
const lrcSet = new Set()
|
||||||
|
let lrc = []
|
||||||
|
let lrcT = []
|
||||||
|
let markIndex = []
|
||||||
|
for (const item of arr) {
|
||||||
|
if (lrcSet.has(item.time)) {
|
||||||
|
if (lrc.length < 2) continue
|
||||||
|
const index = lrc.findIndex(l => l.time == item.time)
|
||||||
|
markIndex.push(index)
|
||||||
|
if (index == lrc.length - 1) {
|
||||||
|
lrcT.push({ ...lrc[index], time: item.time })
|
||||||
|
lrc.push(item)
|
||||||
|
} else {
|
||||||
|
lrcT.push({ ...lrc[index], time: lrc[index + 1].time })
|
||||||
|
if (item.text) {
|
||||||
|
// const lastIndex = lrc.length - 1
|
||||||
|
// markIndex.push(lastIndex)
|
||||||
|
// lrcT.push({ ...lrc[lastIndex], time: lrc[lastIndex - 1].time })
|
||||||
|
lrc.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lrc.push(item)
|
||||||
|
lrcSet.add(item.time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(markIndex)
|
||||||
|
markIndex = Array.from(new Set(markIndex))
|
||||||
|
for (let index = markIndex.length - 1; index >= 0; index--) {
|
||||||
|
lrc.splice(markIndex[index], 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (lrcT.length) {
|
||||||
|
// if (lrc.length * 0.4 < lrcT.length) { // 翻译数量需大于歌词数量的0.4倍,否则认为没有翻译
|
||||||
|
// const tItem = lrc.pop()
|
||||||
|
// tItem.time = lrc[lrc.length - 1].time
|
||||||
|
// lrcT.push(tItem)
|
||||||
|
// } else {
|
||||||
|
// lrc = arr
|
||||||
|
// lrcT = []
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
console.log(lrc, lrcT)
|
||||||
|
|
||||||
|
return {
|
||||||
|
lrc,
|
||||||
|
lrcT,
|
||||||
|
}
|
||||||
|
}, */
|
||||||
|
sortLrcArr(arr) {
|
||||||
|
const lrcSet = new Set()
|
||||||
|
let lrc = []
|
||||||
|
let lrcT = []
|
||||||
|
|
||||||
for (const item of arr) {
|
for (const item of arr) {
|
||||||
if (lrcSet.has(item.time)) {
|
if (lrcSet.has(item.time)) {
|
||||||
if (lrc.length < 2) continue
|
if (lrc.length < 2) continue
|
||||||
@ -42,31 +180,90 @@ export default {
|
|||||||
lrcT,
|
lrcT,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
transformLrc(songinfo, lrclist) {
|
transformLrc(tags, lrclist) {
|
||||||
return `[ti:${songinfo.songName}]\n[ar:${songinfo.artist}]\n[al:${songinfo.album}]\n[by:]\n[offset:0]\n${lrclist ? lrclist.map(l => `[${this.formatTime(l.time)}]${l.lineLyric}\n`).join('') : '暂无歌词'}`
|
return `${tags.join('\n')}\n${lrclist ? lrclist.map(l => `[${l.time}]${l.text}\n`).join('') : '暂无歌词'}`
|
||||||
},
|
},
|
||||||
getLyric(songId) {
|
parseLrc(lrc) {
|
||||||
const requestObj = httpFetch(`http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId=${songId}`)
|
const lines = lrc.split(/\r\n|\r|\n/)
|
||||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
let tags = []
|
||||||
// console.log(body)
|
let lrcArr = []
|
||||||
if (!body.data?.lrclist?.length) return Promise.reject(new Error('Get lyric failed'))
|
for (let i = 0; i < lines.length; i++) {
|
||||||
let lrcInfo
|
const line = lines[i].trim()
|
||||||
try {
|
let result = timeExp.exec(line)
|
||||||
lrcInfo = this.sortLrcArr(body.data.lrclist)
|
if (result) {
|
||||||
} catch (err) {
|
const text = line.replace(timeExp, '').trim()
|
||||||
console.log(err)
|
let time = RegExp.$1
|
||||||
return Promise.reject(new Error('Get lyric failed'))
|
if (/\.\d\d$/.test(time)) time += '0'
|
||||||
}
|
lrcArr.push({
|
||||||
// console.log(body.data.lrclist)
|
time,
|
||||||
// console.log(lrcInfo.lrc, lrcInfo.lrcT)
|
text,
|
||||||
// console.log({
|
})
|
||||||
// lyric: decodeName(this.transformLrc(body.data.songinfo, lrc)),
|
} else if (lrcTools.rxps.tagLine.test(line)) {
|
||||||
// tlyric: decodeName(this.transformLrc(body.data.songinfo, lrcT)),
|
tags.push(line)
|
||||||
// })
|
|
||||||
return {
|
|
||||||
lyric: decodeName(this.transformLrc(body.data.songinfo, lrcInfo.lrc)),
|
|
||||||
tlyric: lrcInfo.lrcT.length ? decodeName(this.transformLrc(body.data.songinfo, lrcInfo.lrcT)) : '',
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
const lrcInfo = this.sortLrcArr(lrcArr)
|
||||||
|
return {
|
||||||
|
lyric: decodeName(this.transformLrc(tags, lrcInfo.lrc)),
|
||||||
|
tlyric: lrcInfo.lrcT.length ? decodeName(this.transformLrc(tags, lrcInfo.lrcT)) : '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// getLyric2(musicInfo, isGetLyricx = true) {
|
||||||
|
// const requestObj = httpFetch(`http://newlyric.kuwo.cn/newlyric.lrc?${buildParams(musicInfo.songmid, isGetLyricx)}`)
|
||||||
|
// requestObj.promise = requestObj.promise.then(({ statusCode, body, raw }) => {
|
||||||
|
// if (statusCode != 200) return Promise.reject(new Error(JSON.stringify(body)))
|
||||||
|
// return decodeLyric({ lrcBase64: raw.toString('base64'), isGetLyricx }).then(base64Data => {
|
||||||
|
// let lrcInfo
|
||||||
|
// console.log(Buffer.from(base64Data, 'base64').toString())
|
||||||
|
// try {
|
||||||
|
// lrcInfo = this.parseLrc(Buffer.from(base64Data, 'base64').toString())
|
||||||
|
// } catch {
|
||||||
|
// return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
// }
|
||||||
|
// if (lrcInfo.tlyric) lrcInfo.tlyric = lrcInfo.tlyric.replace(lrcTools.rxps.wordTimeAll, '')
|
||||||
|
// lrcInfo.lxlyric = lrcTools.parse(lrcInfo.lyric)
|
||||||
|
// // console.log(lrcInfo.lyric)
|
||||||
|
// // console.log(lrcInfo.tlyric)
|
||||||
|
// // console.log(lrcInfo.lxlyric)
|
||||||
|
// // console.log(JSON.stringify(lrcInfo))
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// return requestObj
|
||||||
|
// },
|
||||||
|
getLyric(musicInfo, isGetLyricx = true) {
|
||||||
|
// this.getLyric2(musicInfo)
|
||||||
|
const requestObj = httpFetch(`http://newlyric.kuwo.cn/newlyric.lrc?${buildParams(musicInfo.songmid, isGetLyricx)}`, {
|
||||||
|
cache: false,
|
||||||
|
binary: true,
|
||||||
|
})
|
||||||
|
requestObj.promise = requestObj.promise.then(({ statusCode, body }) => {
|
||||||
|
if (statusCode != 200) return Promise.reject(new Error(JSON.stringify(body)))
|
||||||
|
return decodeLyric({ lrcBuffer: body, isGetLyricx }).then(base64Data => {
|
||||||
|
// let lrcInfo
|
||||||
|
// try {
|
||||||
|
// lrcInfo = this.parseLrc(Buffer.from(base64Data, 'base64').toString())
|
||||||
|
// } catch {
|
||||||
|
// return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
// }
|
||||||
|
let lrcInfo
|
||||||
|
// console.log(Buffer.from(base64Data, 'base64').toString())
|
||||||
|
try {
|
||||||
|
lrcInfo = this.parseLrc(Buffer.from(base64Data, 'base64').toString())
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
}
|
||||||
|
// console.log(lrcInfo)
|
||||||
|
if (lrcInfo.tlyric) lrcInfo.tlyric = lrcInfo.tlyric.replace(lrcTools.rxps.wordTimeAll, '')
|
||||||
|
try {
|
||||||
|
lrcInfo.lxlyric = lrcTools.parse(lrcInfo.lyric)
|
||||||
|
} catch {
|
||||||
|
lrcInfo.lxlyric = ''
|
||||||
|
}
|
||||||
|
lrcInfo.lyric = lrcInfo.lyric.replace(lrcTools.rxps.wordTimeAll, '')
|
||||||
|
if (!existTimeExp.test(lrcInfo.lyric)) return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
// console.log(lrcInfo)
|
||||||
|
return lrcInfo
|
||||||
|
})
|
||||||
})
|
})
|
||||||
return requestObj
|
return requestObj
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// import '../../polyfill/array.find'
|
// import '../../polyfill/array.find'
|
||||||
// import jshtmlencode from 'js-htmlencode'
|
|
||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { formatPlayTime, decodeName } from '../../index'
|
import { formatPlayTime, decodeName } from '../../index'
|
||||||
// import { debug } from '../../utils/env'
|
// import { debug } from '../../utils/env'
|
||||||
@ -47,8 +47,8 @@ export default {
|
|||||||
if (info) {
|
if (info) {
|
||||||
switch (info[2]) {
|
switch (info[2]) {
|
||||||
case '4000':
|
case '4000':
|
||||||
types.push({ type: 'flac32bit', size: info[4] })
|
types.push({ type: 'flac24bit', size: info[4] })
|
||||||
_types.flac32bit = {
|
_types.flac24bit = {
|
||||||
size: info[4].toLocaleUpperCase(),
|
size: info[4].toLocaleUpperCase(),
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -106,10 +106,10 @@ export default {
|
|||||||
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
|
// http://newlyric.kuwo.cn/newlyric.lrc?62355680
|
||||||
return this.musicSearch(str, page, limit).then(({ body: result }) => {
|
return this.musicSearch(str, page, limit).then(({ body: result }) => {
|
||||||
// console.log(result)
|
// console.log(result)
|
||||||
if (!result || (result.TOTAL !== '0' && result.SHOW === '0')) return this.search(str, page, { limit }, ++retryNum)
|
if (!result || (result.TOTAL !== '0' && result.SHOW === '0')) return this.search(str, page, limit, ++retryNum)
|
||||||
let list = this.handleResult(result.abslist)
|
let list = this.handleResult(result.abslist)
|
||||||
|
|
||||||
if (list == null) return this.search(str, page, { limit }, ++retryNum)
|
if (list == null) return this.search(str, page, limit, ++retryNum)
|
||||||
|
|
||||||
this.total = parseInt(result.TOTAL)
|
this.total = parseInt(result.TOTAL)
|
||||||
this.page = page
|
this.page = page
|
||||||
|
@ -73,6 +73,7 @@ export const tokenRequest = async(url, options = {}) => {
|
|||||||
}
|
}
|
||||||
const requestObj = httpFetch(url, options)
|
const requestObj = httpFetch(url, options)
|
||||||
requestObj.promise = requestObj.promise.then(resp => {
|
requestObj.promise = requestObj.promise.then(resp => {
|
||||||
|
// console.log(resp)
|
||||||
if (resp.statusCode == 200) {
|
if (resp.statusCode == 200) {
|
||||||
kw_token.token = matchToken(resp.headers)
|
kw_token.token = matchToken(resp.headers)
|
||||||
}
|
}
|
||||||
@ -80,3 +81,99 @@ export const tokenRequest = async(url, options = {}) => {
|
|||||||
})
|
})
|
||||||
return requestObj
|
return requestObj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const lrcTools = {
|
||||||
|
rxps: {
|
||||||
|
wordLine: /^(\[\d{1,2}:.*\d{1,4}\])\s*(\S+(?:\s+\S+)*)?\s*/,
|
||||||
|
tagLine: /\[(ver|ti|ar|al|offset|by|kuwo):\s*(\S+(?:\s+\S+)*)\s*\]/,
|
||||||
|
wordTimeAll: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/g,
|
||||||
|
wordTime: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/,
|
||||||
|
},
|
||||||
|
offset: 1,
|
||||||
|
offset2: 1,
|
||||||
|
isOK: false,
|
||||||
|
lines: [],
|
||||||
|
tags: [],
|
||||||
|
getWordInfo(str, str2, prevWord) {
|
||||||
|
const offset = parseInt(str)
|
||||||
|
const offset2 = parseInt(str2)
|
||||||
|
let startTime = Math.abs((offset + offset2) / (this.offset * 2))
|
||||||
|
let endTime = Math.abs((offset - offset2) / (this.offset2 * 2)) + startTime
|
||||||
|
if (prevWord) {
|
||||||
|
if (startTime < prevWord.endTime) {
|
||||||
|
prevWord.endTime = startTime
|
||||||
|
if (prevWord.startTime > prevWord.endTime) {
|
||||||
|
prevWord.startTime = prevWord.endTime
|
||||||
|
}
|
||||||
|
|
||||||
|
prevWord.newTimeStr = `<${prevWord.startTime},${prevWord.endTime - prevWord.startTime}>`
|
||||||
|
// console.log(prevWord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
startTime,
|
||||||
|
endTime,
|
||||||
|
timeStr: `<${startTime},${endTime - startTime}>`,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseLine(line) {
|
||||||
|
if (line.length < 6) return
|
||||||
|
let result = this.rxps.wordLine.exec(line)
|
||||||
|
if (result) {
|
||||||
|
const time = result[1]
|
||||||
|
let words = result[2]
|
||||||
|
if (words == null) {
|
||||||
|
words = ''
|
||||||
|
}
|
||||||
|
const wordTimes = words.match(this.rxps.wordTimeAll)
|
||||||
|
if (!wordTimes) return
|
||||||
|
// console.log(wordTimes)
|
||||||
|
let preTimeInfo
|
||||||
|
for (const timeStr of wordTimes) {
|
||||||
|
const result = this.rxps.wordTime.exec(timeStr)
|
||||||
|
const wordInfo = this.getWordInfo(result[1], result[2], preTimeInfo)
|
||||||
|
words = words.replace(timeStr, wordInfo.timeStr)
|
||||||
|
if (preTimeInfo?.newTimeStr) words = words.replace(preTimeInfo.timeStr, preTimeInfo.newTimeStr)
|
||||||
|
preTimeInfo = wordInfo
|
||||||
|
}
|
||||||
|
this.lines.push(time + words)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result = this.rxps.tagLine.exec(line)
|
||||||
|
if (!result) return
|
||||||
|
if (result[1] == 'kuwo') {
|
||||||
|
let content = result[2]
|
||||||
|
if (content != null && content.includes('][')) {
|
||||||
|
content = content.substring(0, content.indexOf(']['))
|
||||||
|
}
|
||||||
|
const valueOf = parseInt(content, 8)
|
||||||
|
this.offset = Math.trunc(valueOf / 10)
|
||||||
|
this.offset2 = Math.trunc(valueOf % 10)
|
||||||
|
if (this.offset == 0 || Number.isNaN(this.offset) || this.offset2 == 0 || Number.isNaN(this.offset2)) {
|
||||||
|
this.isOK = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.tags.push(line)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parse(lrc) {
|
||||||
|
// console.log(lrc)
|
||||||
|
const lines = lrc.split(/\r\n|\r|\n/)
|
||||||
|
const tools = Object.create(this)
|
||||||
|
tools.isOK = true
|
||||||
|
tools.offset = 1
|
||||||
|
tools.offset2 = 1
|
||||||
|
tools.lines = []
|
||||||
|
tools.tags = []
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (!tools.isOK) throw new Error('failed')
|
||||||
|
tools.parseLine(line)
|
||||||
|
}
|
||||||
|
if (!tools.lines.length) return ''
|
||||||
|
let lrcs = tools.lines.join('\n')
|
||||||
|
if (tools.tags.length) lrcs = `${tools.tags.join('\n')}\n${lrcs}`
|
||||||
|
// console.log(lrcs)
|
||||||
|
return lrcs
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import album from './album'
|
import album from './album'
|
||||||
import { dateFormat2 } from '../../'
|
import { dateFormat2 } from '../../index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
_requestObj: null,
|
_requestObj: null,
|
||||||
|
@ -103,30 +103,30 @@ export default {
|
|||||||
let size
|
let size
|
||||||
switch (type.formatType) {
|
switch (type.formatType) {
|
||||||
case 'PQ':
|
case 'PQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: '128k', size })
|
types.push({ type: '128k', size })
|
||||||
_types['128k'] = {
|
_types['128k'] = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'HQ':
|
case 'HQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: '320k', size })
|
types.push({ type: '320k', size })
|
||||||
_types['320k'] = {
|
_types['320k'] = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'SQ':
|
case 'SQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: 'flac', size })
|
types.push({ type: 'flac', size })
|
||||||
_types.flac = {
|
_types.flac = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'ZQ':
|
case 'ZQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: 'flac32bit', size })
|
types.push({ type: 'flac24bit', size })
|
||||||
_types.flac32bit = {
|
_types.flac24bit = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -1,7 +1,52 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import musicSearch from './musicSearch'
|
import musicSearch from './musicSearch'
|
||||||
|
import { decrypt } from './mrc'
|
||||||
|
|
||||||
export default {
|
const mrcTools = {
|
||||||
|
rxps: {
|
||||||
|
lineTime: /^\s*\[(\d+),\d+\]/,
|
||||||
|
wordTime: /\(\d+,\d+\)/,
|
||||||
|
wordTimeAll: /(\(\d+,\d+\))/g,
|
||||||
|
},
|
||||||
|
parseLyric(str) {
|
||||||
|
str = str.replace(/\r/g, '')
|
||||||
|
const lines = str.split('\n')
|
||||||
|
const lxlrcLines = []
|
||||||
|
const lrcLines = []
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.length < 6) continue
|
||||||
|
let result = this.rxps.lineTime.exec(line)
|
||||||
|
if (!result) continue
|
||||||
|
|
||||||
|
const startTime = parseInt(result[1])
|
||||||
|
let time = startTime
|
||||||
|
let ms = time % 1000
|
||||||
|
time /= 1000
|
||||||
|
let m = parseInt(time / 60).toString().padStart(2, '0')
|
||||||
|
time %= 60
|
||||||
|
let s = parseInt(time).toString().padStart(2, '0')
|
||||||
|
time = `${m}:${s}.${ms}`
|
||||||
|
|
||||||
|
let words = line.replace(this.rxps.lineTime, '')
|
||||||
|
|
||||||
|
lrcLines.push(`[${time}]${words.replace(this.rxps.wordTimeAll, '')}`)
|
||||||
|
|
||||||
|
let times = words.match(this.rxps.wordTimeAll)
|
||||||
|
if (!times) continue
|
||||||
|
times = times.map(time => {
|
||||||
|
const result = /\((\d+),(\d+)\)/.exec(time)
|
||||||
|
return `<${parseInt(result[1]) - startTime},${result[2]}>`
|
||||||
|
})
|
||||||
|
const wordArr = words.split(this.rxps.wordTime)
|
||||||
|
const newWords = times.map((time, index) => `${time}${wordArr[index]}`).join('')
|
||||||
|
lxlrcLines.push(`[${time}]${newWords}`)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
lyric: lrcLines.join('\n'),
|
||||||
|
lxlyric: lxlrcLines.join('\n'),
|
||||||
|
}
|
||||||
|
},
|
||||||
getText(url, tryNum = 0) {
|
getText(url, tryNum = 0) {
|
||||||
const requestObj = httpFetch(url, {
|
const requestObj = httpFetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
@ -16,8 +61,13 @@ export default {
|
|||||||
return this.getText(url, ++tryNum)
|
return this.getText(url, ++tryNum)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
getMrc(url) {
|
||||||
|
return this.getText(url).then(text => {
|
||||||
|
return this.parseLyric(decrypt(text))
|
||||||
|
})
|
||||||
|
},
|
||||||
getLrc(url) {
|
getLrc(url) {
|
||||||
return this.getText(url)
|
return this.getText(url).then(text => ({ lxlyric: '', lyric: text }))
|
||||||
},
|
},
|
||||||
getTrc(url) {
|
getTrc(url) {
|
||||||
if (!url) return Promise.resolve('')
|
if (!url) return Promise.resolve('')
|
||||||
@ -31,30 +81,51 @@ export default {
|
|||||||
})
|
})
|
||||||
: Promise.resolve({ lrcUrl: songInfo.lrcUrl, mrcUrl: songInfo.mrcUrl, trcUrl: songInfo.trcUrl })
|
: Promise.resolve({ lrcUrl: songInfo.lrcUrl, mrcUrl: songInfo.mrcUrl, trcUrl: songInfo.trcUrl })
|
||||||
},
|
},
|
||||||
getLyric(songInfo, tryNum = 0) {
|
getLyric(songInfo) {
|
||||||
|
return {
|
||||||
|
promise: this.getMusicInfo(songInfo).then(info => {
|
||||||
|
let p
|
||||||
|
if (info.mrcUrl) p = this.getMrc(info.mrcUrl)
|
||||||
|
else if (info.lrcUrl) p = this.getLrc(info.lrcUrl)
|
||||||
|
if (p == null) return Promise.reject('获取歌词失败')
|
||||||
|
return Promise.all([p, this.getTrc(info.trcUrl)]).then(([lrcInfo, tlyric]) => {
|
||||||
|
lrcInfo.tlyric = tlyric
|
||||||
|
return lrcInfo
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
cancelHttp() {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getLyricWeb(songInfo, tryNum = 0) {
|
||||||
// console.log(songInfo.copyrightId)
|
// console.log(songInfo.copyrightId)
|
||||||
if (songInfo.lrcUrl) {
|
if (songInfo.lrcUrl) {
|
||||||
return {
|
let requestObj = httpFetch(songInfo.lrcUrl)
|
||||||
promise: this.getMusicInfo(songInfo).then(info => {
|
requestObj.promise = requestObj.promise.then(({ body, statusCode }) => {
|
||||||
return Promise.all([this.getLrc(info.lrcUrl), this.getTrc(info.trcUrl)]).then(([lyric, tlyric]) => {
|
if (statusCode !== 200) {
|
||||||
return {
|
if (tryNum > 5) return Promise.reject('歌词获取失败')
|
||||||
lyric,
|
let tryRequestObj = this.getLyricWeb(songInfo, ++tryNum)
|
||||||
tlyric,
|
requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
|
||||||
}
|
return tryRequestObj.promise
|
||||||
})
|
}
|
||||||
}),
|
return {
|
||||||
cancelHttp() {},
|
lyric: body,
|
||||||
}
|
tlyric: '',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return requestObj
|
||||||
} else {
|
} else {
|
||||||
let requestObj = httpFetch(`http://music.migu.cn/v3/api/music/audioPlayer/getLyric?copyrightId=${songInfo.copyrightId}`, {
|
let requestObj = httpFetch(`https://music.migu.cn/v3/api/music/audioPlayer/getLyric?copyrightId=${songInfo.copyrightId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
Referer: 'http://music.migu.cn/v3/music/player/audio?from=migu',
|
Referer: 'https://music.migu.cn/v3/music/player/audio?from=migu',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
if (body.returnCode !== '000000' || !body.lyric) {
|
if (body.returnCode !== '000000' || !body.lyric) {
|
||||||
if (tryNum > 5) return Promise.reject(new Error('Get lyric failed'))
|
if (tryNum > 5) return Promise.reject(new Error('Get lyric failed'))
|
||||||
let tryRequestObj = this.getLyric(songInfo, ++tryNum)
|
let tryRequestObj = this.getLyricWeb(songInfo, ++tryNum)
|
||||||
requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
|
requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
|
||||||
return tryRequestObj.promise
|
return tryRequestObj.promise
|
||||||
}
|
}
|
||||||
@ -66,4 +137,14 @@ export default {
|
|||||||
return requestObj
|
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
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
104
src/utils/musicSdk/mg/mrc.js
Normal file
104
src/utils/musicSdk/mg/mrc.js
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
// const key = 'karakal@123Qcomyidongtiantianhaoting'
|
||||||
|
const DELTA = 2654435769n
|
||||||
|
const MIN_LENGTH = 32
|
||||||
|
// const SPECIAL_CHAR = '0'
|
||||||
|
const keyArr = [
|
||||||
|
27303562373562475n,
|
||||||
|
18014862372307051n,
|
||||||
|
22799692160172081n,
|
||||||
|
34058940340699235n,
|
||||||
|
30962724186095721n,
|
||||||
|
27303523720101991n,
|
||||||
|
27303523720101998n,
|
||||||
|
31244139033526382n,
|
||||||
|
28992395054481524n,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const teaDecrypt = (data, key) => {
|
||||||
|
const length = data.length
|
||||||
|
const lengthBitint = BigInt(length)
|
||||||
|
if (length >= 1) {
|
||||||
|
// let j = data[data.length - 1];
|
||||||
|
let j2 = data[0]
|
||||||
|
let j3 = toLong((6n + (52n / lengthBitint)) * DELTA)
|
||||||
|
while (true) {
|
||||||
|
let j4 = j3
|
||||||
|
if (j4 == 0n) break
|
||||||
|
let j5 = toLong(3n & toLong(j4 >> 2n))
|
||||||
|
let j6 = lengthBitint
|
||||||
|
while (true) {
|
||||||
|
j6--
|
||||||
|
if (j6 > 0n) {
|
||||||
|
let j7 = data[(j6 - 1n)]
|
||||||
|
let i = j6
|
||||||
|
j2 = toLong(data[i] - (toLong(toLong(j2 ^ j4) + toLong(j7 ^ key[toLong(toLong(3n & j6) ^ j5)])) ^ toLong(toLong(toLong(j7 >> 5n) ^ toLong(j2 << 2n)) + toLong(toLong(j2 >> 3n) ^ toLong(j7 << 4n)))))
|
||||||
|
data[i] = j2
|
||||||
|
} else break
|
||||||
|
}
|
||||||
|
let j8 = data[lengthBitint - 1n]
|
||||||
|
j2 = toLong(data[0n] - toLong(toLong(toLong(key[toLong(toLong(j6 & 3n) ^ j5)] ^ j8) + toLong(j2 ^ j4)) ^ toLong(toLong(toLong(j8 >> 5n) ^ toLong(j2 << 2n)) + toLong(toLong(j2 >> 3n) ^ toLong(j8 << 4n)))))
|
||||||
|
data[0] = j2
|
||||||
|
j3 = toLong(j4 - DELTA)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
const longArrToString = (data) => {
|
||||||
|
const arrayList = []
|
||||||
|
for (const j of data) arrayList.push(longToBytes(j).toString('utf16le'))
|
||||||
|
return arrayList.join('')
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/29132118
|
||||||
|
const longToBytes = (l) => {
|
||||||
|
const result = Buffer.alloc(8)
|
||||||
|
for (let i = 0; i < 8; i++) {
|
||||||
|
result[i] = parseInt(l & 0xFFn)
|
||||||
|
l >>= 8n
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const toBigintArray = (data) => {
|
||||||
|
const length = Math.floor(data.length / 16)
|
||||||
|
const jArr = Array(length)
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
jArr[i] = toLong(data.substring(i * 16, (i * 16) + 16))
|
||||||
|
}
|
||||||
|
return jArr
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/lyswhut/lx-music-desktop/issues/445#issuecomment-1139338682
|
||||||
|
const MAX = 9223372036854775807n
|
||||||
|
const MIN = -9223372036854775808n
|
||||||
|
const toLong = str => {
|
||||||
|
const num = typeof str == 'string' ? BigInt('0x' + str) : str
|
||||||
|
if (num > MAX) return toLong(num - (1n << 64n))
|
||||||
|
else if (num < MIN) return toLong(num + (1n << 64n))
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
export const decrypt = (data) => {
|
||||||
|
// console.log(data.length)
|
||||||
|
// -3551594764563790630
|
||||||
|
// console.log(toLongArrayFromArr(Buffer.from(key)))
|
||||||
|
// console.log(teaDecrypt(toBigintArray(data), keyArr))
|
||||||
|
// console.log(longArrToString(teaDecrypt(toBigintArray(data), keyArr)))
|
||||||
|
// console.log(toByteArray(teaDecrypt(toBigintArray(data), keyArr)))
|
||||||
|
return (data == null || data.length < MIN_LENGTH)
|
||||||
|
? data
|
||||||
|
: longArrToString(teaDecrypt(toBigintArray(data), keyArr))
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(14895149309145760986n - )
|
||||||
|
// console.log(toLong('14895149309145760986'))
|
||||||
|
// console.log(decrypt(str))
|
||||||
|
// console.log(decrypt(str))
|
||||||
|
// console.log(toByteArray([6048138644744000495n]))
|
||||||
|
// console.log(toByteArray([16325999628386395n]))
|
||||||
|
// console.log(toLong(90994076459972177136n))
|
||||||
|
|
@ -47,30 +47,30 @@ export default {
|
|||||||
let size
|
let size
|
||||||
switch (type.formatType) {
|
switch (type.formatType) {
|
||||||
case 'PQ':
|
case 'PQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: '128k', size })
|
types.push({ type: '128k', size })
|
||||||
_types['128k'] = {
|
_types['128k'] = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'HQ':
|
case 'HQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: '320k', size })
|
types.push({ type: '320k', size })
|
||||||
_types['320k'] = {
|
_types['320k'] = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'SQ':
|
case 'SQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: 'flac', size })
|
types.push({ type: 'flac', size })
|
||||||
_types.flac = {
|
_types.flac = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'ZQ':
|
case 'ZQ':
|
||||||
size = sizeFormate(type.size)
|
size = sizeFormate(type.size ?? type.androidSize)
|
||||||
types.push({ type: 'flac32bit', size })
|
types.push({ type: 'flac24bit', size })
|
||||||
_types.flac32bit = {
|
_types.flac24bit = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -117,7 +117,7 @@ export default {
|
|||||||
const songResultData = result.songResultData || { result: [], totalCount: 0 }
|
const songResultData = result.songResultData || { result: [], totalCount: 0 }
|
||||||
|
|
||||||
let list = this.handleResult(songResultData.result)
|
let list = this.handleResult(songResultData.result)
|
||||||
if (list == null) return this.search(str, page, { limit }, retryNum)
|
if (list == null) return this.search(str, page, limit, retryNum)
|
||||||
|
|
||||||
this.total = parseInt(songResultData.totalCount)
|
this.total = parseInt(songResultData.totalCount)
|
||||||
this.page = page
|
this.page = page
|
||||||
|
@ -18,7 +18,7 @@ const tx = {
|
|||||||
},
|
},
|
||||||
getLyric(songInfo) {
|
getLyric(songInfo) {
|
||||||
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
|
||||||
return lyric.getLyric(songInfo.songmid)
|
return lyric.getLyric(songInfo)
|
||||||
},
|
},
|
||||||
getPic(songInfo) {
|
getPic(songInfo) {
|
||||||
return apis('tx').getPic(songInfo)
|
return apis('tx').getPic(songInfo)
|
||||||
|
@ -139,8 +139,8 @@ export default {
|
|||||||
}
|
}
|
||||||
if (item.file.size_hires !== 0) {
|
if (item.file.size_hires !== 0) {
|
||||||
let size = sizeFormate(item.file.size_hires)
|
let size = sizeFormate(item.file.size_hires)
|
||||||
types.push({ type: 'flac32bit', size })
|
types.push({ type: 'flac24bit', size })
|
||||||
_types.flac32bit = {
|
_types.flac24bit = {
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,12 @@ import crypto from 'crypto'
|
|||||||
* @param {*} type
|
* @param {*} type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const types = ['flac32bit', 'flac', 'wav', 'ape', '320k', '192k', '128k']
|
export const QUALITYS = ['flac24bit', 'flac', 'wav', 'ape', '320k', '192k', '128k']
|
||||||
export const getMusicType = (info, type) => {
|
export const getMusicType = (info, type) => {
|
||||||
const list = global.lx.qualityList[info.source]
|
const list = global.lx.qualityList[info.source]
|
||||||
if (!list) return '128k'
|
if (!list) return '128k'
|
||||||
if (!list.includes(type)) type = list[list.length - 1]
|
if (!list.includes(type)) type = list[list.length - 1]
|
||||||
const rangeType = types.slice(types.indexOf(type))
|
const rangeType = QUALITYS.slice(QUALITYS.indexOf(type))
|
||||||
for (const type of rangeType) {
|
for (const type of rangeType) {
|
||||||
if (info._types[type]) return type
|
if (info._types[type]) return type
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { linuxapi } from './utils/crypto'
|
import { eapi } from './utils/crypto'
|
||||||
// import { decodeName } from '../..'
|
// import { decodeName } from '../..'
|
||||||
|
|
||||||
// const parseLyric = (str, lrc) => {
|
// const parseLyric = (str, lrc) => {
|
||||||
@ -34,31 +34,209 @@ import { linuxapi } from './utils/crypto'
|
|||||||
// return lxlyric.trim()
|
// return lxlyric.trim()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
export default songmid => {
|
const eapiRequest = (url, data) => {
|
||||||
const requestObj = httpFetch('https://music.163.com/api/linux/forward', {
|
return httpFetch('https://interface3.music.163.com/eapi/song/lyric/v1', {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
headers: {
|
||||||
form: linuxapi({
|
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
||||||
method: 'POST',
|
origin: 'https://music.163.com',
|
||||||
url: 'https://music.163.com/api/song/lyric?_nmclfl=1',
|
// cookie: 'os=pc; deviceId=A9C064BB4584D038B1565B58CB05F95290998EE8B025AA2D07AE; osver=Microsoft-Windows-10-Home-China-build-19043-64bit; appver=2.5.2.197409; channel=netease; MUSIC_A=37a11f2eb9de9930cad479b2ad495b0e4c982367fb6f909d9a3f18f876c6b49faddb3081250c4980dd7e19d4bd9bf384e004602712cf2b2b8efaafaab164268a00b47359f85f22705cc95cb6180f3aee40f5be1ebf3148d888aa2d90636647d0c3061cd18d77b7a0; __csrf=05b50d54082694f945d7de75c210ef94; mode=Z7M-KP5(7)GZ; NMTID=00OZLp2VVgq9QdwokUgq3XNfOddQyIAAAF_6i8eJg; ntes_kaola_ad=1',
|
||||||
params: {
|
},
|
||||||
id: songmid,
|
form: eapi(url, data),
|
||||||
tv: -1,
|
})
|
||||||
lv: -1,
|
// requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
rv: -1,
|
// // console.log(raw)
|
||||||
kv: -1,
|
// console.log(body)
|
||||||
},
|
// // console.log(eapiDecrypt(raw))
|
||||||
}),
|
// // return eapiDecrypt(raw)
|
||||||
|
// return body
|
||||||
|
// })
|
||||||
|
// return requestObj
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseTools = {
|
||||||
|
rxps: {
|
||||||
|
info: /^{"/,
|
||||||
|
lineTime: /^\[(\d+),\d+\]/,
|
||||||
|
wordTime: /\(\d+,\d+,\d+\)/,
|
||||||
|
wordTimeAll: /(\(\d+,\d+,\d+\))/g,
|
||||||
|
},
|
||||||
|
msFormat(timeMs) {
|
||||||
|
if (Number.isNaN(timeMs)) return ''
|
||||||
|
let ms = timeMs % 1000
|
||||||
|
timeMs /= 1000
|
||||||
|
let m = parseInt(timeMs / 60).toString().padStart(2, '0')
|
||||||
|
timeMs %= 60
|
||||||
|
let s = parseInt(timeMs).toString().padStart(2, '0')
|
||||||
|
return `[${m}:${s}.${ms}]`
|
||||||
|
},
|
||||||
|
parseLyric(lines) {
|
||||||
|
const lxlrcLines = []
|
||||||
|
const lrcLines = []
|
||||||
|
|
||||||
|
for (let line of lines) {
|
||||||
|
line = line.trim()
|
||||||
|
let result = this.rxps.lineTime.exec(line)
|
||||||
|
if (!result) {
|
||||||
|
if (line.startsWith('[offset')) {
|
||||||
|
lxlrcLines.push(line)
|
||||||
|
lrcLines.push(line)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const startMsTime = parseInt(result[1])
|
||||||
|
const startTimeStr = this.msFormat(startMsTime)
|
||||||
|
if (!startTimeStr) continue
|
||||||
|
|
||||||
|
let words = line.replace(this.rxps.lineTime, '')
|
||||||
|
|
||||||
|
lrcLines.push(`${startTimeStr}${words.replace(this.rxps.wordTimeAll, '')}`)
|
||||||
|
|
||||||
|
let times = words.match(this.rxps.wordTimeAll)
|
||||||
|
if (!times) continue
|
||||||
|
times = times.map(time => {
|
||||||
|
const result = /\((\d+),(\d+),\d+\)/.exec(time)
|
||||||
|
return `<${Math.max(parseInt(result[1]) - startMsTime, 0)},${result[2]}>`
|
||||||
|
})
|
||||||
|
const wordArr = words.split(this.rxps.wordTime)
|
||||||
|
wordArr.shift()
|
||||||
|
const newWords = times.map((time, index) => `${time}${wordArr[index]}`).join('')
|
||||||
|
lxlrcLines.push(`${startTimeStr}${newWords}`)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
lyricLines: lrcLines,
|
||||||
|
lxlyricLines: lxlrcLines,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
parseHeaderInfo(str) {
|
||||||
|
str = str.trim()
|
||||||
|
str = str.replace(/\r/g, '')
|
||||||
|
if (!str) return null
|
||||||
|
const lines = str.split('\n')
|
||||||
|
return lines.map(line => {
|
||||||
|
if (!this.rxps.info.test(line)) return line
|
||||||
|
try {
|
||||||
|
const info = JSON.parse(line)
|
||||||
|
const timeTag = this.msFormat(info.t)
|
||||||
|
return timeTag ? `${timeTag}${info.c.map(t => t.tx).join('')}` : ''
|
||||||
|
} catch {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
fixTimeTag(lrcLines, targetLrcLines) {
|
||||||
|
const timeTagRxp = /^\[[\d:.]+\]/
|
||||||
|
return targetLrcLines.map((line, index) => {
|
||||||
|
const timeTag = timeTagRxp.exec(lrcLines[index])
|
||||||
|
if (!timeTag) return line
|
||||||
|
return line.replace(timeTagRxp, timeTag[0])
|
||||||
|
})
|
||||||
|
},
|
||||||
|
parse(ylrc, ytlrc, yrlrc, lrc, tlrc, rlrc) {
|
||||||
|
const info = {
|
||||||
|
lyric: '',
|
||||||
|
tlyric: '',
|
||||||
|
rlyric: '',
|
||||||
|
lxlyric: '',
|
||||||
|
}
|
||||||
|
if (ylrc) {
|
||||||
|
let lines = this.parseHeaderInfo(ylrc)
|
||||||
|
if (lines) {
|
||||||
|
const result = this.parseLyric(lines)
|
||||||
|
if (ytlrc) {
|
||||||
|
const lines = this.parseHeaderInfo(ytlrc)
|
||||||
|
if (lines) {
|
||||||
|
if (lines.length == result.lyricLines.length) {
|
||||||
|
info.tlyric = this.fixTimeTag(result.lyricLines, lines).join('\n')
|
||||||
|
} else info.tlyric = lines.join('\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (yrlrc) {
|
||||||
|
const lines = this.parseHeaderInfo(yrlrc)
|
||||||
|
if (lines) {
|
||||||
|
if (lines.length == result.lyricLines.length) {
|
||||||
|
info.rlyric = this.fixTimeTag(result.lyricLines, lines).join('\n')
|
||||||
|
} else info.rlyric = lines.join('\n')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeRxp = /^\[[\d:.]+\]/
|
||||||
|
const headers = lines.filter(l => timeRxp.test(l)).join('\n')
|
||||||
|
info.lyric = `${headers}\n${result.lyricLines.join('\n')}`
|
||||||
|
info.lxlyric = result.lxlyricLines.join('\n')
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lrc) {
|
||||||
|
const lines = this.parseHeaderInfo(lrc)
|
||||||
|
if (lines) info.lyric = lines.join('\n')
|
||||||
|
}
|
||||||
|
if (tlrc) {
|
||||||
|
const lines = this.parseHeaderInfo(tlrc)
|
||||||
|
if (lines) info.tlyric = lines.join('\n')
|
||||||
|
}
|
||||||
|
if (rlrc) {
|
||||||
|
const lines = this.parseHeaderInfo(rlrc)
|
||||||
|
if (lines) info.rlyric = lines.join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/Binaryify/NeteaseCloudMusicApi/pull/1523/files
|
||||||
|
// export default songmid => {
|
||||||
|
// const requestObj = httpFetch('https://music.163.com/api/linux/forward', {
|
||||||
|
// method: 'post',
|
||||||
|
// 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36',
|
||||||
|
// form: linuxapi({
|
||||||
|
// method: 'POST',
|
||||||
|
// url: 'https://music.163.com/api/song/lyric?_nmclfl=1',
|
||||||
|
// params: {
|
||||||
|
// id: songmid,
|
||||||
|
// tv: -1,
|
||||||
|
// lv: -1,
|
||||||
|
// rv: -1,
|
||||||
|
// kv: -1,
|
||||||
|
// },
|
||||||
|
// }),
|
||||||
|
// })
|
||||||
|
// requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
// if (body.code !== 200 || !body?.lrc?.lyric) return Promise.reject(new Error('Get lyric failed'))
|
||||||
|
// // console.log(body)
|
||||||
|
// return {
|
||||||
|
// lyric: body.lrc.lyric,
|
||||||
|
// tlyric: body.tlyric?.lyric ?? '',
|
||||||
|
// rlyric: body.romalrc?.lyric ?? '',
|
||||||
|
// // lxlyric: parseLyric(body.klyric.lyric),
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// return requestObj
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/lyric_new.js
|
||||||
|
export default songmid => {
|
||||||
|
const requestObj = eapiRequest('/api/song/lyric/v1', {
|
||||||
|
id: songmid,
|
||||||
|
cp: false,
|
||||||
|
tv: 0,
|
||||||
|
lv: 0,
|
||||||
|
rv: 0,
|
||||||
|
kv: 0,
|
||||||
|
yv: 0,
|
||||||
|
ytv: 0,
|
||||||
|
yrv: 0,
|
||||||
})
|
})
|
||||||
requestObj.promise = requestObj.promise.then(({ body }) => {
|
requestObj.promise = requestObj.promise.then(({ body }) => {
|
||||||
|
// console.log(body)
|
||||||
if (body.code !== 200 || !body?.lrc?.lyric) return Promise.reject(new Error('Get lyric failed'))
|
if (body.code !== 200 || !body?.lrc?.lyric) return Promise.reject(new Error('Get lyric failed'))
|
||||||
return {
|
const info = parseTools.parse(body.yrc?.lyric, body.ytlrc?.lyric, body.yromalrc?.lyric, body.lrc.lyric, body.tlyric?.lyric, body.romalrc?.lyric)
|
||||||
lyric: body.lrc.lyric,
|
// console.log(info)
|
||||||
tlyric: body.tlyric.lyric,
|
if (!info.lyric) return Promise.reject(new Error('Get lyric failed'))
|
||||||
rlyric: body.romalrc?.lyric ?? '',
|
return info
|
||||||
// lxlyric: parseLyric(body.klyric.lyric),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return requestObj
|
return requestObj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { httpFetch } from '../../request'
|
import { httpFetch } from '../../request'
|
||||||
import { weapi } from './utils/crypto'
|
import { weapi } from './utils/crypto'
|
||||||
import { formatPlayTime, sizeFormate } from '../..'
|
import { formatPlayTime, sizeFormate } from '../../index'
|
||||||
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/song_detail.js
|
// https://github.com/Binaryify/NeteaseCloudMusicApi/blob/master/module/song_detail.js
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// import { weapi } from './utils/crypto'
|
// import { weapi } from './utils/crypto'
|
||||||
import { sizeFormate, formatPlayTime } from '../../index'
|
import { sizeFormate, formatPlayTime } from '../../index'
|
||||||
// import musicDetailApi from './musicDetail'
|
// import musicDetailApi from './musicDetail'
|
||||||
import { eapiRequest } from './utils'
|
import { eapiRequest } from './utils/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
limit: 30,
|
limit: 30,
|
||||||
@ -78,11 +78,11 @@ export default {
|
|||||||
if (limit == null) limit = this.limit
|
if (limit == null) limit = this.limit
|
||||||
return this.musicSearch(str, page, limit).then(result => {
|
return this.musicSearch(str, page, limit).then(result => {
|
||||||
// console.log(result)
|
// console.log(result)
|
||||||
if (!result || result.code !== 200) return this.search(str, page, { limit }, retryNum)
|
if (!result || result.code !== 200) return this.search(str, page, limit, retryNum)
|
||||||
let list = this.handleResult(result.result.songs || [])
|
let list = this.handleResult(result.result.songs || [])
|
||||||
// console.log(list)
|
// console.log(list)
|
||||||
|
|
||||||
if (list == null) return this.search(str, page, { limit }, retryNum)
|
if (list == null) return this.search(str, page, limit, retryNum)
|
||||||
|
|
||||||
this.total = result.result.songCount || 0
|
this.total = result.result.songCount || 0
|
||||||
this.page = page
|
this.page = page
|
||||||
|
@ -153,6 +153,19 @@ const handleRequestData = async(url, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/64945178
|
||||||
|
const blobToBuffer = (blob) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new global.FileReader()
|
||||||
|
reader.onerror = reject
|
||||||
|
reader.onload = () => {
|
||||||
|
const data = reader.result.slice(reader.result.indexOf('base64,') + 7)
|
||||||
|
resolve(Buffer.from(data, 'base64'))
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(blob)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const fetchData = (url, { timeout = 15000, ...options }) => {
|
const fetchData = (url, { timeout = 15000, ...options }) => {
|
||||||
console.log('---start---', url)
|
console.log('---start---', url)
|
||||||
|
|
||||||
@ -167,7 +180,7 @@ const fetchData = (url, { timeout = 15000, ...options }) => {
|
|||||||
return global.fetch(url, {
|
return global.fetch(url, {
|
||||||
...options,
|
...options,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
}).then(resp => resp.text().then(text => {
|
}).then(resp => (options.binary ? resp.blob() : resp.text()).then(text => {
|
||||||
// console.log(options, headers, text)
|
// console.log(options, headers, text)
|
||||||
return {
|
return {
|
||||||
headers: resp.headers.map,
|
headers: resp.headers.map,
|
||||||
@ -177,11 +190,17 @@ const fetchData = (url, { timeout = 15000, ...options }) => {
|
|||||||
ok: resp.ok,
|
ok: resp.ok,
|
||||||
}
|
}
|
||||||
})).then(resp => {
|
})).then(resp => {
|
||||||
try {
|
if (options.binary) {
|
||||||
resp.body = JSON.parse(resp.body)
|
return blobToBuffer(resp.body).then(buffer => {
|
||||||
} catch (_) {
|
resp.body = buffer
|
||||||
|
return resp
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
resp.body = JSON.parse(resp.body)
|
||||||
|
} catch {}
|
||||||
|
return resp
|
||||||
}
|
}
|
||||||
return resp
|
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
// console.log(err, err.code, err.message)
|
// console.log(err, err.code, err.message)
|
||||||
return Promise.reject(err)
|
return Promise.reject(err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user