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(musicInfo: LX.Music.MusicInfoLocal, handler: (infos: LX.Music.MusicInfoOnline[]) => Promise) => { 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 => { 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 => { 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 => { 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) }) }) }