From c88c6cf55eeebad64bc8e721b94fb0fd00bce3bc Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sun, 12 Oct 2025 16:37:24 -0700 Subject: [PATCH] add mediasession playback controls --- .../player/components/center-controls.tsx | 2 +- .../player/hooks/use-media-session.ts | 98 ++++++++++++++++++- 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/renderer/features/player/components/center-controls.tsx b/src/renderer/features/player/components/center-controls.tsx index 3e690261..08ffce67 100644 --- a/src/renderer/features/player/components/center-controls.tsx +++ b/src/renderer/features/player/components/center-controls.tsx @@ -84,7 +84,7 @@ export const CenterControls = ({ playersRef }: CenterControlsProps) => { ], ]); - useMediaSession(); + useMediaSession(playersRef); return ( <> diff --git a/src/renderer/features/player/hooks/use-media-session.ts b/src/renderer/features/player/hooks/use-media-session.ts index da2bff9f..aa157eb4 100644 --- a/src/renderer/features/player/hooks/use-media-session.ts +++ b/src/renderer/features/player/hooks/use-media-session.ts @@ -1,13 +1,99 @@ import { useEffect } from 'react'; -import { useCurrentSong, useCurrentStatus, usePlaybackSettings } from '/@/renderer/store'; +import { useCenterControls } from '/@/renderer/features/player/hooks/use-center-controls'; +import { + useCurrentSong, + useCurrentStatus, + usePlaybackSettings, + useSettingsStore, +} from '/@/renderer/store'; import { PlayerStatus } from '/@/shared/types/types'; -export const useMediaSession = () => { +export const useMediaSession = (playersRef: { player1: any; player2: any }) => { const { mediaSession: mediaSessionEnabled } = usePlaybackSettings(); const playerStatus = useCurrentStatus(); const currentSong = useCurrentSong(); const mediaSession = navigator.mediaSession; + const skip = useSettingsStore((state) => state.general.skipButtons); + + const { + handleNextTrack, + handlePause, + handlePlay, + handlePrevTrack, + handleSeekSlider, + handleSkipBackward, + handleSkipForward, + handleStop, + } = useCenterControls({ + playersRef, + }); + + useEffect(() => { + if (!mediaSessionEnabled || !mediaSession) { + return; + } + + mediaSession.setActionHandler('nexttrack', () => { + console.log('nexttrack'); + handleNextTrack(); + }); + + mediaSession.setActionHandler('pause', () => { + console.log('pause'); + handlePause(); + }); + + mediaSession.setActionHandler('play', () => { + console.log('play'); + handlePlay(); + }); + + mediaSession.setActionHandler('previoustrack', () => { + console.log('previoustrack'); + handlePrevTrack(); + }); + + mediaSession.setActionHandler('seekto', (e) => { + handleSeekSlider(e.seekTime); + }); + + mediaSession.setActionHandler('stop', () => { + handleStop(); + }); + + mediaSession.setActionHandler('seekbackward', (e) => { + handleSkipBackward(e.seekOffset || skip?.skipBackwardSeconds || 5); + }); + + mediaSession.setActionHandler('seekforward', (e) => { + handleSkipForward(e.seekOffset || skip?.skipForwardSeconds || 5); + }); + + return () => { + mediaSession.setActionHandler('nexttrack', null); + mediaSession.setActionHandler('pause', null); + mediaSession.setActionHandler('play', null); + mediaSession.setActionHandler('previoustrack', null); + mediaSession.setActionHandler('seekto', null); + mediaSession.setActionHandler('stop', null); + mediaSession.setActionHandler('seekbackward', null); + mediaSession.setActionHandler('seekforward', null); + }; + }, [ + handleNextTrack, + handlePause, + handlePlay, + handlePrevTrack, + handleSeekSlider, + handleSkipBackward, + handleSkipForward, + handleStop, + mediaSession, + mediaSessionEnabled, + skip?.skipBackwardSeconds, + skip?.skipForwardSeconds, + ]); useEffect(() => { if (!mediaSessionEnabled || !mediaSession) { @@ -26,6 +112,10 @@ export const useMediaSession = () => { }; updateMetadata(); + + return () => { + mediaSession.metadata = null; + }; }, [currentSong, mediaSession, mediaSessionEnabled]); useEffect(() => { @@ -37,5 +127,9 @@ export const useMediaSession = () => { const status = playerStatus === PlayerStatus.PLAYING ? 'playing' : 'paused'; mediaSession.playbackState = status; } + + return () => { + mediaSession.playbackState = 'none'; + }; }, [playerStatus, mediaSession, mediaSessionEnabled]); };