From 2b1024ca2447ac84108913905e8c18450429d958 Mon Sep 17 00:00:00 2001 From: chengww Date: Sun, 26 Apr 2026 21:47:11 +0800 Subject: [PATCH] =?UTF-8?q?fix(player):=20=E9=9D=99=E9=9F=B3=E4=BF=9D?= =?UTF-8?q?=E7=95=99=E5=8E=9F=E9=9F=B3=E9=87=8F=EF=BC=8C=E8=A7=A3=E9=99=A4?= =?UTF-8?q?=E5=90=8E=E5=8F=AF=E6=81=A2=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - playerCore 新增持久化 isMuted 状态及 setMuted/toggleMute,静音时音频输出置 0 但 volume 保持不变 - 音量 > 0 时自动解除静音 - useVolumeControl 移除原 0↔30 切换;滑块/百分比展示真实音量,图标反映静音态 - 三个播放栏的音量滑块在静音时 disabled;PlayBar 百分比文字同步置灰(仅文字颜色) --- .../components/player/MiniPlayBar.vue | 9 ++++- src/renderer/components/player/PlayBar.vue | 24 +++++++++++-- .../components/player/SimplePlayBar.vue | 9 ++++- src/renderer/hooks/useVolumeControl.ts | 18 +++++----- src/renderer/store/modules/player.ts | 4 +++ src/renderer/store/modules/playerCore.ts | 36 +++++++++++++++++-- 6 files changed, 84 insertions(+), 16 deletions(-) diff --git a/src/renderer/components/player/MiniPlayBar.vue b/src/renderer/components/player/MiniPlayBar.vue index c5aab33..aa4eda7 100644 --- a/src/renderer/components/player/MiniPlayBar.vue +++ b/src/renderer/components/player/MiniPlayBar.vue @@ -69,6 +69,7 @@ v-model:value="volumeSlider" :step="0.01" :tooltip="false" + :disabled="isMuted" vertical @wheel.prevent="handleVolumeWheel" > @@ -145,7 +146,13 @@ const { navigateToArtist } = useArtist(); const { isPlaying: play, playMusicEvent, handleNext, handlePrev } = usePlaybackControl(); // 音量控制(统一通过 playerStore 管理) -const { volumeSlider, volumeIcon: getVolumeIcon, mute, handleVolumeWheel } = useVolumeControl(); +const { + isMuted, + volumeSlider, + volumeIcon: getVolumeIcon, + mute, + handleVolumeWheel +} = useVolumeControl(); // 收藏 const { isFavorite, toggleFavorite } = useFavorite(); diff --git a/src/renderer/components/player/PlayBar.vue b/src/renderer/components/player/PlayBar.vue index 66aaae8..944b1f6 100644 --- a/src/renderer/components/player/PlayBar.vue +++ b/src/renderer/components/player/PlayBar.vue @@ -99,8 +99,16 @@
-
{{ Math.round(volumeSlider) }}%
- +
+ {{ Math.round(volumeSlider) }}% +
+
@@ -198,7 +206,13 @@ const { t } = useI18n(); const { isPlaying: play, playMusicEvent, handleNext, handlePrev } = usePlaybackControl(); // 音量控制 -const { volumeSlider, volumeIcon: getVolumeIcon, mute, handleVolumeWheel } = useVolumeControl(); +const { + isMuted, + volumeSlider, + volumeIcon: getVolumeIcon, + mute, + handleVolumeWheel +} = useVolumeControl(); // 收藏 const { isFavorite, toggleFavorite } = useFavorite(); @@ -382,6 +396,10 @@ const openPlayListDrawer = () => { @apply border border-gray-200 dark:border-gray-700; @apply text-gray-800 dark:text-white; white-space: nowrap; + + &.volume-percentage-disabled { + @apply text-gray-400 dark:text-gray-500; + } } } } diff --git a/src/renderer/components/player/SimplePlayBar.vue b/src/renderer/components/player/SimplePlayBar.vue index 9898a6f..519d99d 100644 --- a/src/renderer/components/player/SimplePlayBar.vue +++ b/src/renderer/components/player/SimplePlayBar.vue @@ -68,6 +68,7 @@ v-model:value="volumeSlider" :step="1" :tooltip="false" + :disabled="isMuted" @wheel.prevent="handleVolumeWheel" > @@ -107,7 +108,13 @@ const { isPlaying: play, playMusicEvent, handleNext, handlePrev } = usePlaybackC const { playMode, playModeIcon, togglePlayMode } = usePlayMode(); // 音量控制(统一通过 playerStore 管理) -const { volumeSlider, volumeIcon: getVolumeIcon, mute, handleVolumeWheel } = useVolumeControl(); +const { + isMuted, + volumeSlider, + volumeIcon: getVolumeIcon, + mute, + handleVolumeWheel +} = useVolumeControl(); // 进度条控制 const isDragging = ref(false); diff --git a/src/renderer/hooks/useVolumeControl.ts b/src/renderer/hooks/useVolumeControl.ts index 555b3a5..6a89979 100644 --- a/src/renderer/hooks/useVolumeControl.ts +++ b/src/renderer/hooks/useVolumeControl.ts @@ -9,7 +9,10 @@ import { usePlayerStore } from '@/store/modules/player'; export function useVolumeControl() { const playerStore = usePlayerStore(); - /** 音量滑块值 (0-100) */ + /** 是否静音 */ + const isMuted = computed(() => playerStore.isMuted); + + /** 音量滑块值 (0-100),静音时仍展示原始音量 */ const volumeSlider = computed({ get: () => playerStore.volume * 100, set: (value: number) => { @@ -19,21 +22,17 @@ export function useVolumeControl() { /** 音量图标 class */ const volumeIcon = computed(() => { - if (playerStore.volume === 0) return 'ri-volume-mute-line'; + if (playerStore.isMuted || playerStore.volume === 0) return 'ri-volume-mute-line'; if (playerStore.volume <= 0.5) return 'ri-volume-down-line'; return 'ri-volume-up-line'; }); - /** 静音切换 (0 ↔ 30%) */ + /** 切换静音(保留静音前的音量) */ const mute = () => { - if (volumeSlider.value === 0) { - volumeSlider.value = 30; - } else { - volumeSlider.value = 0; - } + playerStore.toggleMute(); }; - /** 鼠标滚轮调整音量 ±5% */ + /** 鼠标滚轮调整音量 ±5%;静音时向上滚轮会自动解除静音 */ const handleVolumeWheel = (e: WheelEvent) => { const delta = e.deltaY < 0 ? 5 : -5; const newValue = Math.min(Math.max(volumeSlider.value + delta, 0), 100); @@ -41,6 +40,7 @@ export function useVolumeControl() { }; return { + isMuted, volumeSlider, volumeIcon, mute, diff --git a/src/renderer/store/modules/player.ts b/src/renderer/store/modules/player.ts index 1f7cc85..33c8639 100644 --- a/src/renderer/store/modules/player.ts +++ b/src/renderer/store/modules/player.ts @@ -41,6 +41,7 @@ export const usePlayerStore = defineStore('player', () => { musicFull, playbackRate, volume, + isMuted, userPlayIntent, isFmPlaying } = storeToRefs(playerCore); @@ -97,6 +98,7 @@ export const usePlayerStore = defineStore('player', () => { musicFull, playbackRate, volume, + isMuted, userPlayIntent, isFmPlaying, @@ -113,6 +115,8 @@ export const usePlayerStore = defineStore('player', () => { getVolume: playerCore.getVolume, increaseVolume: playerCore.increaseVolume, decreaseVolume: playerCore.decreaseVolume, + setMuted: playerCore.setMuted, + toggleMute: playerCore.toggleMute, handlePause: playerCore.handlePause, // ========== 播放列表管理 (Playlist) ========== diff --git a/src/renderer/store/modules/playerCore.ts b/src/renderer/store/modules/playerCore.ts index aa8f967..3c0ac05 100644 --- a/src/renderer/store/modules/playerCore.ts +++ b/src/renderer/store/modules/playerCore.ts @@ -20,6 +20,7 @@ export const usePlayerCoreStore = defineStore( const musicFull = ref(false); const playbackRate = ref(1.0); const volume = ref(1); + const isMuted = ref(false); const userPlayIntent = ref(false); // 用户是否想要播放 const isFmPlaying = ref(false); // 是否正在播放私人FM @@ -65,7 +66,27 @@ export const usePlayerCoreStore = defineStore( const setVolume = (newVolume: number) => { const normalizedVolume = Math.max(0, Math.min(1, newVolume)); volume.value = normalizedVolume; - audioService.setVolume(normalizedVolume); + // 用户调高音量时自动解除静音 + if (isMuted.value && normalizedVolume > 0) { + isMuted.value = false; + } + audioService.setVolume(isMuted.value ? 0 : normalizedVolume); + }; + + /** + * 设置静音状态(不改变 volume,仅控制音频输出) + */ + const setMuted = (value: boolean) => { + if (isMuted.value === value) return; + isMuted.value = value; + audioService.setVolume(isMuted.value ? 0 : volume.value); + }; + + /** + * 切换静音 + */ + const toggleMute = () => { + setMuted(!isMuted.value); }; /** @@ -169,6 +190,7 @@ export const usePlayerCoreStore = defineStore( musicFull, playbackRate, volume, + isMuted, userPlayIntent, isFmPlaying, audioOutputDeviceId, @@ -187,6 +209,8 @@ export const usePlayerCoreStore = defineStore( getVolume, increaseVolume, decreaseVolume, + setMuted, + toggleMute, handlePause, refreshAudioDevices, setAudioOutputDevice, @@ -197,7 +221,15 @@ export const usePlayerCoreStore = defineStore( persist: { key: 'player-core-store', storage: localStorage, - pick: ['playMusic', 'playMusicUrl', 'playbackRate', 'volume', 'isPlay', 'audioOutputDeviceId'] + pick: [ + 'playMusic', + 'playMusicUrl', + 'playbackRate', + 'volume', + 'isMuted', + 'isPlay', + 'audioOutputDeviceId' + ] } } );