import { IconPatch } from "components/buttons/IconPatch"; import { Icons } from "components/Icon"; import { Loading } from "components/layout/Loading"; import { MWMediaCaption, MWMediaStream } from "providers"; import { ReactElement, useEffect, useRef, useState } from "react"; import Hls from "hls.js"; export interface VideoPlayerProps { source: MWMediaStream; captions: MWMediaCaption[]; startAt?: number; onProgress?: (event: ProgressEvent) => void; } export function SkeletonVideoPlayer(props: { error?: boolean }) { return (
{props.error ? (

Couldn't get your stream

) : (

Getting your stream...

)}
); } export function VideoPlayer(props: VideoPlayerProps) { const videoRef = useRef(null); const [hasErrored, setErrored] = useState(false); const [isLoading, setLoading] = useState(true); const showVideo = !isLoading && !hasErrored; const mustUseHls = props.source.type === "m3u8"; // reset if stream url changes useEffect(() => { setLoading(true); setErrored(false); // hls support if (mustUseHls) { if (!videoRef.current) return; if (!Hls.isSupported()) { setLoading(false); setErrored(true); return; } const hls = new Hls(); if (videoRef.current.canPlayType('application/vnd.apple.mpegurl')) { videoRef.current.src = props.source.url; return; } hls.attachMedia(videoRef.current); hls.loadSource(props.source.url); hls.on(Hls.Events.ERROR, (event, data) => { setErrored(true); console.error(data); }); } }, [props.source.url, videoRef, mustUseHls]); let skeletonUi: null | ReactElement = null; if (hasErrored) { skeletonUi = ; } else if (isLoading) { skeletonUi = ; } return ( <> {skeletonUi} ); }