Some checks reported warnings
arcad/arcast/pipeline/head This commit is unstable
114 lines
2.8 KiB
TypeScript
114 lines
2.8 KiB
TypeScript
import {
|
|
FunctionComponent,
|
|
useCallback,
|
|
useEffect,
|
|
useRef,
|
|
useState,
|
|
} from "react";
|
|
import styles from "./ScreenViewer.module.css";
|
|
import {
|
|
ScreenSharingClient,
|
|
StateChangedEvent,
|
|
StateChangedEventType,
|
|
StreamChangedEvent,
|
|
StreamChangedEventType,
|
|
} from "../../api/webrtc";
|
|
|
|
export interface ScreenViewerProps {
|
|
sessionId: string;
|
|
}
|
|
|
|
export const ScreenViewer: FunctionComponent<ScreenViewerProps> = ({
|
|
sessionId,
|
|
}) => {
|
|
const videoRef = useRef<HTMLVideoElement>(null);
|
|
const [client, setClient] = useState<ScreenSharingClient | null>(null);
|
|
const [stream, setStream] = useState<MediaStream | null>(null);
|
|
const [state, setState] = useState<string | null>(null);
|
|
|
|
const onStreamChanged = useCallback((evt: Event) => {
|
|
setStream((evt as StreamChangedEvent).stream);
|
|
}, []);
|
|
|
|
const onStateChanged = useCallback((evt: Event) => {
|
|
setState((evt as StateChangedEvent).state);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const client = new ScreenSharingClient(sessionId);
|
|
|
|
client.addEventListener(StreamChangedEventType, onStreamChanged);
|
|
client.addEventListener(StateChangedEventType, onStateChanged);
|
|
client.connect();
|
|
setClient(client);
|
|
|
|
return () => {
|
|
client.removeEventListener(StreamChangedEventType, onStreamChanged);
|
|
client.removeEventListener(StateChangedEventType, onStateChanged);
|
|
client.close();
|
|
setClient(null);
|
|
};
|
|
}, [sessionId, onStreamChanged, onStateChanged]);
|
|
|
|
useEffect(() => {
|
|
if (!videoRef.current) return;
|
|
|
|
const video = videoRef.current;
|
|
|
|
console.log("Changing video stream", video, stream);
|
|
|
|
video.autoplay = true;
|
|
video.playsInline = true;
|
|
video.srcObject = stream;
|
|
video.muted = true;
|
|
}, [videoRef, stream]);
|
|
|
|
const isVideoReady = state === "connected" && stream !== null;
|
|
|
|
console.log("isVideoReady", isVideoReady);
|
|
|
|
return (
|
|
<div className={styles.root}>
|
|
<h1
|
|
style={{
|
|
display: `${isVideoReady ? "none" : "block"}`,
|
|
}}
|
|
>
|
|
<ConnectionState state={state} />
|
|
</h1>
|
|
<video
|
|
ref={videoRef}
|
|
className={styles.video}
|
|
style={{
|
|
display: `${isVideoReady ? "block" : "none"}`,
|
|
}}
|
|
></video>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export interface ConnectionStateProps {
|
|
state: string | null;
|
|
}
|
|
|
|
export const ConnectionState: FunctionComponent<ConnectionStateProps> = ({
|
|
state,
|
|
}) => {
|
|
switch (state) {
|
|
case null:
|
|
return <span>Connecting...</span>;
|
|
case "Connecté":
|
|
return <span>Connection established !</span>;
|
|
case "disconnected":
|
|
return <span>Connection lost !</span>;
|
|
case "failed":
|
|
return <span>Connection failed !</span>;
|
|
default:
|
|
return (
|
|
<span>
|
|
État inconnu (<code>{state}</code>)
|
|
</span>
|
|
);
|
|
}
|
|
};
|