var name var connections = new Map() const configuration = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] } const offerOptions = { offerToReceiveAudio: 1, offerToReceiveVideo: 1 } function handleLogin(success) { if (success === false) { alert('try a different username') } else { loginDiv.style.display = 'none' connectDiv.style.display = 'block' } } async function createPeerConnection(target) { console.log('CREATED PEER CONNECTION') var connection = new RTCPeerConnection(configuration) connections[target] = connection connection.onicecandidate = function(event) { if (event.candidate) { send({ type: 'candidate', name: name, target: target, candidate: event.candidate }) } } connection.onnegotiationneeded = function() { handleNegotiationNeededEvent(target) } connection.ontrack = function(event) { handleTrackEvent(event) } connection.onsignalingstatechange = function() { handleSignalingStateChangeEvent(connection) } connection.oniceconnectionstatechange = function() { handleICEConnectionStateChangeEvent(connection) } connection.onicegatheringstatechange = function() { handleICEGatheringStateChangeEvent(connection) } // window.setInterval(getConnectionStats, 1000) } function handleICEConnectionStateChangeEvent(connection) { console.log('ICE CONNECTION CHANGE ' + connection.iceConnectionState) } function handleICEGatheringStateChangeEvent(connection) { console.log('ICE GATHERING CHANGE ' + connection.iceGatheringState) } async function makeOffer(target) { createPeerConnection(target) var connection = connections[target] var offer = await connection.createOffer() send({ type: 'offer', name: name, target: target, offer: offer }) await connection.setLocalDescription(offer) } async function handleOffer(offer, target) { console.log('GOT OFFER FROM ' + target) await createPeerConnection(target) var connection = connections[target] await connection.setRemoteDescription(new RTCSessionDescription(offer)) if (stream) { console.log('STREAM DETECTED') stream.getTracks().forEach((track) => { console.log('ADDED TRACK') connection.addTrack(track, stream) }) } var answer = await connection.createAnswer() await connection.setLocalDescription(answer) send({ type: 'answer', name: name, target: target, answer: answer }) for (let user of connections.keys()) { console.log(user); } console.log('CONNECTION SIZE ' + connections.size) videoTitle.innerHTML = name + ' | ' + connections.size + ' users connected' } async function handleAnswer(answer, target) { console.log('GOT ANSWER FROM ' + target) var connection = connections[target] await connection.setRemoteDescription(new RTCSessionDescription(answer)) } async function handleCandidate(candidate, target) { console.log('GOT CANDIDATE FROM ' + target) var connection = connections[target] await connection.addIceCandidate(new RTCIceCandidate(candidate)) } async function handleNegotiationNeededEvent(target) { console.log('NEGOTIATION NEEDED FROM ' + target) var connection = connections[target] var offer = await connection.createOffer(offerOptions) await connection.setLocalDescription(offer) send({ type: 'video-offer', name: name, target: target, sdp: connection.localDescription }) } function handleLeave() { connections.forEach((connection) => { connection.close() connection = null }) connections = new Map() remoteVideo.pause() remoteVideo.src = null } async function handleVideoOffer(sdp, target) { console.log('GOT VIDEO OFFER FROM ' + target) await createPeerConnection(target) var connection = connections[target] await connection.setRemoteDescription(new RTCSessionDescription(sdp)) if (stream) { console.log('STREAM DETECTED') stream.getTracks().forEach((track) => { console.log('ADDED TRACK') connection.addTrack(track, stream) }) } var answer = await connection.createAnswer() await connection.setLocalDescription(answer) send({ type: 'video-answer', name: name, target: target, sdp: answer }) //var keys = connections.keys().next().value videoTitle.innerHTML = name + ' | connected to ' + target } async function handleVideoAnswer(sdp, target) { console.log('GOT VIDEO ANSWER FROM ' + target) var connection = connections[target] await connection.setRemoteDescription(new RTCSessionDescription(sdp)) } async function handleSignalingStateChangeEvent(connection) { console.log('STATE CHANGED TO : ' + connection.signalingState) switch(connection.signalingState) { case 'closed': await connection.close() break } } function handleTrackEvent(event) { console.log('GOT TRACK') remoteVideo.srcObject = event.streams[0] videoDiv.style.display = 'block' loadDiv.style.display = 'none' } function getConnectionStats() { connections.forEach((connection, target) => { console.log('[' + target + '] ' + connection.connectionState) }) }