feat: 优化音源解析功能,添加音源配置

This commit is contained in:
alger
2025-04-22 23:39:08 +08:00
parent 35b9cbfdbd
commit ed9cf9c4c5
12 changed files with 163 additions and 16 deletions
+9 -1
View File
@@ -4,6 +4,7 @@ import type { ILyric } from '@/type/lyric';
import { isElectron } from '@/utils';
import request from '@/utils/request';
import requestMusic from '@/utils/request_music';
import { cloneDeep } from 'lodash';
const { addData, getData, deleteData } = musicDB;
@@ -79,8 +80,15 @@ export const getMusicLrc = async (id: number) => {
};
export const getParsingMusicUrl = (id: number, data: any) => {
if (isElectron) {
return window.api.unblockMusic(id, data);
const settingStore = useSettingsStore();
// 如果禁用了音乐解析功能,则直接返回空结果
if (!settingStore.setData.enableMusicUnblock) {
return Promise.resolve({ data: { code: 404, message: '音乐解析功能已禁用' } });
}
return window.api.unblockMusic(id, cloneDeep(data), cloneDeep(settingStore.setData.enabledMusicSources));
}
return requestMusic.get<any>('/music', { params: { id } });
};
+2
View File
@@ -28,6 +28,8 @@ declare module 'vue' {
NEmpty: typeof import('naive-ui')['NEmpty']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGrid: typeof import('naive-ui')['NGrid']
NGridItem: typeof import('naive-ui')['NGridItem']
NIcon: typeof import('naive-ui')['NIcon']
NImage: typeof import('naive-ui')['NImage']
NInput: typeof import('naive-ui')['NInput']
+3 -2
View File
@@ -67,6 +67,7 @@ export const getSongUrl = async (
}
} catch (error) {
console.error('error', error);
url = data.data[0].url || '';
}
if (isDownloaded) {
return songDetail;
@@ -344,7 +345,7 @@ export const usePlayerStore = defineStore('player', () => {
(item: SongResult) => item.id === music.id && item.source === music.source
);
fetchSongs(playList.value, playListIndex.value + 1, playListIndex.value + 6);
fetchSongs(playList.value, playListIndex.value + 1, playListIndex.value + 3);
};
const setPlay = async (song: SongResult) => {
@@ -453,7 +454,7 @@ export const usePlayerStore = defineStore('player', () => {
}
await handlePlayMusic(prevSong);
await fetchSongs(playList.value, playListIndex.value - 5, nowPlayListIndex);
await fetchSongs(playList.value, playListIndex.value - 3, nowPlayListIndex);
};
const togglePlayMode = () => {
+100
View File
@@ -150,6 +150,39 @@
/>
</div>
<div class="set-item">
<div>
<div class="set-item-title">{{ t('settings.playback.musicSources') }}</div>
<div class="set-item-content">
<div class="flex items-center gap-2">
<n-switch v-model:value="setData.enableMusicUnblock">
<template #checked>{{ t('common.on') }}</template>
<template #unchecked>{{ t('common.off') }}</template>
</n-switch>
<span>{{ t('settings.playback.musicUnblockEnableDesc') }}</span>
</div>
<div v-if="setData.enableMusicUnblock" class="mt-2">
<div class="text-sm">
<span class="text-gray-500">{{ t('settings.playback.selectedMusicSources') }}</span>
<span v-if="musicSources.length > 0" class="text-gray-400">
{{ musicSources.map((source) => getSourceLabel(source)).join(', ') }}
</span>
<span v-else class="text-red-500 text-xs">
{{ t('settings.playback.noMusicSources') }}
</span>
</div>
</div>
</div>
</div>
<n-button
size="small"
:disabled="!setData.enableMusicUnblock"
@click="showMusicSourcesModal = true"
>
{{ t('settings.playback.configureMusicSources') }}
</n-button>
</div>
<div class="set-item">
<div>
<div class="set-item-title">{{ t('settings.playback.autoPlay') }}</div>
@@ -470,6 +503,33 @@
</n-checkbox-group>
</n-space>
</n-modal>
<!-- 音源设置弹窗 -->
<n-modal
v-model:show="showMusicSourcesModal"
preset="dialog"
:title="t('settings.playback.musicSources')"
:positive-text="t('common.confirm')"
:negative-text="t('common.cancel')"
@positive-click="showMusicSourcesModal = false"
@negative-click="showMusicSourcesModal = false"
>
<n-space vertical>
<p>{{ t('settings.playback.musicSourcesDesc') }}</p>
<n-checkbox-group v-model:value="musicSources">
<n-grid :cols="2" :x-gap="12" :y-gap="8">
<n-grid-item v-for="source in musicSourceOptions" :key="source.value">
<n-checkbox :value="source.value">
{{ source.label }}
</n-checkbox>
</n-grid-item>
</n-grid>
</n-checkbox-group>
<div v-if="musicSources.length === 0" class="text-red-500 text-sm">
{{ t('settings.playback.musicSourcesWarning') }}
</div>
</n-space>
</n-modal>
</div>
</template>
@@ -494,6 +554,11 @@ import { checkUpdate, UpdateResult } from '@/utils/update';
import config from '../../../../package.json';
// 手动定义Platform类型,避免从主进程导入的问题
type Platform = 'qq' | 'migu' | 'kugou' | 'pyncmd'| 'kuwo' | 'bilibili' | 'youtube';
// 所有平台
const ALL_PLATFORMS: Platform[] = ['migu', 'kugou', 'pyncmd', 'kuwo', 'bilibili', 'youtube'];
const settingsStore = useSettingsStore();
const userStore = useUserStore();
@@ -977,6 +1042,41 @@ onMounted(() => {
handleScroll({ target: { scrollTop: 0 } });
});
});
// 音源设置相关
const musicSourceOptions = ref([
{ label: 'MiGu音乐', value: 'migu' },
{ label: '酷狗音乐', value: 'kugou' },
{ label: 'pyncmd', value: 'pyncmd' },
{ label: '酷我音乐', value: 'kuwo' },
{ label: 'Bilibili音乐', value: 'bilibili' },
{ label: 'YouTube', value: 'youtube' }
]);
// 已选择的音源列表
const musicSources = computed({
get: () => {
if (!setData.value.enabledMusicSources) {
return ALL_PLATFORMS;
}
return setData.value.enabledMusicSources as Platform[];
},
set: (newValue: Platform[]) => {
// 确保至少选择一个音源
const valuesToSet = newValue.length > 0 ? newValue : ALL_PLATFORMS;
setData.value = {
...setData.value,
enabledMusicSources: valuesToSet
};
}
});
const showMusicSourcesModal = ref(false);
const getSourceLabel = (source: Platform) => {
const sourceLabel = musicSourceOptions.value.find(s => s.value === source)?.label;
return sourceLabel || source;
};
</script>
<style lang="scss" scoped>