mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-10 11:20:49 +00:00
refactor: move media session logic to hook
This commit is contained in:
parent
5db6df4fc2
commit
c782303407
4 changed files with 62 additions and 47 deletions
|
|
@ -28,6 +28,7 @@ const useVideo = require('./useVideo');
|
|||
const styles = require('./styles');
|
||||
const Video = require('./Video');
|
||||
const { default: Indicator } = require('./Indicator/Indicator');
|
||||
const { default: useMediaSession } = require('./useMediaSession');
|
||||
|
||||
const findTrackByLang = (tracks, lang) => tracks.find((track) => track.lang === lang || langs.where('1', track.lang)?.[2] === lang);
|
||||
const findTrackById = (tracks, id) => tracks.find((track) => track.id === id);
|
||||
|
|
@ -596,52 +597,7 @@ 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]);
|
||||
useMediaSession(video.state, player, onPlayRequested, onPauseRequested, onNextVideoRequested);
|
||||
|
||||
onShortcut('seekForward', (combo) => {
|
||||
if (video.state.time !== null) {
|
||||
|
|
|
|||
57
src/routes/Player/useMediaSession.ts
Normal file
57
src/routes/Player/useMediaSession.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
const useMediaSession = (
|
||||
videoState: VideoState,
|
||||
player: Player,
|
||||
onPlayRequested: () => void,
|
||||
onPauseRequested: () => void,
|
||||
onNextVideoRequested: () => void,
|
||||
) => {
|
||||
useEffect(() => {
|
||||
if (!navigator.mediaSession) return;
|
||||
|
||||
const playbackState = !videoState.paused ? 'playing' : 'paused';
|
||||
navigator.mediaSession.playbackState = playbackState;
|
||||
|
||||
return () => {
|
||||
navigator.mediaSession.playbackState = 'none';
|
||||
};
|
||||
}, [videoState.paused]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!navigator.mediaSession) return;
|
||||
|
||||
const metaItem = player.metaItem && player.metaItem?.type === 'Ready' ? player.metaItem.content as MetaItemPlayer : null;
|
||||
const videoId = player.selected ? player.selected?.streamRequest?.path?.id : null;
|
||||
const video = metaItem?.videos.find(({ id }) => id === videoId);
|
||||
|
||||
const videoInfo = 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]);
|
||||
|
||||
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]);
|
||||
};
|
||||
|
||||
export default useMediaSession;
|
||||
3
src/routes/Player/videoState.d.ts
vendored
Normal file
3
src/routes/Player/videoState.d.ts
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
type VideoState = {
|
||||
paused?: boolean;
|
||||
};
|
||||
1
src/types/models/Player.d.ts
vendored
1
src/types/models/Player.d.ts
vendored
|
|
@ -5,7 +5,6 @@ type LibraryItemPlayer = Pick<LibraryItem, '_id'> & {
|
|||
type VideoPlayer = Video & {
|
||||
upcoming: boolean,
|
||||
watched: boolean,
|
||||
progress: boolean | null,
|
||||
scheduled: boolean,
|
||||
deepLinks: VideoDeepLinks,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue