# WebRTC ![](https://i.imgur.com/xerndvT.png =450x) ---- # What is WebRTC ? `----` #### WebRTC (Web Real-Time Communication) is a free and open-source project providing web browsers and mobile applications with real-time communication (RTC) via APIs ---- ## WebRTC Components `----` <div style="text-align: left; margin-bottom: 20px"><b>MediaDevices</b> acquires the audio and video media (e.g., by accessing a device's camera and microphone)<!-- .element: class="fragment" data-fragment-index="1" --></div> <div style="text-align: left; margin-bottom: 20px"><b>RTCPeerConnection</b> deals with connecting two applications on different computers to communicate using a peer-to-peer protocol.<!-- .element: class="fragment" data-fragment-index="2" --></div> <div style="text-align: left; margin-bottom: 20px"><b>RTCDataChannel</b> allows bidirectional communication of arbitrary data between peers.<!-- .element: class="fragment" data-fragment-index="3" --></div> ---- ## MediaDevices `----` ``` javascript [1|5|8-10] const constraints = { 'video': true, 'audio': true } navigator.mediaDevices.getUserMedia(constraints) .then(stream => { console.log('Got MediaStream:', stream); }) .catch(error => { console.error('Error accessing media devices.', error); }); ``` ---- ## Querying media devices `----` ``` javascript [1|5|8-10] function getConnectedDevices(type, callback) { navigator.mediaDevices.enumerateDevices() .then(devices => { const filtered = devices.filter(device => device.kind === type); callback(filtered); }); } getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras)); ``` ---- ## Listening for devices changes `----` ``` javascript [1|5|8-10] // Listen for changes to media devices and update the list accordingly navigator.mediaDevices.addEventListener('devicechange', event => { const newCameraList = getConnectedDevices('video'); updateCameraList(newCameraList); }); ``` ---- ## Media constraints `----` ``` javascript [1|5|8-10] // Listen for changes to media devices and update the list accordingly // Open camera with at least minWidth and minHeight capabilities async function openCamera(cameraId, minWidth, minHeight) { const constraints = { 'audio': {'echoCancellation': true}, 'video': { 'deviceId': cameraId, 'width': {'min': minWidth}, 'height': {'min': minHeight} } } return await navigator.mediaDevices.getUserMedia(constraints); } ``` ---- ## Local playback `----` ``` javascript [1|5|8-10] async function playVideoFromCamera() { try { const constraints = {'video': true, 'audio': true}; const stream = await navigator.mediaDevices.getUserMedia(constraints); const videoElement = document.querySelector('video#localVideo'); videoElement.srcObject = stream; } catch(error) { console.error('Error opening video camera.', error); } } ``` ---- ## RTCPeerConnection `----` - Peer connections is the part of the WebRTC specifications that deals with connecting two applications on different computers to communicate using a peer-to-peer protocol. - Exchange data: - Media types information - Connectivity information ---- ## Signaling ``` javascript [1|5|8-10] // Set up an asynchronous communication channel that will be // used during the peer connection setup const signalingChannel = new SignalingChannel(remoteClientId); signalingChannel.addEventListener('message', message => { // New message from remote client received }); // Send an asynchronous message to the remote client signalingChannel.send('Hello!'); ``` ---- ## Initiating peer connections - Each peer connection is handled by a **RTCPeerConnection** object. ``` javascript [1|5|8-10] async function makeCall() { const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]} const peerConnection = new RTCPeerConnection(configuration); signalingChannel.addEventListener('message', async message => { if (message.answer) { const remoteDesc = new RTCSessionDescription(message.answer); await peerConnection.setRemoteDescription(remoteDesc); } }); const offer = await peerConnection.createOffer(); await peerConnection.setLocalDescription(offer); signalingChannel.send({'offer': offer}); } ``` ---- ## Session Description Protocol `----` SDP (Session Description Protocol) is the standard describing a peer-to-peer connection. SDP contains the codec, source address, and timing information of audio and video. ---- ## SPD `----` ``` v=0 o=alice 2890844526 2890844526 IN IP4 host.anywhere.com s= c=IN IP4 host.anywhere.com t=0 0 m=audio 49170 RTP/AVP 0 a=rtpmap:0 PCMU/8000 m=video 51372 RTP/AVP 31 a=rtpmap:31 H261/90000 m=video 53000 RTP/AVP 32 a=rtpmap:32 MPV/90000 ``` ---- ## Initiating peer connections `----` ``` javascript [1|5|8-10] const peerConnection = new RTCPeerConnection(configuration); signalingChannel.addEventListener('message', async message => { if (message.offer) { peerConnection.setRemoteDescription(new RTCSessionDescription(message.offer)); const answer = await peerConnection.createAnswer(); await peerConnection.setLocalDescription(answer); signalingChannel.send({'answer': answer}); } }); ``` ---- ## ICE candidates - Before two peers can communitcate using WebRTC, they need to exchange connectivity information. - An external service is usually used for discovering the possible candidates for connecting to a peer. - This service is called ICE and is using either a STUN or a TURN server. ---- ## Trickle ICE ``` javascript [1|5|8-10] // Listen for local ICE candidates on the local RTCPeerConnection peerConnection.addEventListener('icecandidate', event => { if (event.candidate) { signalingChannel.send({'new-ice-candidate': event.candidate}); } }); // Listen for remote ICE candidates and add them to the local RTCPeerConnection signalingChannel.addEventListener('message', async message => { if (message.iceCandidate) { try { await peerConnection.addIceCandidate(message.iceCandidate); } catch (e) { console.error('Error adding received ice candidate', e); } } }); ```` ---- ## Connection established `----` ``` javascript [1|5|8-10] // Listen for connectionstatechange on the local RTCPeerConnection peerConnection.addEventListener('connectionstatechange', event => { if (peerConnection.connectionState === 'connected') { // Peers connected! } }); ``` ---- ## Remote Streams ``` javascript [1|5|8-10] const localStream = await getUserMedia({vide: true, audio: true}); const peerConnection = new RTCPeerConnection(iceConfig); localStream.getTracks().forEach(track => { peerConnection.addTrack(track, localStream); }); ``` ``` javascript [1|5|8-10] const remoteVideo = document.querySelector('#remoteVideo'); peerConnection.addEventListener('track', async (event) => { const [remoteStream] = event.streams; remoteVideo.srcObject = remoteStream; }); ``` ---- ## Data channels ``` javascript [1|5|8-10] const peerConnection = new RTCPeerConnection(configuration); const dataChannel = peerConnection.createDataChannel(); ``` ``` javascript [1|5|8-10] dataChannel.addEventListener('open', event => { // update UI }); dataChannel.addEventListener('close', event => { // update }); ``` ---- # Data channels: Messages ``` javascript [1|5|8-10] // Send a simple text message when we click the button sendButton.addEventListener('click', event => { const message = "Hi!"; dataChannel.send(message); }) ``` ``` javascript [1|5|8-10] // Append new messages to the box of incoming messages dataChannel.addEventListener('message', event => { const message = event.data; // handle income message }); ``` ---- ## ICE `----` Interactive Connectivity Establishment (ICE) is a technique used in computer networking to find ways for two computers to talk to each other as directly as possible in peer-to-peer networking. ---- ## STUN `----` **Session Traversal Utilities for NAT** is a protocol to discover your public address and determine any restrictions in your router that would prevent a direct connection with a peer. ---- ## STUN `----` <div style="background-color: lightgray; color: #fff; padding: 40px;"> ![](https://i.imgur.com/YuaYlqf.png) </div> ---- ## TURN `----` **Traversal Using Relays around NAT** is meant to bypass the Symmetric NAT restriction by opening a connection with a TURN server and relaying all information through that server. ---- ## TURN `----` <div style="background-color: lightgray; color: #fff; padding: 40px;"> ![](https://i.imgur.com/RfYGONW.png) </div> ---- ### WebRTC `----` ![](https://i.imgur.com/XHQ5SdX.png =600x) ---- ### Refs `----` - https://webrtc.org/ - https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API - https://en.wikipedia.org/wiki/WebRTC
{"metaMigratedAt":"2023-06-16T18:00:43.683Z","metaMigratedFrom":"YAML","title":"WebRTC","breaks":true,"slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"e204d102-eabe-4ae2-b6f4-e3b4046b3b23\",\"add\":9578,\"del\":791}]"}
    449 views