window.onload = function demo() { // create peer connection let pc = new RTCPeerConnection({ iceCandidatePoolSize: 4 }); // create websocket for signaling channel let ws = new WebSocket('ws://localhost:8080'); // (callback) called upon discovery of new local ICE candidate pc.onicecandidate = function(event) { if (event.candidate) { console.log("local candidate:\n%c%s", "color: green", event.candidate.candidate); ws.send(JSON.stringify(event.candidate)); } }; // (callback) called upon reception of new remote video track pc.ontrack = function(event) { document.getElementById("remoteVideo").srcObject = event.streams[0]; }; // receive remote answer or candidate ws.onmessage = function(event) { try { let d = JSON.parse(event.data); if ('candidate' in d) { if (d.candidate) { console.log("remote candidate:\n%c%s", "color: blue;", d.candidate); pc.addIceCandidate(d).catch((e) => { console.log("addIceCandidate:\n%c%s", "color: red;", e); }); } } else if ('sdp' in d) { pc.setRemoteDescription(d).catch((e) => { console.log("setRemoteDescription:\n%c%s", "color: red;", e); }); console.log("remote answer:\n%c%s", "color: blue;", d.sdp); } } catch(e) { console.log("remote error:\n%c%s", "color: red;", event.data); } }; // create offer and set to remote peer ws.onopen = function(event) { pc.createOffer({ offerToReceiveVideo: true }).then(function(offer) { console.log("local offer:\n%c%s", "color: green;", offer.sdp); pc.setLocalDescription(offer); ws.send(JSON.stringify(offer)); }); }; }