Merge pull request #1014 from Stremio/feat/player-media-session

Player: Add media session support
This commit is contained in:
Tim 2025-10-13 12:35:55 +02:00 committed by GitHub
commit 9923152de7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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.logo : 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) {
@ -547,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;