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'
+ ]
}
}
);