Preview:
// Get user media
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then(stream => {
    const localVideo = document.getElementById('localVideo');
    localVideo.srcObject = stream;

    const peerConnection = new RTCPeerConnection();
    stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));

    // Set up ICE handling
    peerConnection.onicecandidate = event => {
      if (event.candidate) {
        // Send the candidate to the remote peer
        sendToServer({ type: 'candidate', candidate: event.candidate });
      }
    };

    // When remote stream arrives
    peerConnection.ontrack = event => {
      const remoteVideo = document.getElementById('remoteVideo');
      remoteVideo.srcObject = event.streams[0];
    };

    // Create an offer to connect
    peerConnection.createOffer()
      .then(offer => peerConnection.setLocalDescription(offer))
      .then(() => {
        // Send the offer to the remote peer
        sendToServer({ type: 'offer', offer: peerConnection.localDescription });
      });

    // Handle offer from a remote peer
    receiveFromServer(message => {
      if (message.type === 'offer') {
        peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer))
          .then(() => peerConnection.createAnswer())
          .then(answer => peerConnection.setLocalDescription(answer))
          .then(() => {
            // Send the answer to the remote peer
            sendToServer({ type: 'answer', answer: peerConnection.localDescription });
          });
      } else if (message.type === 'answer') {
        peerConnection.setRemoteDescription(new RTCSessionDescription(message.answer));
      } else if (message.type === 'candidate') {
        peerConnection.addIceCandidate(new RTCIceCandidate(message.candidate));
      }
    });
  })
  .catch(error => {
    console.error('Error accessing media devices.', error);
  });

function sendToServer(message) {
  // Implement server communication to exchange messages
}

function receiveFromServer(callback) {
  // Implement server communication to receive messages
}
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter