v2.0.0
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
import { getDownloadFilePath } from '@renderer/utils/music'
|
||||
|
||||
import {
|
||||
getMusicUrl as getOnlineMusicUrl,
|
||||
getPicUrl as getOnlinePicUrl,
|
||||
getLyricInfo as getOnlineLyricInfo,
|
||||
} from './online'
|
||||
import { buildLyricInfo, getCachedLyricInfo } from './utils'
|
||||
|
||||
export const getMusicUrl = async({ musicInfo, isRefresh, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Download.ListItem
|
||||
isRefresh: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if (!isRefresh) {
|
||||
const path = await getDownloadFilePath(musicInfo, appSetting['download.savePath'])
|
||||
if (path) return path
|
||||
}
|
||||
|
||||
return await getOnlineMusicUrl({ musicInfo: musicInfo.metadata.musicInfo, isRefresh, onToggleSource })
|
||||
}
|
||||
|
||||
export const getPicUrl = async({ musicInfo, isRefresh, listId, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Download.ListItem
|
||||
isRefresh: boolean
|
||||
listId?: string | null
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if (!isRefresh) {
|
||||
const onlineMusicInfo = musicInfo.metadata.musicInfo
|
||||
if (onlineMusicInfo.meta.picUrl && !isRefresh) return onlineMusicInfo.meta.picUrl
|
||||
|
||||
const path = await getDownloadFilePath(musicInfo, appSetting['download.savePath'])
|
||||
if (path) {
|
||||
const pic = await window.lx.worker.main.getMusicFilePic(path)
|
||||
if (pic) return pic
|
||||
}
|
||||
}
|
||||
|
||||
return await getOnlinePicUrl({ musicInfo: musicInfo.metadata.musicInfo, isRefresh, onToggleSource }).then((url) => {
|
||||
// TODO: when listId required save url (update downloadInfo)
|
||||
|
||||
return url
|
||||
})
|
||||
}
|
||||
|
||||
export const getLyricInfo = async({ musicInfo, isRefresh, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Download.ListItem
|
||||
isRefresh: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<LX.Player.LyricInfo> => {
|
||||
if (!isRefresh) {
|
||||
const lyricInfo = await getCachedLyricInfo(musicInfo.metadata.musicInfo)
|
||||
if (lyricInfo) return await buildLyricInfo(lyricInfo)
|
||||
}
|
||||
|
||||
return getOnlineLyricInfo({
|
||||
musicInfo: musicInfo.metadata.musicInfo,
|
||||
isRefresh,
|
||||
onToggleSource,
|
||||
}).catch(async() => {
|
||||
// 尝试读取文件内歌词
|
||||
const path = await getDownloadFilePath(musicInfo, appSetting['download.savePath'])
|
||||
if (path) {
|
||||
const rawlrcInfo = await window.lx.worker.main.getMusicFileLyric(path)
|
||||
if (rawlrcInfo) return buildLyricInfo(rawlrcInfo)
|
||||
}
|
||||
|
||||
throw new Error('failed')
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// if (targetSong.key) { // 如果是已下载的歌曲
|
||||
// const filePath = path.join(appSetting['download.savePath'], targetSong.metadata.fileName)
|
||||
// // console.log(filePath)
|
||||
|
||||
import {
|
||||
getMusicUrl as getOnlineMusicUrl,
|
||||
getPicUrl as getOnlinePicUrl,
|
||||
getLyricInfo as getOnlineLyricInfo,
|
||||
} from './online'
|
||||
import {
|
||||
getMusicUrl as getDownloadMusicUrl,
|
||||
getPicUrl as getDownloadPicUrl,
|
||||
getLyricInfo as getDownloadLyricInfo,
|
||||
} from './download'
|
||||
import {
|
||||
getMusicUrl as getLocalMusicUrl,
|
||||
getPicUrl as getLocalPicUrl,
|
||||
getLyricInfo as getLocalLyricInfo,
|
||||
} from './local'
|
||||
|
||||
|
||||
export const getMusicUrl = async({
|
||||
musicInfo,
|
||||
quality,
|
||||
isRefresh = false,
|
||||
onToggleSource,
|
||||
}: {
|
||||
musicInfo: LX.Music.MusicInfo | LX.Download.ListItem
|
||||
isRefresh?: boolean
|
||||
quality?: LX.Quality
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if ('progress' in musicInfo) {
|
||||
return await getDownloadMusicUrl({ musicInfo, isRefresh, onToggleSource })
|
||||
} else if (musicInfo.source == 'local') {
|
||||
return await getLocalMusicUrl({ musicInfo, isRefresh, onToggleSource })
|
||||
} else {
|
||||
return await getOnlineMusicUrl({ musicInfo, isRefresh, quality, onToggleSource })
|
||||
}
|
||||
}
|
||||
|
||||
export const getPicPath = async({
|
||||
musicInfo,
|
||||
isRefresh = false,
|
||||
listId,
|
||||
onToggleSource,
|
||||
}: {
|
||||
musicInfo: LX.Music.MusicInfo | LX.Download.ListItem
|
||||
listId?: string | null
|
||||
isRefresh?: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if ('progress' in musicInfo) {
|
||||
return await getDownloadPicUrl({ musicInfo, isRefresh, listId, onToggleSource })
|
||||
} else if (musicInfo.source == 'local') {
|
||||
return await getLocalPicUrl({ musicInfo, isRefresh, listId, onToggleSource })
|
||||
} else {
|
||||
return await getOnlinePicUrl({ musicInfo, isRefresh, listId, onToggleSource })
|
||||
}
|
||||
}
|
||||
|
||||
export const getLyricInfo = async({
|
||||
musicInfo,
|
||||
isRefresh = false,
|
||||
onToggleSource,
|
||||
}: {
|
||||
musicInfo: LX.Music.MusicInfo | LX.Download.ListItem
|
||||
isRefresh?: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<LX.Player.LyricInfo> => {
|
||||
if ('progress' in musicInfo) {
|
||||
return await getDownloadLyricInfo({ musicInfo, isRefresh, onToggleSource })
|
||||
} else if (musicInfo.source == 'local') {
|
||||
return await getLocalLyricInfo({ musicInfo, isRefresh, onToggleSource })
|
||||
} else {
|
||||
return await getOnlineLyricInfo({ musicInfo, isRefresh, onToggleSource })
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { updateListMusics } from '@renderer/store/list/action'
|
||||
import { saveLyric, saveMusicUrl } from '@renderer/utils/ipc'
|
||||
import { getLocalFilePath } from '@renderer/utils/music'
|
||||
|
||||
import {
|
||||
buildLyricInfo,
|
||||
getCachedLyricInfo,
|
||||
getOnlineOtherSourceLyricInfo,
|
||||
getOnlineOtherSourceMusicUrl,
|
||||
getOnlineOtherSourcePicUrl,
|
||||
getOtherSource,
|
||||
} from './utils'
|
||||
|
||||
|
||||
export const getMusicUrl = async({ musicInfo, isRefresh, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Music.MusicInfoLocal
|
||||
isRefresh: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if (!isRefresh) {
|
||||
const path = await getLocalFilePath(musicInfo)
|
||||
if (path) return path
|
||||
}
|
||||
onToggleSource()
|
||||
const otherSource = await getOtherSource(musicInfo)
|
||||
if (!otherSource.length) throw new Error('source not found')
|
||||
return await getOnlineOtherSourceMusicUrl({ musicInfos: [...otherSource], onToggleSource, isRefresh }).then(({ url, quality: targetQuality, musicInfo: targetMusicInfo, isFromCache }) => {
|
||||
// saveLyric(musicInfo, data.lyricInfo)
|
||||
if (!isFromCache) void saveMusicUrl(targetMusicInfo, targetQuality, url)
|
||||
|
||||
// TODO: save url ?
|
||||
return url
|
||||
})
|
||||
}
|
||||
|
||||
export const getPicUrl = async({ musicInfo, listId, isRefresh, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Music.MusicInfoLocal
|
||||
listId?: string | null
|
||||
isRefresh: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if (!isRefresh) {
|
||||
if (musicInfo.meta.picUrl) return musicInfo.meta.picUrl
|
||||
|
||||
const pic = await window.lx.worker.main.getMusicFilePic(musicInfo.meta.filePath)
|
||||
if (pic) return pic
|
||||
}
|
||||
|
||||
onToggleSource()
|
||||
const otherSource = await getOtherSource(musicInfo)
|
||||
if (!otherSource.length) throw new Error('source not found')
|
||||
return await getOnlineOtherSourcePicUrl({ musicInfos: [...otherSource], onToggleSource, isRefresh }).then(({ url, musicInfo: targetMusicInfo, isFromCache }) => {
|
||||
if (listId) {
|
||||
musicInfo.meta.picUrl = url
|
||||
void updateListMusics([{ id: listId, musicInfo }])
|
||||
}
|
||||
|
||||
return url
|
||||
})
|
||||
}
|
||||
|
||||
export const getLyricInfo = async({ musicInfo, isRefresh, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Music.MusicInfoLocal
|
||||
isRefresh: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<LX.Player.LyricInfo> => {
|
||||
if (!isRefresh) {
|
||||
const lyricInfo = await getCachedLyricInfo(musicInfo)
|
||||
if (lyricInfo) {
|
||||
// 存在已编辑、原始歌词
|
||||
if (lyricInfo.rawlrcInfo.lyric) return await buildLyricInfo(lyricInfo)
|
||||
}
|
||||
|
||||
// 尝试读取文件内歌词
|
||||
const rawlrcInfo = await window.lx.worker.main.getMusicFileLyric(musicInfo.meta.filePath)
|
||||
if (rawlrcInfo) return buildLyricInfo(lyricInfo ? { ...lyricInfo, rawlrcInfo } : rawlrcInfo)
|
||||
}
|
||||
|
||||
onToggleSource()
|
||||
const otherSource = await getOtherSource(musicInfo)
|
||||
if (!otherSource.length) throw new Error('source not found')
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
return await getOnlineOtherSourceLyricInfo({ musicInfos: [...otherSource], onToggleSource, isRefresh }).then(({ lyricInfo, musicInfo: targetMusicInfo, isFromCache }) => {
|
||||
void saveLyric(musicInfo, lyricInfo)
|
||||
|
||||
if (isFromCache) return buildLyricInfo(lyricInfo)
|
||||
void saveLyric(targetMusicInfo, lyricInfo)
|
||||
|
||||
return buildLyricInfo(lyricInfo)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
import { updateListMusics } from '@renderer/store/list/action'
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
import {
|
||||
saveLyric,
|
||||
saveMusicUrl,
|
||||
getMusicUrl as getStoreMusicUrl,
|
||||
} from '@renderer/utils/ipc'
|
||||
import {
|
||||
buildLyricInfo,
|
||||
getPlayQuality,
|
||||
handleGetOnlineLyricInfo,
|
||||
handleGetOnlineMusicUrl,
|
||||
handleGetOnlinePicUrl,
|
||||
getCachedLyricInfo,
|
||||
} from './utils'
|
||||
|
||||
/* export const setMusicUrl = ({ musicInfo, type, url }: {
|
||||
musicInfo: LX.Music.MusicInfo
|
||||
type: LX.Quality
|
||||
url: string
|
||||
}) => {
|
||||
saveMusicUrl(musicInfo, type, url)
|
||||
}
|
||||
|
||||
export const setPic = (datas: {
|
||||
listId: string
|
||||
musicInfo: LX.Music.MusicInfo
|
||||
url: string
|
||||
}) => {
|
||||
datas.musicInfo.img = datas.url
|
||||
updateMusicInfo({
|
||||
listId: datas.listId,
|
||||
id: datas.musicInfo.songmid,
|
||||
data: { img: datas.url },
|
||||
musicInfo: datas.musicInfo,
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
export const getMusicUrl = async({ musicInfo, quality, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
quality?: LX.Quality
|
||||
isRefresh: boolean
|
||||
allowToggleSource?: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
// if (!musicInfo._types[type]) {
|
||||
// // 兼容旧版酷我源搜索列表过滤128k音质的bug
|
||||
// if (!(musicInfo.source == 'kw' && type == '128k')) throw new Error('该歌曲没有可播放的音频')
|
||||
|
||||
// // return Promise.reject(new Error('该歌曲没有可播放的音频'))
|
||||
// }
|
||||
const targetQuality = quality ?? getPlayQuality(appSetting['player.highQuality'], musicInfo)
|
||||
const cachedUrl = await getStoreMusicUrl(musicInfo, targetQuality)
|
||||
if (cachedUrl && !isRefresh) return cachedUrl
|
||||
|
||||
return await handleGetOnlineMusicUrl({ musicInfo, quality, onToggleSource, isRefresh, allowToggleSource }).then(({ url, quality: targetQuality, musicInfo: targetMusicInfo, isFromCache }) => {
|
||||
if (targetMusicInfo.id != musicInfo.id && !isFromCache) void saveMusicUrl(targetMusicInfo, targetQuality, url)
|
||||
void saveMusicUrl(musicInfo, targetQuality, url)
|
||||
return url
|
||||
})
|
||||
}
|
||||
|
||||
export const getPicUrl = async({ musicInfo, listId, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
listId?: string | null
|
||||
isRefresh: boolean
|
||||
allowToggleSource?: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<string> => {
|
||||
if (musicInfo.meta.picUrl && !isRefresh) return musicInfo.meta.picUrl
|
||||
return await handleGetOnlinePicUrl({ musicInfo, onToggleSource, isRefresh, allowToggleSource }).then(({ url, musicInfo: targetMusicInfo, isFromCache }) => {
|
||||
// picRequest = null
|
||||
if (listId) {
|
||||
musicInfo.meta.picUrl = url
|
||||
void updateListMusics([{ id: listId, musicInfo }])
|
||||
}
|
||||
// savePic({ musicInfo, url, listId })
|
||||
return url
|
||||
})
|
||||
}
|
||||
export const getLyricInfo = async({ musicInfo, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: {
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
isRefresh: boolean
|
||||
allowToggleSource?: boolean
|
||||
onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<LX.Player.LyricInfo> => {
|
||||
if (!isRefresh) {
|
||||
const lyricInfo = await getCachedLyricInfo(musicInfo)
|
||||
if (lyricInfo) return await buildLyricInfo(lyricInfo)
|
||||
}
|
||||
|
||||
// lrcRequest = music[musicInfo.source].getLyric(musicInfo)
|
||||
return await handleGetOnlineLyricInfo({ musicInfo, onToggleSource, isRefresh, allowToggleSource }).then(async({ lyricInfo, musicInfo: targetMusicInfo, isFromCache }) => {
|
||||
// lrcRequest = null
|
||||
if (isFromCache) return await buildLyricInfo(lyricInfo)
|
||||
if (targetMusicInfo.id == musicInfo.id) void saveLyric(musicInfo, lyricInfo)
|
||||
else void saveLyric(targetMusicInfo, lyricInfo)
|
||||
|
||||
return await buildLyricInfo(lyricInfo)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
import { qualityList } from '@renderer/store'
|
||||
import { assertApiSupport } from '@renderer/store/utils'
|
||||
import musicSdk from '@renderer/utils/musicSdk'
|
||||
import {
|
||||
getOtherSource as getOtherSourceFromStore,
|
||||
saveOtherSource as saveOtherSourceFromStore,
|
||||
getMusicUrl as getStoreMusicUrl,
|
||||
getPlayerLyric as getStoreLyric,
|
||||
} from '@renderer/utils/ipc'
|
||||
import { appSetting } from '@renderer/store/setting'
|
||||
import { langS2T, toNewMusicInfo, toOldMusicInfo } from '@renderer/utils'
|
||||
|
||||
|
||||
const getOtherSourcePromises = new Map()
|
||||
export const existTimeExp = /\[\d{1,2}:.*\d{1,4}\]/
|
||||
|
||||
export const getOtherSource = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListItem, isRefresh = false): Promise<LX.Music.MusicInfoOnline[]> => {
|
||||
if (!isRefresh) {
|
||||
const cachedInfo = await getOtherSourceFromStore(musicInfo.id)
|
||||
if (cachedInfo.length) return cachedInfo
|
||||
}
|
||||
let key: string
|
||||
let searchMusicInfo: {
|
||||
name: string
|
||||
singer: string
|
||||
source: string
|
||||
albumName: string
|
||||
interval: string
|
||||
}
|
||||
if ('progress' in musicInfo) {
|
||||
key = `local_${musicInfo.id}`
|
||||
searchMusicInfo = {
|
||||
name: musicInfo.metadata.musicInfo.name,
|
||||
singer: musicInfo.metadata.musicInfo.singer,
|
||||
source: musicInfo.metadata.musicInfo.source,
|
||||
albumName: musicInfo.metadata.musicInfo.meta.albumName,
|
||||
interval: musicInfo.metadata.musicInfo.interval ?? '',
|
||||
}
|
||||
} else {
|
||||
key = `${musicInfo.source}_${musicInfo.id}`
|
||||
searchMusicInfo = {
|
||||
name: musicInfo.name,
|
||||
singer: musicInfo.singer,
|
||||
source: musicInfo.source,
|
||||
albumName: musicInfo.meta.albumName,
|
||||
interval: musicInfo.interval ?? '',
|
||||
}
|
||||
}
|
||||
if (getOtherSourcePromises.has(key)) return getOtherSourcePromises.get(key)
|
||||
|
||||
const promise = musicSdk.findMusic(searchMusicInfo).then((otherSource) => {
|
||||
const sources: LX.Music.MusicInfoOnline[] = otherSource.map(toNewMusicInfo)
|
||||
if (sources.length) void saveOtherSourceFromStore(musicInfo.id, sources)
|
||||
return sources
|
||||
}).finally(() => {
|
||||
if (getOtherSourcePromises.has(key)) getOtherSourcePromises.delete(key)
|
||||
})
|
||||
getOtherSourcePromises.set(key, promise)
|
||||
return promise
|
||||
}
|
||||
|
||||
|
||||
export const buildLyricInfo = async(lyricInfo: MakeOptional<LX.Player.LyricInfo, 'rawlrcInfo'>): Promise<LX.Player.LyricInfo> => {
|
||||
if (!appSetting['player.isS2t']) {
|
||||
// @ts-expect-error
|
||||
if (lyricInfo.rawlrcInfo) return lyricInfo
|
||||
return { ...lyricInfo, rawlrcInfo: { ...lyricInfo } }
|
||||
}
|
||||
|
||||
if (appSetting['player.isS2t']) {
|
||||
const tasks = [
|
||||
lyricInfo.lyric ? window.lx.worker.main.langS2t(lyricInfo.lyric) : Promise.resolve(''),
|
||||
lyricInfo.tlyric ? langS2T(lyricInfo.tlyric) : Promise.resolve(''),
|
||||
lyricInfo.rlyric ? langS2T(lyricInfo.rlyric) : Promise.resolve(''),
|
||||
lyricInfo.lxlyric ? langS2T(lyricInfo.lxlyric) : Promise.resolve(''),
|
||||
]
|
||||
if (lyricInfo.rawlrcInfo) {
|
||||
tasks.push(lyricInfo.lyric ? window.lx.worker.main.langS2t(lyricInfo.lyric) : Promise.resolve(''))
|
||||
tasks.push(lyricInfo.tlyric ? window.lx.worker.main.langS2t(lyricInfo.tlyric) : Promise.resolve(''))
|
||||
tasks.push(lyricInfo.rlyric ? window.lx.worker.main.langS2t(lyricInfo.rlyric) : Promise.resolve(''))
|
||||
tasks.push(lyricInfo.lxlyric ? window.lx.worker.main.langS2t(lyricInfo.lxlyric) : Promise.resolve(''))
|
||||
}
|
||||
return await Promise.all(tasks).then(([lyric, tlyric, rlyric, lxlyric, lyric_raw, tlyric_raw, rlyric_raw, lxlyric_raw]) => {
|
||||
const rawlrcInfo = lyric_raw ? {
|
||||
lyric: lyric_raw,
|
||||
tlyric: tlyric_raw,
|
||||
rlyric: rlyric_raw,
|
||||
lxlyric: lxlyric_raw,
|
||||
} : {
|
||||
lyric,
|
||||
tlyric,
|
||||
rlyric,
|
||||
lxlyric,
|
||||
}
|
||||
return {
|
||||
lyric,
|
||||
tlyric,
|
||||
rlyric,
|
||||
lxlyric,
|
||||
rawlrcInfo,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
return lyricInfo.rawlrcInfo ? lyricInfo : { ...lyricInfo, rawlrcInfo: { ...lyricInfo } }
|
||||
}
|
||||
|
||||
export const getCachedLyricInfo = async(musicInfo: LX.Music.MusicInfo): Promise<LX.Player.LyricInfo | null> => {
|
||||
let lrcInfo = await getStoreLyric(musicInfo)
|
||||
// lrcInfo = {}
|
||||
if (existTimeExp.test(lrcInfo.lyric) && lrcInfo.tlyric != null) {
|
||||
// if (musicInfo.lrc.startsWith('\ufeff[id:$00000000]')) {
|
||||
// let str = musicInfo.lrc.replace('\ufeff[id:$00000000]\n', '')
|
||||
// commit('setLrc', { musicInfo, lyric: str, tlyric: musicInfo.tlrc, lxlyric: musicInfo.tlrc })
|
||||
// } else if (musicInfo.lrc.startsWith('[id:$00000000]')) {
|
||||
// let str = musicInfo.lrc.replace('[id:$00000000]\n', '')
|
||||
// commit('setLrc', { musicInfo, lyric: str, tlyric: musicInfo.tlrc, lxlyric: musicInfo.tlrc })
|
||||
// }
|
||||
|
||||
if (lrcInfo.lxlyric == null) {
|
||||
switch (musicInfo.source) {
|
||||
case 'kg':
|
||||
case 'kw':
|
||||
case 'mg':
|
||||
break
|
||||
default:
|
||||
return lrcInfo
|
||||
}
|
||||
} else if (lrcInfo.rlyric == null) {
|
||||
if (!['wy', 'kg'].includes(musicInfo.source)) return lrcInfo
|
||||
} else return lrcInfo
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const getPlayQuality = (highQuality: boolean, musicInfo: LX.Music.MusicInfoOnline): LX.Quality => {
|
||||
let type: LX.Quality = '128k'
|
||||
let list = qualityList.value[musicInfo.source]
|
||||
if (highQuality && musicInfo.meta._qualitys['320k'] && list && list.includes('320k')) type = '320k'
|
||||
return type
|
||||
}
|
||||
|
||||
export const getOnlineOtherSourceMusicUrl = async({ musicInfos, quality, onToggleSource, isRefresh, retryedSource = [] }: {
|
||||
musicInfos: LX.Music.MusicInfoOnline[]
|
||||
quality?: LX.Quality
|
||||
onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
isRefresh: boolean
|
||||
retryedSource?: LX.OnlineSource[]
|
||||
}): Promise<{
|
||||
url: string
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
quality: LX.Quality
|
||||
isFromCache: boolean
|
||||
}> => {
|
||||
let musicInfo: LX.Music.MusicInfoOnline | null = null
|
||||
let itemQuality: LX.Quality | null = null
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while (musicInfo = (musicInfos.shift() as LX.Music.MusicInfoOnline)) {
|
||||
if (retryedSource.includes(musicInfo.source)) continue
|
||||
retryedSource.push(musicInfo.source)
|
||||
if (!assertApiSupport(musicInfo.source)) continue
|
||||
itemQuality = quality ?? getPlayQuality(appSetting['player.highQuality'], musicInfo)
|
||||
if (!musicInfo.meta._qualitys[itemQuality]) continue
|
||||
|
||||
console.log('try toggle to: ', musicInfo.source, musicInfo.name, musicInfo.singer, musicInfo.interval)
|
||||
onToggleSource(musicInfo)
|
||||
break
|
||||
}
|
||||
if (!musicInfo || !itemQuality) throw new Error(window.i18n.t('toggle_source_failed'))
|
||||
|
||||
const cachedUrl = await getStoreMusicUrl(musicInfo, itemQuality)
|
||||
if (cachedUrl && !isRefresh) return { url: cachedUrl, musicInfo, quality: itemQuality, isFromCache: true }
|
||||
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = musicSdk[musicInfo.source].getMusicUrl(toOldMusicInfo(musicInfo), itemQuality).promise
|
||||
} catch (err: any) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
retryedSource.includes(musicInfo.source)
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
return reqPromise.then(({ url, type }: { url: string, type: LX.Quality }) => {
|
||||
return { musicInfo, url, quality: type, isFromCache: false }
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
return getOnlineOtherSourceMusicUrl({ musicInfos, quality, onToggleSource, isRefresh, retryedSource })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线音乐URL
|
||||
*/
|
||||
export const handleGetOnlineMusicUrl = async({ musicInfo, quality, onToggleSource, isRefresh, allowToggleSource }: {
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
quality?: LX.Quality
|
||||
isRefresh: boolean
|
||||
allowToggleSource: boolean
|
||||
onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
}): Promise<{
|
||||
url: string
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
quality: LX.Quality
|
||||
isFromCache: boolean
|
||||
}> => {
|
||||
// console.log(musicInfo.source)
|
||||
const targetQuality = quality ?? getPlayQuality(appSetting['player.highQuality'], musicInfo)
|
||||
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = musicSdk[musicInfo.source].getMusicUrl(toOldMusicInfo(musicInfo), targetQuality).promise
|
||||
} catch (err: any) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.then(({ url, type }: { url: string, type: LX.Quality }) => {
|
||||
return { musicInfo, url, quality: type, isFromCache: false }
|
||||
}).catch(async(err: any) => {
|
||||
console.log(err)
|
||||
if (!allowToggleSource) throw err
|
||||
onToggleSource()
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
return await getOtherSource(musicInfo).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
return getOnlineOtherSourceMusicUrl({
|
||||
musicInfos: [...otherSource],
|
||||
onToggleSource,
|
||||
quality,
|
||||
isRefresh,
|
||||
retryedSource: [musicInfo.source],
|
||||
})
|
||||
}
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const getOnlineOtherSourcePicUrl = async({ musicInfos, onToggleSource, isRefresh, retryedSource = [] }: {
|
||||
musicInfos: LX.Music.MusicInfoOnline[]
|
||||
onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
isRefresh: boolean
|
||||
retryedSource?: LX.OnlineSource[]
|
||||
}): Promise<{
|
||||
url: string
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
isFromCache: boolean
|
||||
}> => {
|
||||
let musicInfo: LX.Music.MusicInfoOnline | null = null
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while (musicInfo = (musicInfos.shift() as LX.Music.MusicInfoOnline)) {
|
||||
if (retryedSource.includes(musicInfo.source)) continue
|
||||
retryedSource.push(musicInfo.source)
|
||||
// if (!assertApiSupport(musicInfo.source)) continue
|
||||
console.log('try toggle to: ', musicInfo.source, musicInfo.name, musicInfo.singer, musicInfo.interval)
|
||||
onToggleSource(musicInfo)
|
||||
break
|
||||
}
|
||||
if (!musicInfo) throw new Error(window.i18n.t('toggle_source_failed'))
|
||||
|
||||
if (musicInfo.meta.picUrl && !isRefresh) return { musicInfo, url: musicInfo.meta.picUrl, isFromCache: true }
|
||||
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = musicSdk[musicInfo.source].getPic(toOldMusicInfo(musicInfo)).promise
|
||||
} catch (err: any) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
retryedSource.includes(musicInfo.source)
|
||||
return reqPromise.then((url: string) => {
|
||||
return { musicInfo, url, isFromCache: false }
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
return getOnlineOtherSourcePicUrl({ musicInfos, onToggleSource, isRefresh, retryedSource })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线歌曲封面
|
||||
*/
|
||||
export const handleGetOnlinePicUrl = async({ musicInfo, isRefresh, onToggleSource, allowToggleSource }: {
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
isRefresh: boolean
|
||||
allowToggleSource: boolean
|
||||
}): Promise<{
|
||||
url: string
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
isFromCache: boolean
|
||||
}> => {
|
||||
// console.log(musicInfo.source)
|
||||
let reqPromise
|
||||
try {
|
||||
reqPromise = musicSdk[musicInfo.source].getPic(toOldMusicInfo(musicInfo)).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.then((url: string) => {
|
||||
return { musicInfo, url, isFromCache: false }
|
||||
}).catch(async(err: any) => {
|
||||
console.log(err)
|
||||
if (!allowToggleSource) throw err
|
||||
onToggleSource()
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
return await getOtherSource(musicInfo).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
return getOnlineOtherSourcePicUrl({
|
||||
musicInfos: [...otherSource],
|
||||
onToggleSource,
|
||||
isRefresh,
|
||||
retryedSource: [musicInfo.source],
|
||||
})
|
||||
}
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const getOnlineOtherSourceLyricInfo = async({ musicInfos, onToggleSource, isRefresh, retryedSource = [] }: {
|
||||
musicInfos: LX.Music.MusicInfoOnline[]
|
||||
onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
isRefresh: boolean
|
||||
retryedSource?: LX.OnlineSource[]
|
||||
}): Promise<{
|
||||
lyricInfo: LX.Music.LyricInfo | LX.Player.LyricInfo
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
isFromCache: boolean
|
||||
}> => {
|
||||
let musicInfo: LX.Music.MusicInfoOnline | null = null
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while (musicInfo = (musicInfos.shift() as LX.Music.MusicInfoOnline)) {
|
||||
if (retryedSource.includes(musicInfo.source)) continue
|
||||
retryedSource.push(musicInfo.source)
|
||||
// if (!assertApiSupport(musicInfo.source)) continue
|
||||
console.log('try toggle to: ', musicInfo.source, musicInfo.name, musicInfo.singer, musicInfo.interval)
|
||||
onToggleSource(musicInfo)
|
||||
break
|
||||
}
|
||||
if (!musicInfo) throw new Error(window.i18n.t('toggle_source_failed'))
|
||||
|
||||
if (!isRefresh) {
|
||||
const lyricInfo = await getCachedLyricInfo(musicInfo)
|
||||
if (lyricInfo) return { musicInfo, lyricInfo, isFromCache: true }
|
||||
}
|
||||
|
||||
let reqPromise
|
||||
try {
|
||||
// TODO: remove any type
|
||||
reqPromise = (musicSdk[musicInfo.source].getLyric(toOldMusicInfo(musicInfo)) as any).promise
|
||||
} catch (err: any) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
retryedSource.includes(musicInfo.source)
|
||||
return reqPromise.then((lyricInfo: LX.Music.LyricInfo) => {
|
||||
return existTimeExp.test(lyricInfo.lyric) ? {
|
||||
lyricInfo,
|
||||
musicInfo,
|
||||
isFromCache: false,
|
||||
} : Promise.reject(new Error('failed'))
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
}).catch((err: any) => {
|
||||
console.log(err)
|
||||
return getOnlineOtherSourceLyricInfo({ musicInfos, onToggleSource, isRefresh, retryedSource })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线歌词信息
|
||||
*/
|
||||
export const handleGetOnlineLyricInfo = async({ musicInfo, onToggleSource, isRefresh, allowToggleSource }: {
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
onToggleSource: (musicInfo?: LX.Music.MusicInfoOnline) => void
|
||||
isRefresh: boolean
|
||||
allowToggleSource: boolean
|
||||
}): Promise<{
|
||||
musicInfo: LX.Music.MusicInfoOnline
|
||||
lyricInfo: LX.Music.LyricInfo | LX.Player.LyricInfo
|
||||
isFromCache: boolean
|
||||
}> => {
|
||||
// console.log(musicInfo.source)
|
||||
let reqPromise
|
||||
try {
|
||||
// TODO: remove any type
|
||||
reqPromise = (musicSdk[musicInfo.source].getLyric(toOldMusicInfo(musicInfo)) as any).promise
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.then((lyricInfo: LX.Music.LyricInfo) => {
|
||||
return existTimeExp.test(lyricInfo.lyric) ? {
|
||||
musicInfo,
|
||||
lyricInfo,
|
||||
isFromCache: false,
|
||||
} : Promise.reject(new Error('failed'))
|
||||
}).catch(async(err: any) => {
|
||||
console.log(err)
|
||||
if (!allowToggleSource) throw err
|
||||
|
||||
onToggleSource()
|
||||
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
||||
return await getOtherSource(musicInfo).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
return getOnlineOtherSourceLyricInfo({
|
||||
musicInfos: [...otherSource],
|
||||
onToggleSource,
|
||||
isRefresh,
|
||||
retryedSource: [musicInfo.source],
|
||||
})
|
||||
}
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user