/** * @type {import("./MWSE/index").default} */ let mwse; /** * @type {string} */ let mySocketId; /** * @type {string} */ let myIPAddress; /** * @type {string} */ let myNumber; /** * @type {string} */ let roomid; /** * @type {import("./MWSE/Room").default} */ let room; /** * @type {MediaStream} */ let primaryVideoContent; /** * @type {HTMLVideoElement} */ let primaryVideo; /** * @type {HTMLVideoElement} */ let primaryVideoShadow; /** * @type {HTMLVideoElement} */ let secondaryVideo; /** * @type {MediaStream} */ let outgoingStream; /** * @type {MediaStream} */ let outgoingStreamOnlyVideo; /** * @type {HTMLDivElement} */ let videoContainer = document.querySelector(".videolist"); function connect() { mwse = new MWSE({ endpoint: "wss://ws.saqut.com" }); mwse.scope(beginEngine); } /** * @type {HTMLVideoElement} */ let activeVideo; function setPrimaryVideo(video, soundOn) { primaryVideo.srcObject = video; primaryVideoShadow.srcObject = video; if(soundOn == undefined) { primaryVideo.muted = 1; primaryVideo.volume = 0; }else if(soundOn){ primaryVideo.muted = 0; primaryVideo.volume = 1; }else{ primaryVideo.muted = 0; primaryVideo.volume = 0; } } function setSecondaryVideo(video) { // secondaryVideo.srcObject = video; } function templateVideo(name, stream) { let i = document.createElement("video"); i.muted = 1; i.classList.add("frame") i.playsInline = 1; i.autoplay = 1; i.dataset.name = name; if(stream) i.srcObject = stream; return i; } function addVideoList(name, stream, peer) { if(!videoContainer.querySelector(`[name="${name}"]`)) { let video = templateVideo(name, stream); video.dataset.user = peer.socketId; video.onclick = function(){ if(activeVideo) { activeVideo.classList.remove("active"); }; video.classList.add("active"); activeVideo = video; setPrimaryVideo(stream, true); }; videoContainer.appendChild(video); } } function removeVideoList(name) { if(videoContainer.querySelector(`[data-name="${name}"]`)) { let k = videoContainer.querySelector(`[data-name="${name}"]`); if(k.dataset.user == activeVideo?.dataset.user || !activeVideo) { setPrimaryVideo(outgoingStreamOnlyVideo, false); } k.remove(); } } async function beginEngine() { let me = mwse.peer("me"); me.disablePairAuth(); mySocketId = me.socketId; myIPAddress = await mwse.virtualPressure.allocAPIPAddress(); myNumber = await mwse.virtualPressure.allocAPNumber(); let url = new URL(window.location); roomid = url.searchParams.get("room"); if(!!roomid == 0) { let hash = window.crypto.randomUUID(); url.searchParams.set("room", hash); window.location = url.href; }; connectRoom(roomid); }; window.addEventListener("load", () => { primaryVideo = document.querySelector("#primaryVideo"); secondaryVideo = document.querySelector("#secondaryVideo"); primaryVideoShadow = document.querySelector("#primaryVideoShadow"); connect() }); async function startOutgoingWebcam() { outgoingStream = await navigator.mediaDevices.getUserMedia({video: true, audio: true}); outgoingStreamOnlyVideo = new MediaStream(outgoingStream); outgoingStreamOnlyVideo.removeTrack(outgoingStreamOnlyVideo.getAudioTracks()[0]) } async function connectRoom() { await startOutgoingWebcam(); room = mwse.room({ name: roomid, joinType: "free", accessType: "private", description: "Private free joined room", ifexistsJoin: true, notifyActionEjected: true, notifyActionInvite: false, notifyActionJoined: true }); await room.createRoom(); room.on("join", peer => IncomingPeer(peer, true)); room.on("eject", peer => OutgoingPeer(peer)); for (const peer of await room.fetchPeers()) { IncomingPeer(peer) } if(!primaryVideoContent) { setPrimaryVideo(outgoingStreamOnlyVideo); } setSecondaryVideo(outgoingStreamOnlyVideo); addVideoList("My Webcam",outgoingStreamOnlyVideo, mwse.peer("me")) } /** * @param {import("./MWSE/Peer").default} peer */ function IncomingPeer(peer,activeConnect) { let sendedOTP = false; peer.createRTC({ iceServers:[{ urls: "turn:161.97.136.175:3478", username: "argist-eu-east-25", credential: "ee7df17eed35f4cf5a207777f3c0cd7d3b1901a5de7aff52ea55742289d7fee2" },{ urls: "stun:stun.l.google.com:19302" },{ urls: "stun:stun1.l.google.com:19302" },{ urls: "stun:stun2.l.google.com:19302" },{ urls: "stun:stun3.l.google.com:19302" },{ urls: "stun:stun4.l.google.com:19302" }], bundlePolicy: "max-compat", iceCandidatePoolSize: 0, iceTransportPolicy: "all" }); if(activeConnect) { peer.rtc.connect(); } peer.rtc.on('connected',() => { if(!activeConnect && !sendedOTP) { sendedOTP = true; peer.rtc.sendStream(outgoingStream, "Webcam", {}); } }); peer.rtc.on('disconnected',() => { removeVideoList(peer.streamY, peer); }); peer.rtc.on("stream:added", ({stream,name}) => { peer.streamY = peer.socketId + " | " + name + " - " + stream.id; addVideoList(peer.socketId + " | " + name + " - " + stream.id,stream, peer); if(!primaryVideoContent) { primaryVideoContent = stream; setPrimaryVideo(primaryVideoContent, true); } if(activeConnect && !sendedOTP) { sendedOTP = true; peer.rtc.sendStream(outgoingStream, "Webcam", {}); } }) } /** * @param {import("./MWSE/Peer").default} peer */ function OutgoingPeer(peer) { removeVideoList(peer.streamY, peer); }