1
0
Fork 0
mirror of https://github.com/sussy-code/smov.git synced 2024-12-23 15:07:43 +01:00
smov/src/components/video/VideoPlayer.tsx

61 lines
1.9 KiB
TypeScript
Raw Normal View History

2023-01-15 16:51:55 +01:00
import { useGoBack } from "@/hooks/useGoBack";
2023-01-10 19:53:55 +01:00
import { forwardRef, useContext, useEffect, useRef } from "react";
2023-01-15 16:51:55 +01:00
import { VideoErrorBoundary } from "./parts/VideoErrorBoundary";
2023-01-08 15:37:16 +01:00
import { VideoPlayerContext, VideoPlayerContextProvider } from "./VideoContext";
2023-01-08 13:15:32 +01:00
2023-01-08 22:29:38 +01:00
export interface VideoPlayerProps {
autoPlay?: boolean;
2023-01-08 13:15:32 +01:00
children?: React.ReactNode;
}
const VideoPlayerInternals = forwardRef<
HTMLVideoElement,
{ autoPlay: boolean }
>((props, ref) => {
2023-01-08 13:15:32 +01:00
const video = useContext(VideoPlayerContext);
2023-01-10 19:53:55 +01:00
const didInitialize = useRef<true | null>(null);
2023-01-08 13:15:32 +01:00
2023-01-10 19:53:55 +01:00
useEffect(() => {
if (didInitialize.current) return;
if (!video.state.hasInitialized || !video.source) return;
video.state.initPlayer(video.source, video.sourceType);
didInitialize.current = true;
}, [didInitialize, video]);
// muted attribute is required for safari, as they cant change the volume itself
2023-01-08 13:15:32 +01:00
return (
<video
ref={ref}
autoPlay={props.autoPlay}
2023-01-10 19:53:55 +01:00
muted={video.state.volume === 0}
playsInline
className="h-full w-full"
2023-01-10 19:53:55 +01:00
/>
2023-01-08 13:15:32 +01:00
);
});
export function VideoPlayer(props: VideoPlayerProps) {
const playerRef = useRef<HTMLVideoElement | null>(null);
2023-01-08 16:23:42 +01:00
const playerWrapperRef = useRef<HTMLDivElement | null>(null);
2023-01-15 16:51:55 +01:00
const goBack = useGoBack();
// TODO move error boundary to only decorated, <VideoPlayer /> shouldn't have styling
2023-01-08 13:15:32 +01:00
return (
2023-01-08 16:23:42 +01:00
<VideoPlayerContextProvider player={playerRef} wrapper={playerWrapperRef}>
<div
className="relative h-full w-full select-none overflow-hidden bg-black"
2023-01-08 16:23:42 +01:00
ref={playerWrapperRef}
>
2023-01-15 16:51:55 +01:00
<VideoErrorBoundary onGoBack={goBack}>
<VideoPlayerInternals
autoPlay={props.autoPlay ?? false}
ref={playerRef}
/>
<div className="absolute inset-0">{props.children}</div>
</VideoErrorBoundary>
2023-01-08 16:23:42 +01:00
</div>
2023-01-08 13:15:32 +01:00
</VideoPlayerContextProvider>
);
}