import React, { useState, useRef, useEffect, useCallback } from "react"; import { useVideoDimensions } from "@/hooks/use-video-dimensions"; import HlsVideoPlayer from "./HlsVideoPlayer"; import ActivityIndicator from "../indicators/activity-indicator"; import useKeyboardListener from "@/hooks/use-keyboard-listener"; type GenericVideoPlayerProps = { source: string; onPlaying?: () => void; children?: React.ReactNode; }; export function GenericVideoPlayer({ source, onPlaying, children, }: GenericVideoPlayerProps) { const [isLoading, setIsLoading] = useState(true); const [sourceExists, setSourceExists] = useState(true); const videoRef = useRef(null); const containerRef = useRef(null); const { videoDimensions, setVideoResolution } = useVideoDimensions(containerRef); useEffect(() => { const checkSourceExists = async (url: string) => { try { const response = await fetch(url, { method: "HEAD" }); // nginx vod module returns 502 for non existent media // https://github.com/kaltura/nginx-vod-module/issues/468 setSourceExists(response.status !== 502 && response.status !== 404); } catch (error) { setSourceExists(false); } }; checkSourceExists(source); }, [source]); const onSeek = useCallback( (diff: number) => { const currentTime = videoRef.current?.currentTime; if (!currentTime) { return; } videoRef.current!.currentTime = Math.max(0, currentTime + diff); }, [videoRef], ); useKeyboardListener( ["ArrowDown", "ArrowLeft", "ArrowRight", "ArrowUp", " ", "f", "m"], (key, modifiers) => { if (!modifiers.down || modifiers.repeat) { return; } switch (key) { case "ArrowDown": onSeek(-1); break; case "ArrowLeft": onSeek(-10); break; case "ArrowRight": onSeek(10); break; case "ArrowUp": onSeek(1); break; case " ": if (videoRef.current?.paused) { videoRef.current?.play(); } else { videoRef.current?.pause(); } break; case "f": videoRef.current?.requestFullscreen(); break; case "m": if (videoRef.current) { videoRef.current.muted = !videoRef.current.muted; } break; } }, ); return (
{!sourceExists ? (
Video not available
) : ( <> {isLoading && ( )}
{ setIsLoading(false); onPlaying?.(); }} setFullResolution={setVideoResolution} /> {!isLoading && children}
)}
); }