166 lines
5.6 KiB
TypeScript
166 lines
5.6 KiB
TypeScript
import { encodePath } from '@common/utils/common'
|
|
import { updateListMusics } from '@renderer/store/list/action'
|
|
import { saveLyric, saveMusicUrl } from '@renderer/utils/ipc'
|
|
import { getLocalFilePath } from '@renderer/utils/music'
|
|
|
|
import {
|
|
buildLyricInfo,
|
|
getCachedLyricInfo,
|
|
getOnlineOtherSourceLyricByLocal,
|
|
getOnlineOtherSourceLyricInfo,
|
|
getOnlineOtherSourceMusicUrl,
|
|
getOnlineOtherSourceMusicUrlByLocal,
|
|
getOnlineOtherSourcePicByLocal,
|
|
getOnlineOtherSourcePicUrl,
|
|
getOtherSource,
|
|
} from './utils'
|
|
|
|
|
|
const getOtherSourceByLocal = async<T>(musicInfo: LX.Music.MusicInfoLocal, handler: (infos: LX.Music.MusicInfoOnline[]) => Promise<T>) => {
|
|
let result: LX.Music.MusicInfoOnline[] = []
|
|
result = await getOtherSource(musicInfo)
|
|
if (result.length) try { return await handler(result) } catch {}
|
|
if (musicInfo.name.includes('-')) {
|
|
const [name, singer] = musicInfo.name.split('-').map(val => val.trim())
|
|
result = await getOtherSource({
|
|
...musicInfo,
|
|
name,
|
|
singer,
|
|
}, true)
|
|
if (result.length) try { return await handler(result) } catch {}
|
|
result = await getOtherSource({
|
|
...musicInfo,
|
|
name: singer,
|
|
singer: name,
|
|
}, true)
|
|
if (result.length) try { return await handler(result) } catch {}
|
|
}
|
|
let fileName = musicInfo.meta.filePath.split(/\/|\\/).at(-1)
|
|
if (fileName) {
|
|
fileName = fileName.substring(0, fileName.lastIndexOf('.'))
|
|
if (fileName != musicInfo.name) {
|
|
if (fileName.includes('-')) {
|
|
const [name, singer] = fileName.split('-').map(val => val.trim())
|
|
result = await getOtherSource({
|
|
...musicInfo,
|
|
name,
|
|
singer,
|
|
}, true)
|
|
if (result.length) try { return await handler(result) } catch {}
|
|
result = await getOtherSource({
|
|
...musicInfo,
|
|
name: singer,
|
|
singer: name,
|
|
}, true)
|
|
} else {
|
|
result = await getOtherSource({
|
|
...musicInfo,
|
|
name: fileName,
|
|
singer: '',
|
|
}, true)
|
|
}
|
|
if (result.length) try { return await handler(result) } catch {}
|
|
}
|
|
}
|
|
|
|
throw new Error('source not found')
|
|
}
|
|
|
|
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 encodePath(path)
|
|
}
|
|
|
|
try {
|
|
return await getOnlineOtherSourceMusicUrlByLocal(musicInfo, isRefresh).then(({ url, quality, isFromCache }) => {
|
|
if (!isFromCache) void saveMusicUrl(musicInfo, quality, url)
|
|
return url
|
|
})
|
|
} catch {}
|
|
|
|
onToggleSource()
|
|
return getOtherSourceByLocal(musicInfo, async(otherSource) => {
|
|
return 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) {
|
|
const pic = await window.lx.worker.main.getMusicFilePic(musicInfo.meta.filePath)
|
|
if (pic) return pic
|
|
|
|
if (musicInfo.meta.picUrl) return musicInfo.meta.picUrl
|
|
}
|
|
|
|
try {
|
|
return await getOnlineOtherSourcePicByLocal(musicInfo).then(({ url }) => {
|
|
return url
|
|
})
|
|
} catch {}
|
|
|
|
onToggleSource()
|
|
return getOtherSourceByLocal(musicInfo, async(otherSource) => {
|
|
return 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, fileLyricInfo] = await Promise.all([getCachedLyricInfo(musicInfo), window.lx.worker.main.getMusicFileLyric(musicInfo.meta.filePath)])
|
|
if (lyricInfo?.lyric && lyricInfo.lyric != lyricInfo.rawlrcInfo.lyric) {
|
|
// 存在已编辑歌词
|
|
return buildLyricInfo({ ...lyricInfo, rawlrcInfo: fileLyricInfo ?? lyricInfo.rawlrcInfo })
|
|
}
|
|
|
|
if (fileLyricInfo) return buildLyricInfo(fileLyricInfo)
|
|
if (lyricInfo?.lyric) return buildLyricInfo(lyricInfo)
|
|
}
|
|
|
|
try {
|
|
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
return await getOnlineOtherSourceLyricByLocal(musicInfo, isRefresh).then(({ lyricInfo, isFromCache }) => {
|
|
if (!isFromCache) void saveLyric(musicInfo, lyricInfo)
|
|
return buildLyricInfo(lyricInfo)
|
|
})
|
|
} catch {}
|
|
|
|
onToggleSource()
|
|
return getOtherSourceByLocal(musicInfo, async(otherSource) => {
|
|
return getOnlineOtherSourceLyricInfo({ musicInfos: [...otherSource], onToggleSource, isRefresh }).then(async({ lyricInfo, musicInfo: targetMusicInfo, isFromCache }) => {
|
|
void saveLyric(musicInfo, lyricInfo)
|
|
|
|
if (isFromCache) return buildLyricInfo(lyricInfo)
|
|
void saveLyric(targetMusicInfo, lyricInfo)
|
|
|
|
return buildLyricInfo(lyricInfo)
|
|
})
|
|
})
|
|
}
|