Fix react native video new props

This commit is contained in:
Zoe Roux 2024-05-20 00:09:56 +02:00
parent f0b5b55b13
commit 5049ad25b5
No known key found for this signature in database
4 changed files with 75 additions and 62 deletions

View File

@ -39,7 +39,6 @@ import { episodeDisplayNumber } from "../details/episode";
import { ErrorView } from "../errors"; import { ErrorView } from "../errors";
import { Back, Hover, LoadingIndicator } from "./components/hover"; import { Back, Hover, LoadingIndicator } from "./components/hover";
import { useVideoKeyboard } from "./keyboard"; import { useVideoKeyboard } from "./keyboard";
import { MediaSessionManager } from "./media-session";
import { Video, durationAtom, fullscreenAtom } from "./state"; import { Video, durationAtom, fullscreenAtom } from "./state";
import { WatchStatusObserver } from "./watch-status-observer"; import { WatchStatusObserver } from "./watch-status-observer";
@ -90,6 +89,15 @@ export const Player = ({
data && data.type === "episode" && data.nextEpisode data && data.type === "episode" && data.nextEpisode
? `/watch/${data.nextEpisode.slug}?t=0` ? `/watch/${data.nextEpisode.slug}?t=0`
: undefined; : undefined;
const title =
data &&
(data.type === "movie"
? data.name
: `${data.show!.name} ${episodeDisplayNumber({
seasonNumber: data.seasonNumber,
episodeNumber: data.episodeNumber,
absoluteNumber: data.absoluteNumber,
})}`);
useVideoKeyboard(info?.subtitles, info?.fonts, previous, next); useVideoKeyboard(info?.subtitles, info?.fonts, previous, next);
@ -119,26 +127,7 @@ export const Player = ({
return ( return (
<> <>
{data && ( <Head title={title} description={data?.overview} />
<Head
title={
data.type === "movie"
? data.name
: `${data.show!.name} ${episodeDisplayNumber({
seasonNumber: data.seasonNumber,
episodeNumber: data.episodeNumber,
absoluteNumber: data.absoluteNumber,
})}`
}
description={data.overview}
/>
)}
<MediaSessionManager
title={data?.name ?? t("show.episodeNoMetadata")}
image={data?.thumbnail?.high}
next={next}
previous={previous}
/>
{data && info && ( {data && info && (
<WatchStatusObserver type={type} slug={data.slug} duration={info.durationSeconds} /> <WatchStatusObserver type={type} slug={data.slug} duration={info.durationSeconds} />
)} )}
@ -150,6 +139,13 @@ export const Player = ({
})} })}
> >
<Video <Video
metadata={{
title: title ?? t("show.episodeNoMetadata"),
description: data?.overview ?? undefined,
imageUri: data?.thumbnail?.high,
next: next,
previous: previous,
}}
links={data?.links} links={data?.links}
audios={info?.audios} audios={info?.audios}
subtitles={info?.subtitles} subtitles={info?.subtitles}

View File

@ -104,6 +104,7 @@ export const Video = memo(function Video({
setError, setError,
fonts, fonts,
startTime: startTimeP, startTime: startTimeP,
metadata,
...props ...props
}: { }: {
links?: Episode["links"]; links?: Episode["links"];
@ -113,6 +114,13 @@ export const Video = memo(function Video({
setError: (error: string | undefined) => void; setError: (error: string | undefined) => void;
fonts?: string[]; fonts?: string[];
startTime?: number | null; startTime?: number | null;
metadata: {
title?: string;
description?: string;
imageUri?: string;
previous?: string;
next?: string;
};
} & Partial<VideoProps>) { } & Partial<VideoProps>) {
const ref = useRef<ElementRef<typeof NativeVideo> | null>(null); const ref = useRef<ElementRef<typeof NativeVideo> | null>(null);
const [isPlaying, setPlay] = useAtom(playAtom); const [isPlaying, setPlay] = useAtom(playAtom);
@ -220,8 +228,12 @@ export const Video = memo(function Video({
source={{ source={{
uri: source, uri: source,
startPosition: startTime.current ? startTime.current * 1000 : undefined, startPosition: startTime.current ? startTime.current * 1000 : undefined,
metadata: metadata,
...links, ...links,
}} }}
showNotificationControls
playInBackground
playWhenInactive
paused={!isPlaying} paused={!isPlaying}
muted={isMuted} muted={isMuted}
volume={volume} volume={volume}

View File

@ -19,6 +19,7 @@
*/ */
import "react-native-video"; import "react-native-video";
import type { ReactVideoSourceProperties } from "react-native-video";
declare module "react-native-video" { declare module "react-native-video" {
interface ReactVideoProps { interface ReactVideoProps {
@ -27,7 +28,7 @@ declare module "react-native-video" {
onMediaUnsupported?: () => void; onMediaUnsupported?: () => void;
} }
export type VideoProps = Omit<ReactVideoProps, "source"> & { export type VideoProps = Omit<ReactVideoProps, "source"> & {
source: { uri: string; hls: string | null; startPosition?: number }; source: ReactVideoSourceProperties & { hls: string | null };
}; };
} }
@ -120,7 +121,7 @@ const Video = forwardRef<VideoRef, VideoProps>(function Video(
type: SelectedTrackType.INDEX, type: SelectedTrackType.INDEX,
value: subtitles?.indexOf(subtitle), value: subtitles?.indexOf(subtitle),
} }
: { type: SelectedTrackType.DISABLED } : { type: SelectedTrackType.DISABLED, value: "" }
} }
{...props} {...props}
/> />

View File

@ -38,6 +38,7 @@ import toVttBlob from "srt-webvtt";
import { useForceRerender, useYoshiki } from "yoshiki"; import { useForceRerender, useYoshiki } from "yoshiki";
import { useDisplayName } from "../utils"; import { useDisplayName } from "../utils";
import { PlayMode, audioAtom, playAtom, playModeAtom, progressAtom, subtitleAtom } from "./state"; import { PlayMode, audioAtom, playAtom, playModeAtom, progressAtom, subtitleAtom } from "./state";
import { MediaSessionManager } from "./media-session";
let hls: Hls | null = null; let hls: Hls | null = null;
@ -208,46 +209,49 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
const setProgress = useSetAtom(progressAtom); const setProgress = useSetAtom(progressAtom);
return ( return (
<video <>
ref={ref} <MediaSessionManager {...source.metadata} />
src={source.uri} <video
muted={muted} ref={ref}
autoPlay={!paused} src={source.uri}
controls={false} muted={muted}
playsInline autoPlay={!paused}
onCanPlay={() => onBuffer?.call(null, { isBuffering: false })} controls={false}
onWaiting={() => onBuffer?.call(null, { isBuffering: true })} playsInline
onDurationChange={() => { onCanPlay={() => onBuffer?.call(null, { isBuffering: false })}
if (!ref.current) return; onWaiting={() => onBuffer?.call(null, { isBuffering: true })}
onLoad?.call(null, { duration: ref.current.duration } as any); onDurationChange={() => {
}} if (!ref.current) return;
onTimeUpdate={() => { onLoad?.call(null, { duration: ref.current.duration } as any);
if (!ref.current) return; }}
onProgress?.call(null, { onTimeUpdate={() => {
currentTime: ref.current.currentTime, if (!ref.current) return;
playableDuration: ref.current.buffered.length onProgress?.call(null, {
? ref.current.buffered.end(ref.current.buffered.length - 1) currentTime: ref.current.currentTime,
: 0, playableDuration: ref.current.buffered.length
seekableDuration: 0, ? ref.current.buffered.end(ref.current.buffered.length - 1)
}); : 0,
}} seekableDuration: 0,
onError={() => {
if (ref?.current?.error?.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED)
onMediaUnsupported?.call(undefined);
else {
onError?.call(null, {
error: { errorString: ref.current?.error?.message ?? "Unknown error" },
}); });
} }}
}} onError={() => {
onLoadedMetadata={() => { if (ref?.current?.error?.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED)
if (source.startPosition) setProgress(source.startPosition / 1000); onMediaUnsupported?.call(undefined);
}} else {
onPlay={() => onPlaybackStateChanged?.({ isPlaying: true })} onError?.call(null, {
onPause={() => onPlaybackStateChanged?.({ isPlaying: false })} error: { errorString: ref.current?.error?.message ?? "Unknown error" },
onEnded={onEnd} });
{...css({ width: "100%", height: "100%", objectFit: "contain" })} }
/> }}
onLoadedMetadata={() => {
if (source.startPosition) setProgress(source.startPosition / 1000);
}}
onPlay={() => onPlaybackStateChanged?.({ isPlaying: true })}
onPause={() => onPlaybackStateChanged?.({ isPlaying: false })}
onEnded={onEnd}
{...css({ width: "100%", height: "100%", objectFit: "contain" })}
/>
</>
); );
}); });