// Slide #1: Getting local video stream and initializing a peer connection with it (both caller and callee) var localStream = null; var localVideo = document.getElementById('localVideo'); navigator .mediaDevices .getUserMedia({ audio: true, video: true }) .then(stream => { localVideo.srcObject = stream; localStream = stream; }); var pc = new RTCPeerConnection({ iceServers: [...] }); localStream .getTracks() .forEach(track => pc.addTrack(track, localStream)); // Slide #2: Creating SDP offer (caller) pc.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true }) .then(offer => signaling.send('offer', offer)); // Slide #3: Handling SDP offer and sending SDP answer (callee) signaling.on('offer', offer => { pc.setRemoteDescription(offer) .then(() => pc.createAnswer()) .then(answer => signaling.send('answer', answer)) }); // Slide #4: Handling SDP answer (calleer) signaling.on('answer', answer => pc.setRemoteDescription(answer)); // Slide #5: Exchanging ICE candidates pc.onicecandidate = event => signaling.send('candidate', event.candidate); signaling.on('candidate', candidate => pc.addIceCandidate(candidate)); // Slide #6: Getting remote video stream (both caller and callee) var remoteVideo = document.getElementById('remoteVideo'); pc.onaddstream = event => remoteVideo.srcObject = event.streams[0];