Premiers pas avec WebRTC

WebRTC est un nouveau front depuis la longue guerre pour un Web ouvert et non encombré.

Brendan Eich, inventeur de JavaScript

Communication en temps réel sans plug-ins

Imaginez un monde dans lequel votre téléphone, votre télévision et votre ordinateur pourraient communiquer sur une plate-forme commune. Imaginez qu'il soit facile d'ajouter le chat vidéo et le partage de données peer-to-peer à votre application Web. C'est la vision de WebRTC.

Pour essayer, WebRTC est disponible sur ordinateur et sur mobile dans Google Chrome, Safari, Firefox et Opera. L'application de chat vidéo disponible sur appr.tc constitue un bon point de départ:

  1. Ouvrez appr.tc dans votre navigateur.
  2. Cliquez sur Rejoindre pour rejoindre un salon de chat et permettre à l'application d'utiliser votre webcam.
  3. Ouvrez l'URL affichée à la fin de la page dans un nouvel onglet ou, mieux encore, sur un autre ordinateur.

Guide de démarrage rapide

Vous n'avez pas le temps de lire cet article ou vous ne voulez que du code ?

Vous pouvez également accéder directement à l'atelier de programmation WebRTC, un guide par étapes qui explique comment créer une application de chat vidéo complète, incluant un simple serveur de signalement.

Un très court aperçu de WebRTC

L'un des derniers grands défis du Web est de permettre la communication humaine par la voix et la vidéo: la communication en temps réel ou RTC en abrégé. La fonctionnalité RTC doit être aussi naturelle dans une application Web que la saisie de texte dans une entrée de texte. Sans cela, vous êtes limité dans votre capacité à innover et à développer de nouvelles façons d'interagir.

À l'origine, la RTC était une entreprise et un processus complexe qui nécessitait l'obtention de licences ou le développement en interne de technologies audio et vidéo coûteuses. Intégrer la technologie RTC aux contenus, données et services existants s'est révélé difficile et chronophage, en particulier sur le Web.

Le chat vidéo Gmail a gagné en popularité en 2008 et, en 2011, Google a lancé Hangouts, qui utilise Google Talk (tout comme Gmail). Google a acheté GIPS, une entreprise qui a développé de nombreux composants requis pour la fonctionnalité RTC, tels que les codecs et les techniques d'annulation de l'écho. Google a développé en Open Source les technologies développées par le GIPS et a interagi avec les organismes de normalisation compétents à l'IETF (Internet Engineering Task Force) et au World Wide Web Consortium (W3C) pour garantir le consensus du secteur. En mai 2011, Ericsson a conçu la première implémentation de WebRTC.

WebRTC a implémenté des normes ouvertes pour la communication vidéo, audio et de données en temps réel et sans plug-in. Le besoin était réel:

  • De nombreux services Web utilisaient la fonctionnalité RTC, mais avaient besoin de téléchargements, d'applications natives ou de plug-ins. comme Skype, Facebook et Hangouts.
  • Le téléchargement, l'installation et la mise à jour de plug-ins sont complexes, source d'erreurs et ennuyeux.
  • Les plug-ins sont difficiles à déployer, déboguer, dépanner, tester et gérer. Ils peuvent nécessiter des licences et être intégrés à des technologies complexes et coûteuses. Il est souvent difficile de persuader les utilisateurs d'installer des plug-ins.

Les principes directeurs du projet WebRTC sont les suivants : ses API doivent être Open Source, sans frais, standardisées, intégrées aux navigateurs Web et plus efficaces que les technologies existantes.

Où en sommes-nous maintenant ?

WebRTC est utilisé dans diverses applications, comme Google Meet. WebRTC a également été intégré aux applications natives WebKitGTK+ et Qt.

WebRTC implémente les trois API suivantes : - MediaStream (également appelé getUserMedia) - RTCPeerConnection - RTCDataChannel

Les API sont définies dans ces deux spécifications:

Les trois API sont compatibles avec Chrome, Safari, Firefox, Edge et Opera sur mobile et ordinateur.

getUserMedia: pour obtenir des démonstrations et du code, consultez les exemples WebRTC ou les incroyables exemples de Chris Wilson qui utilisent getUserMedia comme entrée pour l'audio Web.

RTCPeerConnection: pour une démonstration simple et une application de chat vidéo entièrement fonctionnelle, consultez les exemples de connexion de pairs et appr.tc de WebRTC. Cette application utilise adapter.js, un shim JavaScript géré par Google avec l'aide de la communauté WebRTC, pour éliminer les différences de navigateur et les modifications de spécifications.

RTCDataChannel: pour voir cela en action, consultez les exemples WebRTC pour consulter l'une des démonstrations de canaux de données.

L'atelier de programmation WebRTC montre comment utiliser les trois API pour créer une application simple de chat vidéo et de partage de fichiers.

Votre premier WebRTC

Les applications WebRTC doivent effectuer plusieurs opérations:

  • Diffusez des contenus audio, vidéo ou autres.
  • Obtenez des informations réseau, telles que les adresses IP et les ports, et échangez-les avec d'autres clients WebRTC (appelés pairs) pour permettre la connexion, même via des NAT et des pare-feu.
  • Coordonner les communications de signalement pour signaler les erreurs, et lancer ou fermer les sessions.
  • Échangez des informations sur les médias et les fonctionnalités du client, telles que la résolution et les codecs.
  • Diffusez des contenus audio, vidéo ou de données.

Pour acquérir et communiquer des flux de données, WebRTC implémente les API suivantes:

  • MediaStream a accès aux flux de données (via la caméra et le micro de l'utilisateur, par exemple).
  • RTCPeerConnection vous permet de passer des appels audio ou vidéo avec des fonctionnalités de chiffrement et de gestion de la bande passante.
  • RTCDataChannel permet la communication peer-to-peer de données génériques.

Une discussion détaillée sur le réseau et les différents aspects de WebRTC sera présentée ultérieurement.

API MediaStream (également appelée API getUserMedia)

L'API MediaStream représente les flux multimédias synchronisés. Par exemple, un flux provenant de l'entrée de la caméra et du micro contient des pistes audio et vidéo synchronisées. (Ne confondez pas MediaStreamTrack avec l'élément <track>, qui est entièrement différent.)

Le moyen le plus simple de comprendre l'API MediaStream est de l'examiner dans le monde réel:

  1. Dans votre navigateur, accédez à Exemples WebRTC getUserMedia.
  2. Ouvrez la console.
  3. Inspectez la variable stream, qui se trouve dans un champ d'application global.

Chaque MediaStream comporte une entrée, qui peut être une MediaStream générée par getUserMedia(), et une sortie, qui peut être transmise à un élément vidéo ou à un RTCPeerConnection.

La méthode getUserMedia() utilise un paramètre d'objet MediaStreamConstraints et renvoie un Promise qui résout un objet MediaStream.

Chaque MediaStream possède un label, par exemple 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'. Un tableau de valeurs MediaStreamTrack est renvoyé par les méthodes getAudioTracks() et getVideoTracks().

Pour l'exemple getUserMedia, stream.getAudioTracks() renvoie un tableau vide (car il n'y a pas de son) et, en supposant qu'une webcam fonctionnelle est connectée, stream.getVideoTracks() renvoie un tableau d'un MediaStreamTrack représentant le flux de la webcam. Chaque MediaStreamTrack est d'un genre ('video' ou 'audio'), d'un label (par exemple, 'FaceTime HD Camera (Built-in)') et représente un ou plusieurs canaux audio ou vidéo. Dans le cas présent, il n'y a qu'une seule piste vidéo et pas de son, mais il est facile d'imaginer des cas d'utilisation où il en existe davantage, comme une application de chat qui reçoit les flux de la caméra avant, de la caméra arrière, du micro et une application qui partage son écran.

Vous pouvez associer un élément MediaStream à un élément vidéo en définissant l'attribut srcObject. Auparavant, pour cela, vous deviez définir l'attribut src sur une URL d'objet créée avec URL.createObjectURL(), mais cela est désormais obsolète.

getUserMedia peut également être utilisé comme nœud d'entrée pour l'API Web Audio:

// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
  audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
  audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
  console.log('Sorry! Web Audio not supported.');
}

// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;

// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;

navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
  // Create an AudioNode from the stream.
  const mediaStreamSource =
    audioContext.createMediaStreamSource(stream);
  mediaStreamSource.connect(filterNode);
  filterNode.connect(gainNode);
  // Connect the gain node to the destination. For example, play the sound.
  gainNode.connect(audioContext.destination);
});

Les applications et les extensions basées sur Chromium peuvent également intégrer getUserMedia. L'ajout d'autorisations audioCapture et/ou videoCapture au fichier manifeste permet de demander et de n'accorder l'autorisation qu'une seule fois lors de l'installation. Par la suite, l'utilisateur n'est plus invité à autoriser l'accès à la caméra ou au micro.

L'autorisation ne doit être accordée qu'une seule fois pour getUserMedia(). La première fois, un bouton "Autoriser" s'affiche dans la barre d'informations du navigateur. L'accès HTTP pour getUserMedia() a été abandonné dans Chrome à la fin de l'année 2015, car il avait été classé comme fonctionnalité puissante.

Le but est d'activer un MediaStream pour n'importe quelle source de flux de données, et pas seulement une caméra ou un micro. Cela permettrait de diffuser des flux à partir de données stockées ou de sources de données arbitraires, telles que des capteurs ou d'autres entrées.

getUserMedia() prend vraiment vie en combinaison avec d'autres API et bibliothèques JavaScript:

  • Webcam Toy est une application de photomaton qui utilise WebGL pour ajouter des effets bizarres et merveilleux aux photos, qui peuvent être partagées ou enregistrées en local.
  • FaceKat est un jeu de suivi des visages créé avec headtrackr.js.
  • ASCII Camera utilise l'API Canvas pour générer des images ASCII.
Image ASCII générée par idevelop.ro/ascii-camera
de l'art ASCII de la goume !

Contraintes

Vous pouvez utiliser des contraintes pour définir des valeurs de résolution vidéo pour getUserMedia(). Cela permet également de prendre en charge d'autres contraintes, telles que le format, le mode de face (caméra avant ou arrière), la fréquence d'images, la hauteur et la largeur, et une méthode applyConstraints().

Pour obtenir un exemple, consultez Exemples WebRTC getUserMedia: sélectionner la résolution.

Définir une valeur de contrainte non autorisée génère une valeur DOMException ou OverconstrainedError si, par exemple, une résolution demandée n'est pas disponible. Pour voir cela en pratique, consultez les exemples WebRTC getUserMedia: sélectionner la résolution pour une démonstration.

Capture d'écran et capture d'onglet

Les applications Chrome permettent également de partager la vidéo en direct d'un seul onglet du navigateur ou de l'ensemble du bureau via les API chrome.tabCapture et chrome.desktopCapture. Pour obtenir une démonstration et en savoir plus, consultez Partager l'écran avec WebRTC. Cet article date de quelques années, mais il est toujours intéressant.)

Il est également possible d'utiliser la capture d'écran en tant que source MediaStream dans Chrome à l'aide de la contrainte chromeMediaSource expérimentale. Notez que la capture d'écran nécessite HTTPS et ne doit être utilisée qu'en développement, car elle est activée via un indicateur de ligne de commande, comme expliqué dans cet article.

Signalisation: contrôle de session, informations réseau et multimédias

WebRTC utilise RTCPeerConnection pour communiquer des flux de données entre les navigateurs (également appelés pairs), mais a également besoin d'un mécanisme pour coordonner la communication et envoyer des messages de contrôle, un processus appelé signalisation. Les méthodes et protocoles de signalisation ne sont pas spécifiés par WebRTC. Le signal ne fait pas partie de l'API RTCPeerConnection.

À la place, les développeurs d'applications WebRTC peuvent choisir le protocole de messagerie de leur choix, tel que SIP ou XMPP, et n'importe quel canal de communication duplex approprié (bidirectionnel). L'exemple appr.tc utilise XHR et l'API Channel comme mécanisme de signalement. L'atelier de programmation utilise Socket.io s'exécutant sur un serveur de nœuds.

Le signal permet d'échanger trois types d'informations:

  • Messages de contrôle de session: pour initialiser ou fermer la communication, et signaler les erreurs.
  • Configuration du réseau: vers l'extérieur, quels sont l'adresse IP et le port de votre ordinateur ?
  • Fonctionnalités multimédias: quels codecs et résolutions peuvent être gérés par votre navigateur et le navigateur avec lequel il souhaite communiquer ?

L'échange d'informations via le signal doit s'effectuer correctement avant que le streaming peer-to-peer puisse commencer.

Par exemple, imaginez qu'Alice veuille communiquer avec Bob. Voici un exemple de code tiré de la spécification WebRTC W3C, qui illustre le processus de signalement en action. Le code suppose l'existence d'un mécanisme de signalement créé dans la méthode createSignalingChannel(). Notez également que dans Chrome et Opera, RTCPeerConnection est actuellement préfixé.

// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);

// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});

// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
  try {
    await pc.setLocalDescription(await pc.createOffer());
    // Send the offer to the other peer.
    signaling.send({desc: pc.localDescription});
  } catch (err) {
    console.error(err);
  }
};

// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
  // Don't set srcObject again if it is already set.
  if (remoteView.srcObject) return;
  remoteView.srcObject = event.streams[0];
};

// Call start() to initiate.
async function start() {
  try {
    // Get local stream, show it in self-view, and add it to be sent.
    const stream =
      await navigator.mediaDevices.getUserMedia(constraints);
    stream.getTracks().forEach((track) =>
      pc.addTrack(track, stream));
    selfView.srcObject = stream;
  } catch (err) {
    console.error(err);
  }
}

signaling.onmessage = async ({desc, candidate}) => {
  try {
    if (desc) {
      // If you get an offer, you need to reply with an answer.
      if (desc.type === 'offer') {
        await pc.setRemoteDescription(desc);
        const stream =
          await navigator.mediaDevices.getUserMedia(constraints);
        stream.getTracks().forEach((track) =>
          pc.addTrack(track, stream));
        await pc.setLocalDescription(await pc.createAnswer());
        signaling.send({desc: pc.localDescription});
      } else if (desc.type === 'answer') {
        await pc.setRemoteDescription(desc);
      } else {
        console.log('Unsupported SDP type.');
      }
    } else if (candidate) {
      await pc.addIceCandidate(candidate);
    }
  } catch (err) {
    console.error(err);
  }
};

Tout d'abord, Alice et Bob échangent des informations sur le réseau. (L'expression rechercher des candidats fait référence au processus de recherche d'interfaces réseau et de ports à l'aide du framework ICE.)

  1. Alice crée un objet RTCPeerConnection avec un gestionnaire onicecandidate, qui s'exécute lorsque des candidats au réseau deviennent disponibles.
  2. Alice envoie des données de candidats sérialisées à Bob via le canal de signal qu'il utilise, tel que WebSocket ou un autre mécanisme.
  3. Lorsque Bob reçoit un message de candidat d'Alice, il appelle addIceCandidate pour ajouter le candidat à la description du pair distant.

Les clients WebRTC (également appelés pairs, ou Alice et Bob dans cet exemple) doivent également vérifier et échanger des informations sur les médias audio et vidéo locaux et distants, telles que les capacités de résolution et de codec. Signal pour échanger des informations de configuration multimédia en échangeant une offre et une réponse à l'aide du protocole de description de session (SDP):

  1. Alice exécute la méthode createOffer() RTCPeerConnection. Le résultat est transmis à un RTCSessionDescription (description de la session locale d'Alice).
  2. Dans le rappel, Alice définit la description locale à l'aide de setLocalDescription(), puis envoie cette description de session à Bob via son canal de signalement. Notez que RTCPeerConnection ne commencera à rassembler des candidats qu'après l'appel de setLocalDescription(). Ce point est codifié dans l'ébauche JSEP IETF.
  3. Bob définit la description qu'Alice lui a envoyée en tant que description distante à l'aide de setRemoteDescription().
  4. Bob exécute la méthode RTCPeerConnection createAnswer(), en lui transmettant la description à distance qu'il a obtenue auprès d'Alice afin qu'une session locale compatible avec la sienne puisse être générée. Le rappel createAnswer() reçoit un RTCSessionDescription. Bob définit cette description comme description locale et l'envoie à Alice.
  5. Lorsque Alice obtient la description de session de Bob, elle la définit comme description à distance avec setRemoteDescription.
  6. Ping!

Les objets RTCSessionDescription sont des blobs conformes au Session Description Protocol (SDP). Sérialisé, un objet SDP ressemble à ceci:

v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126

// ...

a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810

L'acquisition et l'échange d'informations sur le réseau et les médias peuvent être effectués simultanément, mais les deux processus doivent être terminés avant que la diffusion audio et vidéo entre pairs puisse commencer.

L'architecture offre/réponse décrite précédemment est appelée JavaScript Session Establishment Protocol, ou JSEP. Vous trouverez une excellente animation expliquant le processus de signalement et de diffusion dans la vidéo de démonstration d'Ericsson pour sa première implémentation WebRTC.

Schéma de l&#39;architecture JSEP
Architecture JSEP

Une fois le processus de signalement terminé, les données peuvent être diffusées directement peer-to-peer, entre l'appelant et l'appelant ou, en cas d'échec, via un serveur relais intermédiaire (nous y reviendrons plus tard). Le traitement par flux est la tâche de RTCPeerConnection.

RTCPeerConnection

RTCPeerConnection est le composant WebRTC qui gère une communication stable et efficace de flux de données entre les pairs.

Voici un schéma d'architecture WebRTC montrant le rôle de RTCPeerConnection. Comme vous le remarquerez, les parties vertes sont complexes !

Schéma de l&#39;architecture WebRTC
Architecture WebGLC (disponible sur webrtc.org)

D'un point de vue JavaScript, la principale chose à comprendre dans ce schéma est que RTCPeerConnection protège les développeurs Web des myriades de complexités qui se cachent en dessous. Les codecs et protocoles utilisés par WebRTC effectuent une tâche considérable pour rendre la communication en temps réel possible, même sur des réseaux peu fiables:

  • Dissimulation de la perte de paquets
  • Annulation de l'écho
  • Adaptabilité de la bande passante
  • Mise en mémoire tampon dynamique de la gigue
  • Contrôle automatique du gain
  • Réduction et suppression du bruit
  • Nettoyage d'images

Le code W3C précédent présente un exemple simplifié de WebRTC du point de vue de la signalisation. Voici des tutoriels sur deux applications WebRTC fonctionnelles. Le premier est un exemple simple illustrant RTCPeerConnection, et le second est un client de chat vidéo entièrement opérationnel.

RTCPeerConnection sans serveurs

Le code suivant provient des exemples WebRTC de connexion de pairs, qui comporte des RTCPeerConnection locaux et distants (ainsi que des vidéos locales et distantes) sur une même page Web. Cela ne constitue rien de très utile (l'appelant et l'appelé se trouvent sur la même page), mais cela rend le fonctionnement de l'API RTCPeerConnection un peu plus clair, car les objets RTCPeerConnection de la page peuvent échanger des données et des messages directement sans avoir à utiliser de mécanismes de signalement intermédiaires.

Dans cet exemple, pc1 représente le pair local (appelant) et pc2 le pair distant (appelé).

Appelant

  1. Créez un RTCPeerConnection et ajoutez le flux à partir de getUserMedia() : ```js // Servers est un fichier de configuration facultatif. (Voir la discussion sur TURN et STUN plus loin.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEvery((track) => { pc1.addTrack(track, localStream); });
  1. Créez une offre et définissez-la comme description locale pour pc1 et comme description à distance pour pc2. Cette opération peut être effectuée directement dans le code sans utiliser le signalement, car l'appelant et l'appelé se trouvent sur la même page : js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );

Callée

  1. Créez pc2 et, lorsque le flux de pc1 est ajouté, affichez-le dans un élément vidéo : js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }

API RTCPeerConnection et serveurs

En situation réelle, WebRTC a besoin de serveurs, même si la simplicité est de plus en plus simple. Voici ce qui peut se produire:

  • Les utilisateurs se découvrent et échangent des informations du monde réel, comme des noms.
  • Les applications clientes WebRTC (appairages) échangent des informations réseau.
  • Les pairs échangent des données sur les médias, telles que le format et la résolution vidéo.
  • Les applications clientes WebRTC traversent les passerelles NAT et les pare-feu.

En d'autres termes, WebRTC a besoin de quatre types de fonctionnalités côté serveur:

  • Découverte et communication avec les utilisateurs
  • Serveur de signalement
  • Traversée NAT/pare-feu
  • Serveurs relais en cas d'échec de la communication peer-to-peer

La traversée NAT, la mise en réseau peer-to-peer et les exigences liées à la création d'une application de serveur pour la découverte et le signalement des utilisateurs dépassent le cadre de cet article. Il suffit d'indiquer que le protocole STUN et son extension TURN sont utilisés par le framework ICE pour permettre à RTCPeerConnection de gérer la traversée NAT et d'autres aléas du réseau.

ICE est un framework permettant de mettre en relation des pairs, par exemple deux clients de chat vidéo. Dans un premier temps, ICE tente de connecter directement les pairs avec la latence la plus faible possible via UDP. Dans ce processus, les serveurs STUN n'ont qu'une seule tâche: permettre à un pair protégé par une NAT d'obtenir son adresse publique et son port. Pour en savoir plus sur STUN et TURN, consultez Créer les services de backend nécessaires à une application WebRTC.

Rechercher des candidats à une connexion
Rechercher des candidats à une connexion

En cas d'échec du protocole UDP, ICE essaie TCP. En cas d'échec de la connexion directe, notamment en raison de la traversée NAT et des pare-feu de l'entreprise, ICE utilise un serveur TURN intermédiaire (relais). En d'autres termes, ICE utilise d'abord STUN avec UDP pour connecter directement les pairs et, en cas d'échec, se rabat sur un serveur de relais TURN. L'expression recherche de candidats fait référence au processus de recherche d'interfaces réseau et de ports.

Parcours de données WebRTC
Parcours de données WebRTC

Justin Uberti, ingénieur WebRTC, donne plus d'informations sur ICE, STUN et TURN dans la présentation WebRTC Google I/O 2013. (Les diapositives de présentation donnent des exemples d'implémentations de serveurs TURN et STUN.)

Un client de chat vidéo simple

La démonstration du chat vidéo disponible à l'adresse appr.tc est idéale pour essayer WebRTC, avec signalisation et traversée NAT/pare-feu à l'aide d'un serveur STUN. Cette appli utilise adapter.js, un shim qui isole les applis des modifications de spécifications et des différences de préfixes.

Le code est délibérément détaillé dans sa journalisation. Consultez la console pour comprendre l'ordre des événements. Voici un tutoriel détaillé du code.

Topologies de réseaux

WebRTC, tel qu'il est actuellement implémenté, n'accepte que la communication un à un, mais il peut être utilisé dans des scénarios réseau plus complexes, par exemple avec plusieurs pairs communiquant chacun entre eux directement ou via un MCU (Multipoint Control Unit), un serveur capable de gérer un grand nombre de participants et de transférer le flux de façon sélective, et de mixer ou enregistrer des contenus audio et vidéo.

Schéma de la topologie de l&#39;unité de contrôle multipoint
Exemple de topologie d'unité de contrôle multipoint

De nombreuses applications WebRTC existantes ne communiquent qu'entre les navigateurs Web. Toutefois, les serveurs de passerelle peuvent permettre à une application WebRTC exécutée sur un navigateur d'interagir avec des appareils tels que les téléphones (également appelés RTCP) et avec des systèmes VOIP. En mai 2012, Doubango Telecom a publié en Open Source le client SIP sipml5, créé avec WebRTC et WebSocket, qui, entre autres, permettent des appels vidéo entre des navigateurs et des applications fonctionnant sur iOS et Android. Lors de la conférence Google I/O, Tethr et Tropo ont présenté un cadre pour les communications en cas de sinistre dans une mallette à l'aide d'une cellule OpenBTS pour permettre la communication entre les feature phones et les ordinateurs via WebRTC. Communication téléphonique sans opérateur !

Démonstration Tethr/Tropo lors de la conférence Google I/O 2012
Tethr/Tropo: les communications en cas de sinistre en mallette

API RTCDataChannel

En plus de l'audio et de la vidéo, WebRTC accepte la communication en temps réel pour d'autres types de données.

L'API RTCDataChannel permet l'échange de données arbitraires peer-to-peer avec une faible latence et un débit élevé. Pour les démonstrations sur une seule page et pour apprendre à créer une application de transfert de fichiers simple, consultez les exemples WebRTC et l'atelier de programmation WebRTC, respectivement.

L'API peut être utilisée dans de nombreux cas, par exemple:

  • Jeux vidéo
  • Applications de bureau à distance
  • Chat textuel en temps réel
  • Transfert de fichiers
  • Réseaux décentralisés

L'API offre plusieurs fonctionnalités pour tirer le meilleur parti de RTCPeerConnection et permettre une communication peer-to-peer performante et flexible:

  • Tirer parti de la configuration de la session RTCPeerConnection
  • Plusieurs canaux simultanés avec priorisation
  • Sémantique de distribution fiable et peu fiable
  • Sécurité intégrée (DTLS) et contrôle de l'encombrement
  • Possibilité d'utiliser l'audio ou la vidéo avec ou sans audio

La syntaxe est délibérément semblable à WebSocket avec une méthode send() et un événement message:

const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
  localConnection.createDataChannel('sendDataChannel');

// ...

remoteConnection.ondatachannel = (event) => {
  receiveChannel = event.channel;
  receiveChannel.onmessage = onReceiveMessage;
  receiveChannel.onopen = onReceiveChannelStateChange;
  receiveChannel.onclose = onReceiveChannelStateChange;
};

function onReceiveMessage(event) {
  document.querySelector("textarea#send").value = event.data;
}

document.querySelector("button#send").onclick = () => {
  var data = document.querySelector("textarea#send").value;
  sendChannel.send(data);
};

La communication s'effectue directement entre les navigateurs. Par conséquent, RTCDataChannel peut être beaucoup plus rapide que WebSocket, même si un serveur de relais (TURN) est requis en cas d'échec du trou qui fait face aux pare-feu et aux NAT.

RTCDataChannel est disponible dans Chrome, Safari, Firefox, Opera et Samsung Internet. Le jeu Cube Slam utilise l'API pour communiquer son état. Jouez avec un ami ou l'ours ! La plate-forme innovante Sharefest a permis de partager des fichiers via RTCDataChannel et peerCDN. Elle offrait un aperçu de la façon dont WebRTC pouvait permettre la distribution de contenus peer-to-peer.

Pour en savoir plus sur RTCDataChannel, consultez le brouillon de spécifications de protocole de l'IETF.

Sécurité

Une application ou un plug-in de communication en temps réel peut compromettre la sécurité de plusieurs façons. Exemple :

  • Les données ou contenus multimédias non chiffrés peuvent être interceptés entre des navigateurs, ou entre un navigateur et un serveur.
  • Une application peut enregistrer et diffuser du contenu vidéo ou audio à l'insu de l'utilisateur.
  • Des logiciels malveillants ou des virus peuvent être installés parallèlement à une application ou un plug-in apparemment inoffensifs.

WebRTC propose plusieurs fonctionnalités pour éviter ces problèmes:

  • Les implémentations WebRTC utilisent des protocoles sécurisés, tels que DTLS et SRTP.
  • Le chiffrement est obligatoire pour tous les composants WebRTC, y compris les mécanismes de signalement.
  • WebRTC n'est pas un plug-in. Ses composants s'exécutent dans le bac à sable du navigateur et non dans un processus distinct. Les composants ne nécessitent pas d'installation séparée et sont mis à jour en même temps que le navigateur.
  • L'accès à la caméra et au micro doit être explicitement accordé. Lorsque l'appareil photo ou le micro est en cours d'exécution, cela est clairement indiqué par l'interface utilisateur.

Cet article ne traite pas de la sécurité des contenus multimédias en streaming. Pour en savoir plus, consultez la proposition d'architecture de sécurité WebRTC proposée par l'IETF.

En conclusion

Les API et les normes de WebRTC peuvent démocratiser et décentraliser les outils de création de contenu et de communication, y compris la téléphonie, les jeux vidéo, la production vidéo, la création de musique et la collecte d'actualités.

La technologie n'est pas plus perturbante que cela.

Comme l'a dit le blogueur Phil Edholm, "éventuellement, WebRTC et HTML5 pourraient permettre la même transformation de la communication en temps réel que le navigateur d'origine pour l'information".

Outils pour les développeurs

En savoir plus

Normes et protocoles

Récapitulatif de la compatibilité avec WebRTC

API MediaStream et getUserMedia

  • Chrome pour ordinateur 18.0.1008 ou version ultérieure ; Chrome pour Android 29 ou version ultérieure
  • Opera 18 ou version ultérieure ; Opera pour Android 20 ou version ultérieure
  • Opera 12, Opera Mobile 12 (sur la base du moteur Presto)
  • Firefox 17 ou version ultérieure
  • Microsoft Edge 16 ou version ultérieure
  • Safari 11.2 ou version ultérieure sur iOS, et version 11.1 ou ultérieure sous macOS
  • UC 11.8 ou version ultérieure sur Android
  • Samsung Internet 4 ou version ultérieure

API RTCPeerConnection

  • Chrome pour ordinateur 20 ou version ultérieure ; Chrome pour Android 29 ou version ultérieure (sans indicateur)
  • Opera 18 ou version ultérieure (activé par défaut) ; Opera pour Android 20 ou version ultérieure (activé par défaut)
  • Firefox 22 ou version ultérieure (activé par défaut)
  • Microsoft Edge 16 ou version ultérieure
  • Safari 11.2 ou version ultérieure sur iOS, et version 11.1 ou ultérieure sous macOS
  • Samsung Internet 4 ou version ultérieure

API RTCDataChannel

  • Version expérimentale dans Chrome 25, mais plus stable (et avec l'interopérabilité Firefox) dans Chrome 26 et versions ultérieures ; Chrome pour Android 29 et versions ultérieures
  • Version stable (et interopérabilité avec Firefox) sous Opera 18 ou version ultérieure ; Opera pour Android 20 ou version ultérieure
  • Firefox 22 ou version ultérieure (activé par défaut)

Pour en savoir plus sur la compatibilité multiplate-forme des API telles que getUserMedia et RTCPeerConnection, consultez caniuse.com et Chrome Platform Status.

Les API natives pour RTCPeerConnection sont également disponibles dans la documentation sur webrtc.org.