diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index bc4c37dc..c0acb5cd 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -709,6 +709,8 @@ "clearCacheSuccess": "Cache erfolgreich geleert", "contextMenu": "Kontextmenü-Einstellungen (Rechtsklick)", "customCssEnable_description": "ermöglicht das Schreiben benutzerdefinierten CSS.", - "doubleClickBehavior": "bei Doppelklick alle gesuchten Tracks zur Warteschlange hinzufügen" + "doubleClickBehavior": "bei Doppelklick alle gesuchten Tracks zur Warteschlange hinzufügen", + "mediaSession" : "aktiviere Medien-Sitzung API", + "mediaSession_description": "Aktiviert die Windows Media Session-Integration, die Mediensteuerungen und Metadaten im Systemlautstärke-Overlay und auf dem Sperrbildschirm anzeigt (nur Windows)" } } diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index cdb14c1f..5d6dd8ac 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -727,6 +727,8 @@ "transcodeBitrate_description": "selects the bitrate to transcode. 0 means let the server pick", "transcodeFormat": "format to transcode", "transcodeFormat_description": "selects the format to transcode. leave empty to let the server decide", + "mediaSession": "enable media session", + "mediaSession_description": "Enables Windows Media Session integration, displaying media controls and metadata in the system volume overlay and lock screen (Windows only)", "translationApiProvider": "translation api provider", "translationApiProvider_description": "api provider for translation", "translationApiKey": "translation api key", diff --git a/src/main/index.ts b/src/main/index.ts index 33a6cec3..cfd9bbda 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -548,7 +548,14 @@ async function createWindow(first = true): Promise { } } -app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling,MediaSessionService'); +const enableWindowsMediaSession = store.get('mediaSession', false) as boolean; +const shouldDisableMediaFeatures = process.platform !== 'win32' || !enableWindowsMediaSession; +if (shouldDisableMediaFeatures) { + app.commandLine.appendSwitch( + 'disable-features', + 'HardwareMediaKeyHandling,MediaSessionService', + ); +} // https://github.com/electron/electron/issues/46538#issuecomment-2808806722 app.commandLine.appendSwitch('gtk-version', '3'); diff --git a/src/renderer/features/settings/components/playback/media-session-settings.tsx b/src/renderer/features/settings/components/playback/media-session-settings.tsx new file mode 100644 index 00000000..dec9051d --- /dev/null +++ b/src/renderer/features/settings/components/playback/media-session-settings.tsx @@ -0,0 +1,40 @@ +import { useTranslation } from 'react-i18next'; + +import { + SettingOption, + SettingsSection, +} from '/@/renderer/features/settings/components/settings-section'; +import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store'; +import { Switch } from '/@/shared/components/switch/switch'; + +export const MediaSessionSettings = () => { + const { t } = useTranslation(); + const { mediaSession } = usePlaybackSettings(); + const { toggleMediaSession } = useSettingsStoreActions(); + + function handleMediaSessionChange() { + const current = mediaSession; + toggleMediaSession(); + window.api.ipc.send('settings-set', { property: 'mediaSession', value: !current }); + } + + const mediaSessionOptions: SettingOption[] = [ + { + control: ( + + ), + description: t('setting.mediaSession', { + context: 'description', + postProcess: 'sentenceCase', + }), + note: t('common.restartRequired', { postProcess: 'sentenceCase' }), + title: t('setting.mediaSession', { postProcess: 'sentenceCase' }), + }, + ]; + + return ; +}; diff --git a/src/renderer/features/settings/components/playback/playback-tab.tsx b/src/renderer/features/settings/components/playback/playback-tab.tsx index 37781c5d..9effec07 100644 --- a/src/renderer/features/settings/components/playback/playback-tab.tsx +++ b/src/renderer/features/settings/components/playback/playback-tab.tsx @@ -3,6 +3,7 @@ import { lazy, Suspense, useMemo } from 'react'; import { AudioSettings } from '/@/renderer/features/settings/components/playback/audio-settings'; import { LyricSettings } from '/@/renderer/features/settings/components/playback/lyric-settings'; +import { MediaSessionSettings } from '/@/renderer/features/settings/components/playback/media-session-settings'; import { ScrobbleSettings } from '/@/renderer/features/settings/components/playback/scrobble-settings'; import { TranscodeSettings } from '/@/renderer/features/settings/components/playback/transcode-settings'; import { useSettingsStore } from '/@/renderer/store'; @@ -31,6 +32,7 @@ export const PlaybackTab = () => { }>{hasFancyAudio && } + diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index 0100c560..40738166 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -202,6 +202,7 @@ export interface SettingsSlice extends SettingsState { setTable: (type: TableType, data: DataTableProps) => void; setTranscodingConfig: (config: TranscodingConfig) => void; toggleContextMenuItem: (item: ContextMenuItemType) => void; + toggleMediaSession: () => void; toggleSidebarCollapseShare: () => void; }; } @@ -298,6 +299,7 @@ export interface SettingsState { audioDeviceId?: null | string; crossfadeDuration: number; crossfadeStyle: CrossfadeStyle; + mediaSession: boolean; mpvExtraParameters: string[]; mpvProperties: MpvSettings; muted: boolean; @@ -491,6 +493,7 @@ const initialState: SettingsState = { audioDeviceId: undefined, crossfadeDuration: 5, crossfadeStyle: CrossfadeStyle.EQUALPOWER, + mediaSession: false, mpvExtraParameters: [], mpvProperties: { audioExclusiveMode: 'no', @@ -752,6 +755,11 @@ export const useSettingsStore = createWithEqualityFn()( !state.general.disabledContextMenu[item]; }); }, + toggleMediaSession: () => { + set((state) => { + state.playback.mediaSession = !state.playback.mediaSession; + }); + }, toggleSidebarCollapseShare: () => { set((state) => { state.general.sidebarCollapseShared =