import { useEffect, useRef, useState } from "react"; import axios from "axios"; import { toast } from "react-toastify"; const lines = ["line1"]; // 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(); const incomingVideoRef = useRef(); const [localMediaStream, setLocalMediaStream] = useState(); // connect to media server for line connections as a broadcaster and consumer useEffect(() => { (async () => { // note: [later] create a unique peer connection to server for each line // lines.forEach((lineId) => { // }); // create the peer and add the tranceiver const peer = await createPeer("line1"); // console.log(`peer connection for ${lineId}`, peer); })(); }, [lines]); const createPeer = async (lineId: string) => { const peer = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.stunprotocol.org", }, ], }); peer.onconnectionstatechange = console.log; peer.onnegotiationneeded = () => console.log("negotiation needed"); peer.onicecandidate = console.warn; const localMediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: false, }); console.log("localMediaStream", localMediaStream); console.log(`tracks: `, localMediaStream.getTracks()); setLocalMediaStream(localMediaStream); if (videoRef.current) { toast("got local user video stream"); videoRef.current.srcObject = localMediaStream; // todo: add other tracks like screenshare and such localMediaStream.getTracks().forEach((track: MediaStreamTrack) => { console.log( `adding track to peer connection: different mediums | audio, video, screen based on selection` ); peer.addTrack(track, localMediaStream); }); } peer.addTransceiver("video"); console.log(peer.connectionState); // 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)); peer.ontrack = handleTrackEvent; console.log( `done handling negotiation with media server | remote description: `, desc ); console.log(peer); return peer; }; const handleNegotiationNeededEvent = async ( peer: RTCPeerConnection, lineId: string ) => {}; // render tracks on the server peer sending something // todo: memoize the line so that we can show user where stream is coming from const handleTrackEvent = (e: any) => { const incomingStream = e.streams[0]; console.log("incoming stream", incomingStream); if (incomingVideoRef.current) { toast(`setting incoming stream ref`); incomingVideoRef.current.srcObject = new MediaStream(incomingStream); setInterval(() => { incomingVideoRef!.current!.play().then(console.log).catch(console.log); }, 2000); incomingVideoRef.current.oncanplay = () => console.log("cannn PLLLAYY VID!!!!"); incomingVideoRef.current.play().then(console.log).catch(console.log); } }; 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)
); }