import { useEffect, useRef, useState } from "react"; import axios from "axios"; import { toast } from "react-toastify"; const lines = ["line1", "line2", "line3", "line4", "line5"]; // todo: join different combinations of lines based on page params // for now, every browser tab/client joins all 5 lines and streams to one specific one export default function VideoChat() { const [selectedLine, setSelectedLine] = useState(lines[0]); const videoRef = useRef(); // connect to media server for line connections as a broadcaster and consumer useEffect(() => { navigator.mediaDevices .getUserMedia({ video: true, audio: true }) .then((mediaStream: any) => { console.log("mediaStream", mediaStream); if (videoRef.current) { toast("got local user video stream"); videoRef.current.srcObject = mediaStream; videoRef.current.play(); // create a unique peer connection to server for each line lines.forEach((lineId) => { // create the peer and add the tranceiver const peer = createPeer(lineId); console.log(`peer connection for ${lineId}`, peer); peer.addTransceiver("video"); mediaStream.getTracks().forEach((track: any) => { console.log(`adding track to peer connection`); peer.addTrack(track, mediaStream); }); }); } }); }, [lines]); const createPeer = (lineId: string) => { const peer = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.stunprotocol.org", }, ], }); peer.ontrack = handleTrackEvent; peer.onnegotiationneeded = () => handleNegotiationNeededEvent(peer, lineId); return peer; }; const handleNegotiationNeededEvent = async ( peer: RTCPeerConnection, lineId: string ) => { // create offer const offer = await peer.createOffer(); await peer.setLocalDescription(offer); const payload = { sdp: peer.localDescription, }; // send offer to server to accept const { data } = await axios.post( `http://localhost:5000/api/rtc/join/${lineId}`, payload ); // receive server acceptance and set remote configs const desc = new RTCSessionDescription(data.data.sdp); peer.setRemoteDescription(desc).catch((e) => console.log(e)); console.log(`done handling negotiation with media server`); }; // render tracks on the server peer sending something function handleTrackEvent(e: any) { const incomingStream = e.streams[0]; console.log("incoming stream", e); } return (

This is a baller video app

  1. - user joins 5 lines hardcoded lines (stream to and accept any streams in those lines)
  2. - user can see which line certain content is coming from
  3. - user can set medium: share screen or video (along with audio)
  4. - user can select medium they want to send to
  5. - user hold tilde to stream selected medium in a specific line
  6. - user can receive transmitted stream content from any line, and see which line it's streamed to

Your Video

toggle medium (todo)
); }