# WebRTC

----
# 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;">

</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;">

</div>
----
### WebRTC
`----`

----
### 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}]"}