From c26dac2154d8d6d5eb0433b0d3179089ce2885ae Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 6 Oct 2025 14:09:01 +0200 Subject: [PATCH 1/3] feat(Player): add media session support --- src/routes/Player/Player.js | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 436f1a781..e9583ec3c 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -532,6 +532,53 @@ const Player = ({ urlParams, queryParams }) => { } }, [settings.pauseOnMinimize, shell.windowClosed, shell.windowHidden]); + // Media Session PlaybackState + React.useEffect(() => { + if (!navigator.mediaSession) return; + + const playbackState = !video.state.paused ? 'playing' : 'paused'; + navigator.mediaSession.playbackState = playbackState; + + return () => navigator.mediaSession.playbackState = 'none'; + }, [video.state.paused]); + + // Media Session Metadata + React.useEffect(() => { + if (!navigator.mediaSession) return; + + const metaItem = player.metaItem && player.metaItem.type === 'Ready' ? player.metaItem.content : null; + const videoId = player.selected ? player.selected.streamRequest.path.id : null; + const video = metaItem ? metaItem.videos.find(({ id }) => id === videoId) : null; + + const videoInfo = video && video.season && video.episode ? ` (${video.season}x${video.episode})`: null; + const videoTitle = video ? `${video.title}${videoInfo}` : null; + const metaTitle = metaItem ? metaItem.name : null; + const imageUrl = metaItem ? metaItem.poster : null; + + const title = videoTitle ?? metaTitle; + const artist = videoTitle ? metaTitle : undefined; + const artwork = imageUrl ? [{ src: imageUrl }] : undefined; + + if (title) { + navigator.mediaSession.metadata = new MediaMetadata({ + title, + artist, + artwork, + }); + } + }, [player.metaItem, player.selected]); + + // Media Session Actions + React.useEffect(() => { + if (!navigator.mediaSession) return; + + navigator.mediaSession.setActionHandler('play', onPlayRequested); + navigator.mediaSession.setActionHandler('pause', onPauseRequested); + + const nexVideoCallback = player.nextVideo ? onNextVideoRequested : null; + navigator.mediaSession.setActionHandler('nexttrack', nexVideoCallback); + }, [player.nextVideo, onPlayRequested, onPauseRequested, onNextVideoRequested]); + React.useLayoutEffect(() => { const onKeyDown = (event) => { switch (event.code) { From 122e43dbe52452d26bf486e891282beaf4f6cfd3 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 13 Oct 2025 12:26:42 +0200 Subject: [PATCH 2/3] refactor(Player): remove handling of media keys --- src/routes/Player/Player.js | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index 6342daa54..e9583ec3c 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -594,36 +594,6 @@ const Player = ({ urlParams, queryParams }) => { break; } - case 'MediaPlayPause': { - if (!menusOpen && !nextVideoPopupOpen && video.state.paused !== null) { - event.preventDefault(); - if (video.state.paused) { - onPlayRequested(); - setSeeking(false); - } else { - onPauseRequested(); - } - } - - break; - } - case 'MediaPlay': { - if (!menusOpen && !nextVideoPopupOpen && video.state.paused === true) { - event.preventDefault(); - onPlayRequested(); - setSeeking(false); - } - - break; - } - case 'MediaPause': { - if (!menusOpen && !nextVideoPopupOpen && video.state.paused === false) { - event.preventDefault(); - onPauseRequested(); - } - - break; - } case 'ArrowRight': { if (!menusOpen && !nextVideoPopupOpen && video.state.time !== null) { const seekDuration = event.shiftKey ? settings.seekShortTimeDuration : settings.seekTimeDuration; From 3eff7f0903a8fd6f8ccec8cfbb99feb06a3e06b4 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 13 Oct 2025 12:33:46 +0200 Subject: [PATCH 3/3] refactor(Player): use poster for media session artwork --- src/routes/Player/Player.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/Player/Player.js b/src/routes/Player/Player.js index e9583ec3c..eab38bd96 100644 --- a/src/routes/Player/Player.js +++ b/src/routes/Player/Player.js @@ -553,7 +553,7 @@ const Player = ({ urlParams, queryParams }) => { const videoInfo = video && video.season && video.episode ? ` (${video.season}x${video.episode})`: null; const videoTitle = video ? `${video.title}${videoInfo}` : null; const metaTitle = metaItem ? metaItem.name : null; - const imageUrl = metaItem ? metaItem.poster : null; + const imageUrl = metaItem ? metaItem.logo : null; const title = videoTitle ?? metaTitle; const artist = videoTitle ? metaTitle : undefined;