mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-05-12 21:40:45 +00:00
feat(player): implement media session ipc
This commit is contained in:
parent
a83788ef67
commit
82484d032d
2 changed files with 56 additions and 16 deletions
|
|
@ -27,6 +27,10 @@ export type WindowState = {
|
||||||
state: number;
|
state: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type MediaStatus = {
|
||||||
|
paused: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
const createId = () => Math.floor(Math.random() * 9999) + 1;
|
const createId = () => Math.floor(Math.random() * 9999) + 1;
|
||||||
|
|
||||||
const useShell = () => {
|
const useShell = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { useShell } from 'stremio/common';
|
||||||
|
import { MediaStatus } from 'stremio/common/useShell';
|
||||||
|
|
||||||
const useMediaSession = (
|
const useMediaSession = (
|
||||||
videoState: VideoState,
|
videoState: VideoState,
|
||||||
|
|
@ -7,20 +9,31 @@ const useMediaSession = (
|
||||||
onPauseRequested: () => void,
|
onPauseRequested: () => void,
|
||||||
onNextVideoRequested: () => void,
|
onNextVideoRequested: () => void,
|
||||||
) => {
|
) => {
|
||||||
useEffect(() => {
|
const shell = useShell();
|
||||||
if (!navigator.mediaSession) return;
|
|
||||||
|
|
||||||
|
// Playback state
|
||||||
|
useEffect(() => {
|
||||||
const playbackState = !videoState.paused ? 'playing' : 'paused';
|
const playbackState = !videoState.paused ? 'playing' : 'paused';
|
||||||
navigator.mediaSession.playbackState = playbackState;
|
|
||||||
|
if (navigator.mediaSession) {
|
||||||
|
navigator.mediaSession.playbackState = playbackState;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shell.active) {
|
||||||
|
shell.send('media.status', {
|
||||||
|
paused: !!videoState.paused,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
navigator.mediaSession.playbackState = 'none';
|
if (navigator.mediaSession) {
|
||||||
|
navigator.mediaSession.playbackState = 'none';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}, [videoState.paused]);
|
}, [videoState.paused]);
|
||||||
|
|
||||||
|
// Metadata
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!navigator.mediaSession) return;
|
|
||||||
|
|
||||||
const metaItem = player.metaItem && player.metaItem?.type === 'Ready' ? player.metaItem.content as MetaItemPlayer : null;
|
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 videoId = player.selected ? player.selected?.streamRequest?.path?.id : null;
|
||||||
const video = metaItem?.videos.find(({ id }) => id === videoId);
|
const video = metaItem?.videos.find(({ id }) => id === videoId);
|
||||||
|
|
@ -35,22 +48,45 @@ const useMediaSession = (
|
||||||
const artwork = imageUrl ? [{ src: imageUrl }] : undefined;
|
const artwork = imageUrl ? [{ src: imageUrl }] : undefined;
|
||||||
|
|
||||||
if (title) {
|
if (title) {
|
||||||
navigator.mediaSession.metadata = new MediaMetadata({
|
if (navigator.mediaSession) {
|
||||||
title,
|
navigator.mediaSession.metadata = new MediaMetadata({
|
||||||
artist,
|
title,
|
||||||
artwork,
|
artist,
|
||||||
});
|
artwork,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shell.active) {
|
||||||
|
shell.send('media.metadata', {
|
||||||
|
title,
|
||||||
|
artist,
|
||||||
|
artUrl: imageUrl,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [player.metaItem, player.selected]);
|
}, [player.metaItem, player.selected]);
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!navigator.mediaSession) return;
|
if (navigator.mediaSession) {
|
||||||
|
navigator.mediaSession.setActionHandler('play', onPlayRequested);
|
||||||
navigator.mediaSession.setActionHandler('play', onPlayRequested);
|
navigator.mediaSession.setActionHandler('pause', onPauseRequested);
|
||||||
navigator.mediaSession.setActionHandler('pause', onPauseRequested);
|
}
|
||||||
|
|
||||||
const nexVideoCallback = player.nextVideo ? onNextVideoRequested : null;
|
const nexVideoCallback = player.nextVideo ? onNextVideoRequested : null;
|
||||||
navigator.mediaSession.setActionHandler('nexttrack', nexVideoCallback);
|
if (navigator.mediaSession && nexVideoCallback) {
|
||||||
|
navigator.mediaSession.setActionHandler('nexttrack', nexVideoCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const onMediaStatus = ({ paused }: MediaStatus) => {
|
||||||
|
paused ? onPauseRequested() : onPlayRequested();
|
||||||
|
};
|
||||||
|
|
||||||
|
shell.on('media.status', onMediaStatus);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
shell.on('media.status', onMediaStatus);
|
||||||
|
};
|
||||||
}, [player.nextVideo, onPlayRequested, onPauseRequested, onNextVideoRequested]);
|
}, [player.nextVideo, onPlayRequested, onPauseRequested, onNextVideoRequested]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue