From 8bf7cbe0330675e064bc751561791eb58308bd28 Mon Sep 17 00:00:00 2001 From: floatlesss <117862164+floatlesss@users.noreply.github.com> Date: Sun, 30 Nov 2025 19:02:30 +0000 Subject: [PATCH 1/3] Signed-off-by: floatlesss <117862164+floatlesss@users.noreply.github.com> fix(player-mediasession): manually update playbackState - 4744 --- ui/src/audioplayer/Player.jsx | 20 ++++++++++++++++---- ui/src/share/SharePlayer.jsx | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/ui/src/audioplayer/Player.jsx b/ui/src/audioplayer/Player.jsx index 03419add3..60bc1c7e9 100644 --- a/ui/src/audioplayer/Player.jsx +++ b/ui/src/audioplayer/Player.jsx @@ -148,6 +148,13 @@ const Player = () => { } }, [playerState, defaultOptions, isMobilePlayer]) + // ReactJKMusicPlayer doesn't set playbackState, so we do it manually + const updateMediaSessionPlaybackState = useCallback((state) => { + if ('mediaSession' in navigator) { + navigator.mediaSession.playbackState = state + } + }, []) + const onAudioListsChange = useCallback( (_, audioLists, audioInfo) => dispatch(syncQueue(audioInfo, audioLists)), [dispatch], @@ -207,6 +214,7 @@ const Player = () => { context.resume() } + updateMediaSessionPlaybackState('playing') dispatch(currentPlaying(info)) if (startTime === null) { setStartTime(Date.now()) @@ -235,7 +243,7 @@ const Player = () => { } } }, - [context, dispatch, showNotifications, startTime], + [context, dispatch, showNotifications, startTime, updateMediaSessionPlaybackState], ) const onAudioPlayTrackChange = useCallback(() => { @@ -248,12 +256,16 @@ const Player = () => { }, [scrobbled, startTime]) const onAudioPause = useCallback( - (info) => dispatch(currentPlaying(info)), - [dispatch], + (info) => { + updateMediaSessionPlaybackState('paused') + dispatch(currentPlaying(info)) + }, + [dispatch, updateMediaSessionPlaybackState], ) const onAudioEnded = useCallback( (currentPlayId, audioLists, info) => { + updateMediaSessionPlaybackState('none') setScrobbled(false) setStartTime(null) dispatch(currentPlaying(info)) @@ -262,7 +274,7 @@ const Player = () => { // eslint-disable-next-line no-console .catch((e) => console.log('Keepalive error:', e)) }, - [dispatch, dataProvider], + [dispatch, dataProvider, updateMediaSessionPlaybackState], ) const onCoverClick = useCallback((mode, audioLists, audioInfo) => { diff --git a/ui/src/share/SharePlayer.jsx b/ui/src/share/SharePlayer.jsx index a3a15e50a..4bbbcc9c4 100644 --- a/ui/src/share/SharePlayer.jsx +++ b/ui/src/share/SharePlayer.jsx @@ -1,3 +1,4 @@ +import { useCallback } from 'react' import ReactJkMusicPlayer from 'navidrome-music-player' import config, { shareInfo } from '../config' import { shareCoverUrl, shareDownloadUrl, shareStreamUrl } from '../utils' @@ -39,6 +40,35 @@ const SharePlayer = () => { src: shareDownloadUrl(shareInfo?.id), }) } + + // ReactJKMusicPlayer doesn't set playbackState, so we do it manually + const updateMediaSessionPlaybackState = useCallback((state) => { + if ('mediaSession' in navigator) { + navigator.mediaSession.playbackState = state + } + }, []) + + const onAudioPlay = useCallback( + (info) => { + updateMediaSessionPlaybackState('playing') + }, + [updateMediaSessionPlaybackState], + ) + + const onAudioPause = useCallback( + (info) => { + updateMediaSessionPlaybackState('paused') + }, + [updateMediaSessionPlaybackState], + ) + + const onAudioEnded = useCallback( + (currentPlayId, audioLists, info) => { + updateMediaSessionPlaybackState('none') + }, + [updateMediaSessionPlaybackState], + ) + const options = { audioLists: list, mode: 'full', @@ -59,6 +89,9 @@ const SharePlayer = () => { ) From c3cdba5a8512850c3b62332f2a4997b65544fb50 Mon Sep 17 00:00:00 2001 From: floatlesss <117862164+floatlesss@users.noreply.github.com> Date: Sun, 30 Nov 2025 19:09:13 +0000 Subject: [PATCH 2/3] Signed-off-by: floatlesss <117862164+floatlesss@users.noreply.github.com> style(player.jsx): (unimportant) prettier fix on player.jsx - 4744 --- ui/src/audioplayer/Player.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/src/audioplayer/Player.jsx b/ui/src/audioplayer/Player.jsx index 60bc1c7e9..c64f72cd3 100644 --- a/ui/src/audioplayer/Player.jsx +++ b/ui/src/audioplayer/Player.jsx @@ -243,7 +243,13 @@ const Player = () => { } } }, - [context, dispatch, showNotifications, startTime, updateMediaSessionPlaybackState], + [ + context, + dispatch, + showNotifications, + startTime, + updateMediaSessionPlaybackState, + ], ) const onAudioPlayTrackChange = useCallback(() => { From 16a46afe3db5abe484ec4c443acf9fa3c431b67c Mon Sep 17 00:00:00 2001 From: floatlesss <117862164+floatlesss@users.noreply.github.com> Date: Sun, 30 Nov 2025 19:39:30 +0000 Subject: [PATCH 3/3] Signed-off-by: floatlesss <117862164+floatlesss@users.noreply.github.com> refactor(unused params): prefix unused params with underscore - 4744 --- ui/src/share/SharePlayer.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/src/share/SharePlayer.jsx b/ui/src/share/SharePlayer.jsx index 4bbbcc9c4..197e8729f 100644 --- a/ui/src/share/SharePlayer.jsx +++ b/ui/src/share/SharePlayer.jsx @@ -49,21 +49,21 @@ const SharePlayer = () => { }, []) const onAudioPlay = useCallback( - (info) => { + (_info) => { updateMediaSessionPlaybackState('playing') }, [updateMediaSessionPlaybackState], ) const onAudioPause = useCallback( - (info) => { + (_info) => { updateMediaSessionPlaybackState('paused') }, [updateMediaSessionPlaybackState], ) const onAudioEnded = useCallback( - (currentPlayId, audioLists, info) => { + (_currentPlayId, _audioLists, _info) => { updateMediaSessionPlaybackState('none') }, [updateMediaSessionPlaybackState],