From 052af7c42079a0a85ff858de358a61c14a8b7539 Mon Sep 17 00:00:00 2001 From: Simon Slamka Date: Mon, 27 Jul 2026 00:51:21 +0300 Subject: [PATCH] Revert "feat(player): set right ctrl vol max to mpv's vol max if player==local (#2198)" (#2288) This reverts commit ddd45ad5ba94fa5c3dbe1757ccc966d7f87effd7. --- src/main/features/core/player/index.ts | 7 +-- src/main/features/linux/mpris.ts | 12 ++-- .../audio-player/engine/mpv-player-engine.tsx | 6 +- .../player/audio-player/utils/volume.ts | 58 ------------------- .../player/components/right-controls.tsx | 16 +++-- .../features/player/hooks/use-mpris.ts | 6 +- src/renderer/store/player.store.ts | 5 +- src/renderer/store/settings.store.ts | 7 --- src/shared/constants/volume.ts | 10 ---- 9 files changed, 21 insertions(+), 106 deletions(-) delete mode 100644 src/renderer/features/player/audio-player/utils/volume.ts delete mode 100644 src/shared/constants/volume.ts diff --git a/src/main/features/core/player/index.ts b/src/main/features/core/player/index.ts index a9491a5ce..a09a13fa0 100644 --- a/src/main/features/core/player/index.ts +++ b/src/main/features/core/player/index.ts @@ -10,7 +10,6 @@ import log from '../../../logger'; import { store } from '../settings'; import { isMacOS, isWindows } from '/@/main/env'; -import { MPV_VOLUME_MAX_CEILING } from '/@/shared/constants/volume'; import { PlayerData } from '/@/shared/types/domain-types'; declare module 'node-mpv'; @@ -504,12 +503,10 @@ ipcMain.on('player-auto-next', async (_event, url?: string) => { } }); -// Sets the volume to the given value. mpv clamps to its effective --volume-max, -// so the upper bound here is just a sanity guard; mpv itself is the final -// authority on how loud it will actually go. +// Sets the volume to the given value (0-100) ipcMain.on('player-volume', async (_event, value: number) => { try { - if (value == null || Number.isNaN(value) || value < 0 || value > MPV_VOLUME_MAX_CEILING) { + if (!value || value < 0 || value > 100) { return; } diff --git a/src/main/features/linux/mpris.ts b/src/main/features/linux/mpris.ts index 34c97d689..4f91f63bb 100644 --- a/src/main/features/linux/mpris.ts +++ b/src/main/features/linux/mpris.ts @@ -3,7 +3,6 @@ import Player from 'mpris-service'; import { getMainWindow } from '/@/main/index'; import log from '/@/main/logger'; -import { MPV_VOLUME_MAX_CEILING } from '/@/shared/constants/volume'; import { QueueSong } from '/@/shared/types/domain-types'; import { PlayerRepeat, PlayerStatus } from '/@/shared/types/types'; @@ -71,11 +70,14 @@ mprisPlayer.on('previous', () => { } }); -// The renderer clamps to the active backend's maximum (mpv's --volume-max when -// mpv is selected), since that range is derived from settings the renderer owns. -// Only a sanity range is enforced here. mprisPlayer.on('volume', (vol: number) => { - const volume = Math.min(MPV_VOLUME_MAX_CEILING, Math.max(0, Math.round(vol * 100))); + let volume = Math.round(vol * 100); + + if (volume > 100) { + volume = 100; + } else if (volume < 0) { + volume = 0; + } getMainWindow()?.webContents.send('request-volume', { volume, diff --git a/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx b/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx index 3b95a774f..ad963156f 100644 --- a/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx +++ b/src/renderer/features/player/audio-player/engine/mpv-player-engine.tsx @@ -7,7 +7,6 @@ import { eventEmitter } from '/@/renderer/events/event-emitter'; import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; import { getSongUrl } from '/@/renderer/features/player/audio-player/hooks/use-stream-url'; import { AudioPlayer, PlayerOnProgressProps } from '/@/renderer/features/player/audio-player/types'; -import { resolveVolumeMax } from '/@/renderer/features/player/audio-player/utils/volume'; import { useRadioStore } from '/@/renderer/features/radio/hooks/use-radio-player'; import { getMpvProperties } from '/@/renderer/features/settings/components/playback/mpv-properties'; import { @@ -17,7 +16,7 @@ import { usePlayerStore, useSettingsStore, } from '/@/renderer/store'; -import { PlayerStatus, PlayerType } from '/@/shared/types/types'; +import { PlayerStatus } from '/@/shared/types/types'; export interface MpvPlayerEngineHandle extends AudioPlayer {} @@ -335,8 +334,7 @@ export const MpvPlayerEngine = (props: MpvPlayerEngineProps) => { } }, increaseVolume(by: number) { - const maxVol = resolveVolumeMax(PlayerType.LOCAL, mpvExtraParameters) / 100; - const newVol = Math.min(maxVol, internalVolume + by / 100); + const newVol = Math.min(1, internalVolume + by / 100); setInternalVolume(newVol); if (mpvPlayer) { mpvPlayer.volume(newVol * 100); diff --git a/src/renderer/features/player/audio-player/utils/volume.ts b/src/renderer/features/player/audio-player/utils/volume.ts deleted file mode 100644 index 97b4602db..000000000 --- a/src/renderer/features/player/audio-player/utils/volume.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - DEFAULT_VOLUME_MAX, - MPV_VOLUME_MAX_CEILING, - MPV_VOLUME_MAX_DEFAULT, -} from '/@/shared/constants/volume'; -import { PlayerType } from '/@/shared/types/types'; - -const VOLUME_MAX_FLAG = '--volume-max'; - -// mpv accepts either "--volume-max=200" or "--volume-max 200" (as two argv -// entries). Repeated options are last-wins, so we scan from the end. -export const parseMpvVolumeMax = (extraParameters: string[] = []): null | number => { - for (let i = extraParameters.length - 1; i >= 0; i -= 1) { - const param = extraParameters[i]?.trim(); - if (!param?.startsWith(VOLUME_MAX_FLAG)) { - continue; - } - - const raw = param.includes('=') - ? param.slice(param.indexOf('=') + 1) - : extraParameters[i + 1]; - - const parsed = Number(raw); - if (!Number.isFinite(parsed)) { - return null; - } - - return Math.min(MPV_VOLUME_MAX_CEILING, Math.max(1, parsed)); - } - - return null; -}; - -// The highest value the volume control may reach for the active backend. -export const resolveVolumeMax = ( - playbackType: PlayerType, - extraParameters: string[] = [], -): number => { - if (playbackType !== PlayerType.LOCAL) { - return DEFAULT_VOLUME_MAX; - } - - const configured = parseMpvVolumeMax(extraParameters) ?? MPV_VOLUME_MAX_DEFAULT; - return Math.min(MPV_VOLUME_MAX_CEILING, Math.max(DEFAULT_VOLUME_MAX, configured)); -}; - -// Constrains an externally sourced volume (mpris, remote) to the active backend's range. -export const clampVolume = ( - volume: number, - playbackType: PlayerType, - extraParameters: string[] = [], -): number => { - if (!Number.isFinite(volume)) { - return 0; - } - - return Math.min(resolveVolumeMax(playbackType, extraParameters), Math.max(0, volume)); -}; diff --git a/src/renderer/features/player/components/right-controls.tsx b/src/renderer/features/player/components/right-controls.tsx index 166c0679f..0212c4690 100644 --- a/src/renderer/features/player/components/right-controls.tsx +++ b/src/renderer/features/player/components/right-controls.tsx @@ -37,7 +37,6 @@ import { useShowRatings, useSidebarRightExpanded, useSideQueueType, - useVolumeMax, useVolumeWheelStep, useVolumeWidth, } from '/@/renderer/store'; @@ -62,11 +61,11 @@ import { useThrottledValue } from '/@/shared/hooks/use-throttled-value'; import { LibraryItem, QueueSong, ServerType } from '/@/shared/types/domain-types'; import { PlayerType } from '/@/shared/types/types'; -const calculateVolumeUp = (volume: number, volumeWheelStep: number, volumeMax: number) => { +const calculateVolumeUp = (volume: number, volumeWheelStep: number) => { let volumeToSet: number; - const newVolumeGreaterThanMax = volume + volumeWheelStep > volumeMax; - if (newVolumeGreaterThanMax) { - volumeToSet = volumeMax; + const newVolumeGreaterThanHundred = volume + volumeWheelStep > 100; + if (newVolumeGreaterThanHundred) { + volumeToSet = 100; } else { volumeToSet = volume + volumeWheelStep; } @@ -628,7 +627,6 @@ const VolumeButton = () => { const muted = usePlayerMuted(); const volumeWheelStep = useVolumeWheelStep(); const volumeWidth = useVolumeWidth(); - const volumeMax = useVolumeMax(); const { decreaseVolume, increaseVolume, mediaToggleMute, setVolume } = usePlayer(); const isMinWidth = useMediaQuery('(max-width: 480px)'); @@ -690,12 +688,12 @@ const VolumeButton = () => { if (e.deltaY > 0 || e.deltaX > 0) { volumeToSet = calculateVolumeDown(volume, volumeWheelStep); } else { - volumeToSet = calculateVolumeUp(volume, volumeWheelStep, volumeMax); + volumeToSet = calculateVolumeUp(volume, volumeWheelStep); } setVolume(volumeToSet); }, - [setVolume, volume, volumeWheelStep, volumeMax], + [setVolume, volume, volumeWheelStep], ); const handleVolumeDownThrottled = useThrottledCallback(handleVolumeDown, 100); @@ -759,7 +757,7 @@ const VolumeButton = () => { {!isMinWidth ? ( { diff --git a/src/renderer/features/player/hooks/use-mpris.ts b/src/renderer/features/player/hooks/use-mpris.ts index 08e6c38db..bdec1c386 100644 --- a/src/renderer/features/player/hooks/use-mpris.ts +++ b/src/renderer/features/player/hooks/use-mpris.ts @@ -3,12 +3,11 @@ import React, { useEffect, useMemo } from 'react'; import { useItemImageUrl } from '/@/renderer/components/item-image/item-image'; import { usePlayerEvents } from '/@/renderer/features/player/audio-player/hooks/use-player-events'; -import { clampVolume } from '/@/renderer/features/player/audio-player/utils/volume'; import { useIsRadioActive, useRadioPlayer, } from '/@/renderer/features/radio/hooks/use-radio-player'; -import { usePlayerSong, usePlayerStore, useSettingsStore } from '/@/renderer/store'; +import { usePlayerSong, usePlayerStore } from '/@/renderer/store'; import { LibraryItem, QueueSong } from '/@/shared/types/domain-types'; import { PlayerShuffle, ServerType } from '/@/shared/types/types'; @@ -135,8 +134,7 @@ export const useMPRIS = () => { }); mpris?.requestVolume((data: { volume: number }) => { - const { mpvExtraParameters, type } = useSettingsStore.getState().playback; - player.setVolume(clampVolume(data.volume, type, mpvExtraParameters)); + player.setVolume(data.volume); }); return () => { diff --git a/src/renderer/store/player.store.ts b/src/renderer/store/player.store.ts index a186b3ae8..f38a74c76 100644 --- a/src/renderer/store/player.store.ts +++ b/src/renderer/store/player.store.ts @@ -7,7 +7,6 @@ import { useShallow } from 'zustand/react/shallow'; import { createWithEqualityFn } from 'zustand/traditional'; import { eventEmitter } from '/@/renderer/events/event-emitter'; -import { resolveVolumeMax } from '/@/renderer/features/player/audio-player/utils/volume'; import { useRadioStore as useRadioPlayerStore } from '/@/renderer/features/radio/hooks/use-radio-player'; import { createSelectors } from '/@/renderer/lib/zustand'; import { useSettingsStore } from '/@/renderer/store/settings.store'; @@ -905,10 +904,8 @@ export const usePlayerStoreBase = createWithEqualityFn()( }; }, increaseVolume: (value: number) => { - const { mpvExtraParameters, type } = useSettingsStore.getState().playback; - const volumeMax = resolveVolumeMax(type, mpvExtraParameters); set((state) => { - state.player.volume = Math.min(volumeMax, state.player.volume + value); + state.player.volume = Math.min(100, state.player.volume + value); }); }, isFirstTrackInQueue: () => { diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index 387545e8d..6d105e861 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -21,7 +21,6 @@ import { PLAYLIST_TABLE_COLUMNS, SONG_TABLE_COLUMNS, } from '/@/renderer/components/item-list/item-table-list/default-columns'; -import { resolveVolumeMax } from '/@/renderer/features/player/audio-player/utils/volume'; import { audiomotionanalyzerPresets } from '/@/renderer/features/visualizer/components/audiomotionanalyzer/presets'; import { AppRoute } from '/@/renderer/router/routes'; import { getEnvSettingsOverrides } from '/@/renderer/store/env-settings-overrides'; @@ -2755,12 +2754,6 @@ export const useGeneralSettings = () => useSettingsStore((state) => state.genera export const usePlaybackType = () => useSettingsStore((state) => state.playback.type, shallow); -export const useVolumeMax = () => - useSettingsStore( - (state) => resolveVolumeMax(state.playback.type, state.playback.mpvExtraParameters), - shallow, - ); - export const usePlayButtonBehavior = () => useSettingsStore((state) => state.general.playButtonBehavior, shallow); diff --git a/src/shared/constants/volume.ts b/src/shared/constants/volume.ts deleted file mode 100644 index 29fc629b8..000000000 --- a/src/shared/constants/volume.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Defines the volume limits shared by the main and renderer processes. -// The active maximum is resolved from these in the renderer, which owns the -// playback settings that determine it. - -// The web-audio backend has no headroom above unity gain, so it stays at 100. -export const DEFAULT_VOLUME_MAX = 100; -// mpv's default --volume-max when the user passes nothing. -export const MPV_VOLUME_MAX_DEFAULT = 130; -// mpv's own hard ceiling for --volume-max. -export const MPV_VOLUME_MAX_CEILING = 1000;