diff --git a/src/i18n/lang/en-US/player.ts b/src/i18n/lang/en-US/player.ts index 914969e..2afd8bc 100644 --- a/src/i18n/lang/en-US/player.ts +++ b/src/i18n/lang/en-US/player.ts @@ -29,6 +29,15 @@ export default { lrc: { noLrc: 'No lyrics, please enjoy' }, + reparse: { + title: 'Select Music Source', + desc: 'Click a source to directly reparse the current song. This source will be used next time this song plays.', + success: 'Reparse successful', + failed: 'Reparse failed', + warning: 'Please select a music source', + bilibiliNotSupported: 'Bilibili videos do not support reparsing', + processing: 'Processing...' + }, playBar: { expand: 'Expand Lyrics', collapse: 'Collapse Lyrics', @@ -37,6 +46,7 @@ export default { noSongPlaying: 'No song playing', eq: 'Equalizer', playList: 'Play List', + reparse: 'Reparse', playMode: { sequence: 'Sequence', loop: 'Loop', diff --git a/src/i18n/lang/zh-CN/player.ts b/src/i18n/lang/zh-CN/player.ts index d886d9d..de4adea 100644 --- a/src/i18n/lang/zh-CN/player.ts +++ b/src/i18n/lang/zh-CN/player.ts @@ -29,6 +29,15 @@ export default { lrc: { noLrc: '暂无歌词, 请欣赏' }, + reparse: { + title: '选择解析音源', + desc: '点击音源直接进行解析,下次播放此歌曲时将使用所选音源', + success: '重新解析成功', + failed: '重新解析失败', + warning: '请选择一个音源', + bilibiliNotSupported: 'B站视频不支持重新解析', + processing: '解析中...' + }, playBar: { expand: '展开歌词', collapse: '收起歌词', @@ -37,6 +46,7 @@ export default { noSongPlaying: '没有正在播放的歌曲', eq: '均衡器', playList: '播放列表', + reparse: '重新解析', playMode: { sequence: '顺序播放', loop: '循环播放', diff --git a/src/renderer/api/music.ts b/src/renderer/api/music.ts index 58ac2c8..b67dea0 100644 --- a/src/renderer/api/music.ts +++ b/src/renderer/api/music.ts @@ -88,8 +88,26 @@ export const getParsingMusicUrl = async (id: number, data: any) => { return Promise.resolve({ data: { code: 404, message: '音乐解析功能已禁用' } }); } + // 获取音源设置,优先使用歌曲自定义音源 + const songId = String(id); + const savedSource = localStorage.getItem(`song_source_${songId}`); + let enabledSources: any[] = []; + + // 如果有歌曲自定义音源,使用自定义音源 + if (savedSource) { + try { + enabledSources = JSON.parse(savedSource); + console.log(`使用歌曲 ${id} 自定义音源:`, enabledSources); + } catch (e) { + console.error('解析自定义音源失败, 使用全局设置', e); + enabledSources = settingStore.setData.enabledMusicSources || []; + } + } else { + // 没有自定义音源,使用全局音源设置 + enabledSources = settingStore.setData.enabledMusicSources || []; + } + // 检查是否选择了GD音乐台解析 - const enabledSources = settingStore.setData.enabledMusicSources || []; if (enabledSources.includes('gdmusic')) { // 获取音质设置并转换为GD音乐台格式 try { diff --git a/src/renderer/components/player/PlayBar.vue b/src/renderer/components/player/PlayBar.vue index 15f7501..9cc36c9 100644 --- a/src/renderer/components/player/PlayBar.vue +++ b/src/renderer/components/player/PlayBar.vue @@ -127,6 +127,12 @@ {{ playMusic.id ? t('player.playBar.lyric') : t('player.playBar.noSongPlaying') }} + + + {{ t('player.playBar.reparse') }} + { } .audio-button { - @apply flex items-center mx-4; + @apply flex items-center; .iconfont { - @apply text-2xl transition cursor-pointer m-4; + @apply text-2xl transition cursor-pointer mx-3; @apply hover:text-green-500; } } diff --git a/src/renderer/components/player/ReparsePopover.vue b/src/renderer/components/player/ReparsePopover.vue new file mode 100644 index 0000000..84a6b28 --- /dev/null +++ b/src/renderer/components/player/ReparsePopover.vue @@ -0,0 +1,233 @@ + + + + + \ No newline at end of file diff --git a/src/renderer/store/modules/player.ts b/src/renderer/store/modules/player.ts index 09c8420..0562f98 100644 --- a/src/renderer/store/modules/player.ts +++ b/src/renderer/store/modules/player.ts @@ -14,6 +14,7 @@ import { createDiscreteApi } from 'naive-ui'; import { useSettingsStore } from './settings'; import { useUserStore } from './user'; +import { type Platform } from '@/types/music'; const musicHistory = useMusicHistory(); const { message } = createDiscreteApi(['message']); @@ -102,6 +103,27 @@ export const getSongUrl = async ( } const numericId = typeof id === 'string' ? parseInt(id, 10) : id; + + // 检查是否有自定义音源设置 + const songId = String(id); + const savedSource = localStorage.getItem(`song_source_${songId}`); + + // 如果有自定义音源设置,直接使用getParsingMusicUrl获取URL + if (savedSource && songData.source !== 'bilibili') { + try { + console.log(`使用自定义音源解析歌曲 ID: ${songId}`); + const res = await getParsingMusicUrl(numericId, cloneDeep(songData)); + if (res && res.data && res.data.data && res.data.data.url) { + return res.data.data.url; + } + // 如果自定义音源解析失败,继续使用正常的获取流程 + console.warn('自定义音源解析失败,使用默认音源'); + } catch (error) { + console.error('自定义音源解析出错:', error); + } + } + + // 正常获取URL流程 const { data } = await getMusicUrl(numericId, isDownloaded); let url = ''; let songDetail = null; @@ -1170,6 +1192,62 @@ export const usePlayerStore = defineStore('player', () => { } }; + // 使用指定的音源重新解析当前播放的歌曲 + const reparseCurrentSong = async (sourcePlatform: Platform) => { + try { + const currentSong = playMusic.value; + if (!currentSong || !currentSong.id) { + console.warn('没有有效的播放对象'); + return false; + } + + // B站视频不支持重新解析 + if (currentSong.source === 'bilibili') { + console.warn('B站视频不支持重新解析'); + return false; + } + + // 保存用户选择的音源 + const songId = String(currentSong.id); + localStorage.setItem(`song_source_${songId}`, JSON.stringify([sourcePlatform])); + + // 停止当前播放 + const currentSound = audioService.getCurrentSound(); + if (currentSound) { + currentSound.pause(); + } + + // 重新获取歌曲URL + const numericId = typeof currentSong.id === 'string' + ? parseInt(currentSong.id, 10) + : currentSong.id; + + const res = await getParsingMusicUrl(numericId, cloneDeep(currentSong)); + if (res && res.data && res.data.data && res.data.data.url) { + // 更新URL + const newUrl = res.data.data.url; + + // 使用新URL更新播放 + const updatedMusic = { + ...currentSong, + playMusicUrl: newUrl, + expiredAt: Date.now() + 1800000 // 半小时后过期 + }; + + // 更新播放器状态并开始播放 + await setPlay(updatedMusic); + setPlayMusic(true); + + return true; + } else { + return false; + } + } catch (error) { + console.error('重新解析失败:', error); + return false; + } + }; + return { play, isPlay, @@ -1212,6 +1290,7 @@ export const usePlayerStore = defineStore('player', () => { addToFavorite, removeFromFavorite, removeFromPlayList, - playAudio + playAudio, + reparseCurrentSong }; });