新增自动换源下载功能
This commit is contained in:
@@ -3,7 +3,15 @@ import fs from 'fs'
|
||||
import path from 'path'
|
||||
import music from '../../utils/music'
|
||||
import { getMusicType } from '../../utils/music/utils'
|
||||
import { setMeta, saveLrc, getLyric, setLyric, getMusicUrl, setMusicUrl } from '../../utils'
|
||||
import {
|
||||
setMeta,
|
||||
saveLrc,
|
||||
getLyric as getLyricFromStorage,
|
||||
setLyric,
|
||||
getMusicUrl as getMusicUrlFormStorage,
|
||||
setMusicUrl,
|
||||
assertApiSupport,
|
||||
} from '../../utils'
|
||||
|
||||
// state
|
||||
const state = {
|
||||
@@ -147,8 +155,33 @@ const pauseTasks = async(store, list, runs = []) => {
|
||||
await pauseTasks(store, list, runs)
|
||||
}
|
||||
|
||||
const getUrl = async(downloadInfo, isRefresh) => {
|
||||
const cachedUrl = await getMusicUrl(downloadInfo.musicInfo, downloadInfo.type)
|
||||
const handleGetMusicUrl = function(musicInfo, type, retryedSource = [], originMusic) {
|
||||
// console.log(musicInfo.source)
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getMusicUrl(musicInfo, type).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source) || !assertApiSupport(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return handleGetMusicUrl.call(this, item, type, retryedSource, originMusic)
|
||||
}
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const getMusicUrl = async function(downloadInfo, isUseOtherSource, isRefresh) {
|
||||
const cachedUrl = await getMusicUrlFormStorage(downloadInfo.musicInfo, downloadInfo.type)
|
||||
if (!downloadInfo.musicInfo._types[downloadInfo.type]) {
|
||||
// 兼容旧版酷我源搜索列表过滤128k音质的bug
|
||||
if (!(downloadInfo.musicInfo.source == 'kw' && downloadInfo.type == '128k')) throw new Error('该歌曲没有可下载的音频')
|
||||
@@ -157,11 +190,62 @@ const getUrl = async(downloadInfo, isRefresh) => {
|
||||
}
|
||||
return cachedUrl && !isRefresh
|
||||
? cachedUrl
|
||||
: music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise.then(({ url }) => {
|
||||
: (
|
||||
isUseOtherSource
|
||||
? handleGetMusicUrl.call(this, downloadInfo.musicInfo, downloadInfo.type)
|
||||
: music[downloadInfo.musicInfo.source].getMusicUrl(downloadInfo.musicInfo, downloadInfo.type).promise
|
||||
).then(({ url }) => {
|
||||
setMusicUrl(downloadInfo.musicInfo, downloadInfo.type, url)
|
||||
return url
|
||||
})
|
||||
}
|
||||
const getPic = function(musicInfo, retryedSource = [], originMusic) {
|
||||
// console.log(musicInfo.source)
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getPic(musicInfo).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return getPic.call(this, item, retryedSource, originMusic)
|
||||
}
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
const getLyric = function(musicInfo, retryedSource = [], originMusic) {
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getLyric(musicInfo).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return getLyric.call(this, item, retryedSource, originMusic)
|
||||
}
|
||||
}
|
||||
return Promise.reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 修复 1.1.x版本 酷狗源歌词格式
|
||||
const fixKgLyric = lrc => /\[00:\d\d:\d\d.\d+\]/.test(lrc) ? lrc.replace(/(?:\[00:(\d\d:\d\d.\d+\]))/gm, '[$1') : lrc
|
||||
@@ -172,22 +256,30 @@ const fixKgLyric = lrc => /\[00:\d\d:\d\d.\d+\]/.test(lrc) ? lrc.replace(/(?:\[0
|
||||
* @param {*} filePath
|
||||
* @param {*} isEmbedPic // 是否嵌入图片
|
||||
*/
|
||||
const saveMeta = (downloadInfo, filePath, isEmbedPic, isEmbedLyric) => {
|
||||
const saveMeta = function(downloadInfo, filePath, isUseOtherSource, isEmbedPic, isEmbedLyric) {
|
||||
if (downloadInfo.type === 'ape') return
|
||||
const tasks = [
|
||||
isEmbedPic
|
||||
? downloadInfo.musicInfo.img
|
||||
? Promise.resolve(downloadInfo.musicInfo.img)
|
||||
: music[downloadInfo.musicInfo.source].getPic(downloadInfo.musicInfo).promise.catch(err => {
|
||||
: (
|
||||
isUseOtherSource
|
||||
? getPic.call(this, downloadInfo.musicInfo)
|
||||
: music[downloadInfo.musicInfo.source].getPic(downloadInfo.musicInfo).promise
|
||||
).catch(err => {
|
||||
console.log(err)
|
||||
return null
|
||||
})
|
||||
: Promise.resolve(),
|
||||
isEmbedLyric
|
||||
? getLyric(downloadInfo.musicInfo).then(lrcInfo => {
|
||||
? getLyricFromStorage(downloadInfo.musicInfo).then(lrcInfo => {
|
||||
return lrcInfo.lyric
|
||||
? Promise.resolve({ lyric: lrcInfo.lyric, tlyric: lrcInfo.tlyric || '' })
|
||||
: music[downloadInfo.musicInfo.source].getLyric(downloadInfo.musicInfo).promise.then(({ lyric, tlyric, lxlyric }) => {
|
||||
: (
|
||||
isUseOtherSource
|
||||
? getLyric.call(this, downloadInfo.musicInfo)
|
||||
: music[downloadInfo.musicInfo.source].getLyric(downloadInfo.musicInfo).promise
|
||||
).then(({ lyric, tlyric, lxlyric }) => {
|
||||
setLyric(downloadInfo.musicInfo, { lyric, tlyric, lxlyric })
|
||||
return { lyric, tlyric, lxlyric }
|
||||
}).catch(err => {
|
||||
@@ -231,9 +323,9 @@ const downloadLyric = (downloadInfo, filePath) => {
|
||||
})
|
||||
}
|
||||
|
||||
const refreshUrl = function(commit, downloadInfo) {
|
||||
const refreshUrl = function(commit, downloadInfo, isUseOtherSource) {
|
||||
commit('setStatusText', { downloadInfo, text: '链接失效,正在刷新链接' })
|
||||
getUrl(downloadInfo, true).then(url => {
|
||||
getMusicUrl.call(this, downloadInfo, isUseOtherSource, true).then(url => {
|
||||
commit('updateUrl', { downloadInfo, url })
|
||||
commit('setStatusText', { downloadInfo, text: '链接刷新成功' })
|
||||
const dl = dls[downloadInfo.key]
|
||||
@@ -341,7 +433,7 @@ const actions = {
|
||||
commit('onCompleted', downloadInfo)
|
||||
dispatch('startTask')
|
||||
|
||||
saveMeta(downloadInfo, downloadInfo.filePath, rootState.setting.download.isEmbedPic, rootState.setting.download.isEmbedLyric)
|
||||
saveMeta.call(_this, downloadInfo, downloadInfo.filePath, rootState.setting.download.isUseOtherSource, rootState.setting.download.isEmbedPic, rootState.setting.download.isEmbedLyric)
|
||||
if (rootState.setting.download.isDownloadLrc) downloadLyric(downloadInfo, downloadInfo.filePath)
|
||||
console.log('on complate')
|
||||
},
|
||||
@@ -358,7 +450,8 @@ const actions = {
|
||||
return
|
||||
}
|
||||
if (err.code == 'ENOTFOUND') {
|
||||
refreshUrl.call(_this, commit, downloadInfo)
|
||||
commit('onError', { downloadInfo, errorMsg: '链接失效' })
|
||||
refreshUrl.call(_this, commit, downloadInfo, rootState.setting.download.isUseOtherSource)
|
||||
} else {
|
||||
console.log('Download failed, Attempting Retry')
|
||||
dls[downloadInfo.key].start()
|
||||
@@ -375,7 +468,13 @@ const actions = {
|
||||
case 401:
|
||||
case 403:
|
||||
case 410:
|
||||
refreshUrl.call(_this, commit, downloadInfo)
|
||||
commit('onError', { downloadInfo, errorMsg: '链接失效' })
|
||||
refreshUrl.call(_this, commit, downloadInfo, rootState.setting.download.isUseOtherSource)
|
||||
break
|
||||
default:
|
||||
dls[downloadInfo.key].start()
|
||||
commit('setStatusText', { downloadInfo, text: '正在重试' })
|
||||
break
|
||||
}
|
||||
},
|
||||
onStart() {
|
||||
@@ -394,7 +493,7 @@ const actions = {
|
||||
commit('setStatusText', { downloadInfo, text: '获取URL中...' })
|
||||
let p = options.url
|
||||
? Promise.resolve()
|
||||
: getUrl(downloadInfo).then(url => {
|
||||
: getMusicUrl.call(this, downloadInfo, rootState.setting.download.isUseOtherSource).then(url => {
|
||||
commit('updateUrl', { downloadInfo, url })
|
||||
if (!url) return Promise.reject(new Error('获取URL失败'))
|
||||
options.url = url
|
||||
|
||||
@@ -68,16 +68,16 @@ const filterList = async({ playedList, listInfo, savePath, commit }) => {
|
||||
|
||||
const getPic = function(musicInfo, retryedSource = [], originMusic) {
|
||||
// console.log(musicInfo.source)
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getPic(musicInfo).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.promise.catch(err => {
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
return this.dispatch('list/getOtherSource', musicInfo).then(otherSource => {
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
@@ -91,16 +91,16 @@ const getPic = function(musicInfo, retryedSource = [], originMusic) {
|
||||
})
|
||||
}
|
||||
const getLyric = function(musicInfo, retryedSource = [], originMusic) {
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = music[musicInfo.source].getLyric(musicInfo).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.promise.catch(err => {
|
||||
return reqPromise.catch(err => {
|
||||
if (!retryedSource.includes(musicInfo.source)) retryedSource.push(musicInfo.source)
|
||||
return this.dispatch('list/getOtherSource', musicInfo).then(otherSource => {
|
||||
if (!originMusic) originMusic = musicInfo
|
||||
return this.dispatch('list/getOtherSource', originMusic).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
|
||||
Reference in New Issue
Block a user