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 ? (
) : (
)}
);
}
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}
>
);
}