Files
zap.stream/src/element/live-video-player.tsx
2023-07-24 21:43:51 +01:00

100 lines
3.0 KiB
TypeScript

import Hls from "hls.js";
import { useEffect, useMemo, useRef, useState } from "react";
import { WISH } from "wish";
export enum VideoStatus {
Online = "online",
Offline = "offline",
}
export interface VideoPlayerProps {
stream?: string, status?: string, poster?: string
}
export function LiveVideoPlayer(
props: VideoPlayerProps
) {
const video = useRef<HTMLVideoElement>(null);
const streamCached = useMemo(() => props.stream, [props.stream]);
const [status, setStatus] = useState<VideoStatus>();
const [src, setSrc] = useState<string>();
useEffect(() => {
if (
streamCached &&
video.current
) {
if (Hls.isSupported()) {
try {
const hls = new Hls();
hls.loadSource(streamCached);
hls.attachMedia(video.current);
hls.on(Hls.Events.ERROR, (event, data) => {
console.debug(event, data);
const errorType = data.type;
if (errorType === Hls.ErrorTypes.NETWORK_ERROR && data.fatal) {
hls.stopLoad();
hls.detachMedia();
setStatus(VideoStatus.Offline);
}
});
hls.on(Hls.Events.MANIFEST_PARSED, () => {
setStatus(VideoStatus.Online);
});
hls.on(Hls.Events.LEVEL_SWITCHING, (e, l) => {
console.debug("HLS Level Switch", l);
});
return () => hls.destroy();
} catch (e) {
console.error(e);
setStatus(VideoStatus.Offline);
}
} else {
setSrc(streamCached);
setStatus(VideoStatus.Online);
video.current.muted = true;
video.current.load();
}
}
}, [video, streamCached, props.status]);
return (
<div className="video-overlay">
<div className={status}>
<div>{status}</div>
</div>
<video ref={video} autoPlay={true} poster={props.poster} src={src} playsInline={true} controls={status === VideoStatus.Online} />
</div>
);
}
export function WebRTCPlayer(props: VideoPlayerProps) {
const video = useRef<HTMLVideoElement>(null);
const streamCached = useMemo(() => "https://customer-uu10flpvos4pfhgu.cloudflarestream.com/7634aee1af35a2de4ac13ca3d1718a8b/webRTC/play", [props.stream]);
const [status] = useState<VideoStatus>();
//https://customer-uu10flpvos4pfhgu.cloudflarestream.com/7634aee1af35a2de4ac13ca3d1718a8b/webRTC/play
useEffect(() => {
if (video.current && streamCached) {
const client = new WISH();
client.addEventListener("log", console.debug);
client.WithEndpoint(streamCached, true)
client.Play().then(s => {
if (video.current) {
video.current.srcObject = s;
}
}).catch(console.error);
return () => { client.Disconnect().catch(console.error); }
}
}, [video, streamCached]);
return (
<div className="video-overlay">
<div className={status}>
<div>{status}</div>
</div>
<video ref={video} autoPlay={true} poster={props.poster} controls={status === VideoStatus.Online} />
</div>
);
}