Premiers pas avec WebRTC

WebRTC est un nouveau front dans la longue guerre pour un Web ouvert et sans entraves.

Brendan Eich, inventeur de JavaScript

Communication en temps réel sans plug-in

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

Pour essayer, WebRTC est disponible sur ordinateur et mobile dans Google Chrome, Safari, Firefox et Opera. Commencez par l'application de chat vidéo simple sur appr.tc:

  1. Ouvrez appr.tc dans votre navigateur.
  2. Cliquez sur Rejoindre pour rejoindre une salle de chat et autorisez l'application à 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.

Démarrage rapide

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

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

Un bref historique de WebRTC

L'un des derniers grands défis du Web est de permettre la communication humaine par le biais de la voix et de la vidéo: la communication en temps réel, ou RTC. La RTC doit être aussi naturelle dans une application Web que la saisie de texte dans une zone de saisie. Sans elle, vous ne pouvez pas innover et développer de nouvelles façons d'interagir avec les utilisateurs.

Historiquement, le RTC a été complexe et réservé aux entreprises, car il nécessitait de licencier ou de développer en interne des technologies audio et vidéo coûteuses. L'intégration de la technologie RTC aux contenus, données et services existants s'est avérée difficile et fastidieuse, en particulier sur le Web.

Le chat vidéo Gmail est devenu populaire en 2008. En 2011, Google a lancé Hangouts, qui utilise Talk (comme Gmail). Google a racheté GIPS, une entreprise qui a développé de nombreux composants requis pour le RTC, tels que les codecs et les techniques d'annulation de l'écho. Google a rendu open source les technologies développées par GIPS et a collaboré avec les organismes de normalisation concernés de l'Internet Engineering Task Force (IETF) et du World Wide Web Consortium (W3C) pour obtenir un consensus au sein de l'industrie. En mai 2011, Ericsson a créé 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, sans plug-in. Le besoin était réel:

  • De nombreux services Web utilisaient le RTC, mais nécessitaient des téléchargements, des applications natives ou des plug-ins. Skype, Facebook et Hangouts en font partie.
  • Le téléchargement, l'installation et la mise à jour des plug-ins sont des opérations complexes, sujettes aux erreurs et pénibles.
  • Les plug-ins sont difficiles à déployer, à déboguer, à résoudre les problèmes, à tester et à gérer. Ils peuvent nécessiter l'obtention de licences et l'intégration à une technologie complexe et coûteuse. 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, normalisées, intégrées aux navigateurs Web et plus efficaces que les technologies existantes.

Où en sommes-nous ?

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

WebRTC implémente ces trois API : - 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 essayez les exemples incroyables 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 WebRTC Peer connection (Connexion entre pairs WebRTC) et appr.tc, respectivement. Cette application utilise adapter.js, un shim JavaScript géré par Google avec l'aide de la communauté WebRTC, pour masquer les différences entre les navigateurs et les modifications de spécifications.

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

L'atelier de programmation WebRTC explique 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 tâches:

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

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

  • MediaStream accède aux flux de données, par exemple à partir de la caméra et du micro de l'utilisateur.
  • RTCPeerConnection permet les appels audio ou vidéo avec des fonctionnalités de chiffrement et de gestion de la bande passante.
  • RTCDataChannel permet la communication de données génériques en pair à pair.

(Nous reviendrons plus tard sur les aspects réseau et de signalisation de WebRTC.)

API MediaStream (également appelée API getUserMedia)

L'API MediaStream représente des flux multimédias synchronisés. Par exemple, un flux provenant de l'entrée de la caméra et du micro comporte des pistes vidéo et audio 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 consiste probablement à l'examiner dans un cas concret:

  1. Dans votre navigateur, accédez à Exemples WebRTC getUserMedia.
  2. Ouvrez la console.
  3. Inspectez la variable stream, qui est de portée globale.

Chaque MediaStream possède une entrée, qui peut être un MediaStream généré 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 se résout en objet MediaStream.

Chaque MediaStream possède un label, tel que 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'. Un tableau de 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 d'audio) et, en supposant qu'une webcam fonctionnelle soit connectée, stream.getVideoTracks() renvoie un tableau d'un seul MediaStreamTrack représentant le flux de la webcam. Chaque MediaStreamTrack possède un type ('video' ou 'audio'), un label (par exemple, 'FaceTime HD Camera (Built-in)') et représente un ou plusieurs canaux audio ou vidéo. Dans ce cas, il n'y a qu'une seule piste vidéo et pas d'audio, mais il est facile d'imaginer des cas d'utilisation où il y en a plus, comme une application de chat qui reçoit des flux de la caméra avant, de la caméra arrière, du micro et d'une application qui partage son écran.

Vous pouvez associer un MediaStream à un élément vidéo en définissant l'attribut srcObject. Auparavant, cela se faisait en définissant l'attribut src sur une URL d'objet créée avec URL.createObjectURL(), mais cette méthode est obsolète.

getUserMedia peut également être utilisé en tant que 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 extensions basées sur Chromium peuvent également intégrer getUserMedia. Ajouter des autorisations audioCapture et/ou videoCapture au fichier manifeste permet de ne demander et d'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 infobar du navigateur. L'accès HTTP pour getUserMedia() a été abandonné par Chrome fin 2015, car il était classé comme fonctionnalité puissante.

L'objectif est potentiellement d'activer un MediaStream pour n'importe quelle source de données de streaming, et non seulement pour une caméra ou un micro. Cela permet de diffuser des données stockées ou des sources de données arbitraires, telles que des capteurs ou d'autres entrées.

getUserMedia() prend tout son sens en combinaison avec d'autres API et bibliothèques JavaScript:

  • Webcam Toy est une application de photomaton qui utilise WebGL pour ajouter des effets étranges et merveilleux aux photos, qui peuvent être partagées ou enregistrées localement.
  • FaceKat est un jeu de suivi du visage créé avec headtrackr.js.
  • La caméra ASCII utilise l'API Canvas pour générer des images ASCII.
Image ASCII générée par idevelop.ro/ascii-camera
gUM ASCII art!

Contraintes

Les contraintes peuvent être utilisées 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 prise de vue (caméra avant ou arrière), la fréquence d'images, la hauteur et la largeur, ainsi qu'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 DOMException ou une OverconstrainedError si, par exemple, la résolution demandée n'est pas disponible. Pour voir comment cela fonctionne, consultez Exemples WebRTC getUserMedia: sélectionner la résolution pour une démonstration.

Capture d'écran et d'onglet

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

Vous pouvez également utiliser la capture d'écran comme 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 que pour le développement, car elle est activée via un indicateur de ligne de commande, comme expliqué dans cet article.

Signalisation: contrôle de la session, informations sur le réseau et les médias

WebRTC utilise RTCPeerConnection pour communiquer des données de streaming 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. La signalisation ne fait pas partie de l'API RTCPeerConnection.

Au lieu de cela, les développeurs d'applications WebRTC peuvent choisir le protocole de messagerie de leur choix, comme SIP ou XMPP, et tout canal de communication duplex (à deux voies) approprié. L'exemple appr.tc utilise XHR et l'API Channel comme mécanisme de signalisation. L'atelier de programmation utilise Socket.io exécuté sur un serveur Node.

La signalisation permet d'échanger trois types d'informations:

  • Messages de contrôle de session: pour initialiser ou fermer la communication et signaler les erreurs.
  • Configuration réseau: quelle est l'adresse IP et le port de votre ordinateur pour le monde extérieur ?
  • 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 la signalisation doit être terminé avant que le streaming peer-to-peer puisse commencer.

Par exemple, imaginons qu'Alice souhaite communiquer avec Bob. Voici un exemple de code tiré de la spécification WebRTC du W3C, qui illustre le processus de signalisation en action. Le code suppose l'existence d'un mécanisme de signalisation créé dans la méthode createSignalingChannel(). Notez également que, sur 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 réseau. (L'expression trouver 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 de réseau deviennent disponibles.
  2. Alice envoie des données candidates sérialisées à Bob via le canal de signalisation qu'elle utilise, tel que WebSocket ou un autre mécanisme.
  3. Lorsque Bob reçoit un message 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 déterminer et échanger des informations multimédias audio et vidéo locales et distantes, telles que la résolution et les fonctionnalités de codec. La signalisation pour échanger des informations de configuration multimédia se fait en échangeant une offre et une réponse à l'aide du protocole SDP (Session Description Protocol):

  1. Alice exécute la méthode createOffer() de RTCPeerConnection. Le résultat est transmis à un RTCSessionDescription, la 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 signalisation. Notez que RTCPeerConnection ne commencera à collecter des candidats que lorsque setLocalDescription() sera appelé. Cela est codifié dans le brouillon de l'IETF sur le JSEP.
  3. Bob définit la description qu'Alice lui a envoyée comme description distante à l'aide de setRemoteDescription().
  4. Bob exécute la méthode createAnswer() RTCPeerConnection, en lui transmettant la description distante qu'il a reçue 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 cela comme description locale et l'envoie à Alice.
  5. Lorsque Alice reçoit la description de la session de Bob, elle la définit comme description distante avec setRemoteDescription.
  6. Ping !

Les objets RTCSessionDescription sont des blobs conformes au protocole SDP (Session Description Protocol). Sérialisé, un objet SDP se présente comme suit:

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 réseau et multimédias peuvent être effectués simultanément, mais les deux processus doivent être terminés avant que le streaming audio et vidéo entre pairs puisse commencer.

L'architecture d'offre/réponse décrite précédemment est appelée JavaScript Session Establishment Protocol (JSEP). (Une excellente animation explique le processus de signalisation et de streaming 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 signalisation terminé, les données peuvent être diffusées directement en pair à pair, entre l'appelant et l'appelé, ou, en cas d'échec, via un serveur de relais intermédiaire (nous y reviendrons plus tard). Le streaming est la tâche de RTCPeerConnection.

RTCPeerConnection

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

Vous trouverez ci-dessous un schéma d'architecture WebRTC illustrant le rôle de RTCPeerConnection. Comme vous le remarquerez, les parties vertes sont complexes.

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

Du point de vue JavaScript, l'essentiel à retenir de ce diagramme est que RTCPeerConnection protège les développeurs Web de la myriade de complexités qui se cachent en dessous. Les codecs et les protocoles utilisés par WebRTC effectuent un travail considérable pour permettre la communication en temps réel, même sur des réseaux peu fiables:

  • Masquage 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 des images

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

RTCPeerConnection sans serveur

Le code suivant est extrait de l'exemple de connexion entre pairs WebRTC, qui comporte des RTCPeerConnection locaux et distants (et des vidéos locales et distantes) sur une même page Web. Cela n'a rien de très utile (l'appelant et le destinataire se trouvent sur la même page), mais cela clarifie le fonctionnement de l'API RTCPeerConnection, car les objets RTCPeerConnection de la page peuvent échanger des données et des messages directement sans avoir à utiliser de mécanismes de signalisation intermédiaires.

Dans cet exemple, pc1 représente l'homologue local (appelant) et pc2 l'homologue distant (destinataire).

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().forEach((track) => { pc1.addTrack(track, localStream); });
  1. Créez une offre et définissez-la comme description locale pour pc1 et comme description distante pour pc2. Cela peut être fait directement dans le code sans utiliser de signalisation, car l'appelant et le destinataire 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 );

Appelé

  1. Créez pc2 et, lorsque la diffusion de pc1 est ajoutée, affichez-la 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

Dans la pratique, WebRTC a besoin de serveurs, même simples. Il peut donc se produire ce qui suit:

  • Les utilisateurs se découvrent et échangent des informations réelles, comme des noms.
  • Les applications clientes WebRTC (pairs) échangent des informations réseau.
  • Les pairs échangent des données sur les contenus multimédias, comme 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 des utilisateurs
  • Serveur de signalement
  • Traversée NAT/pare-feu
  • Serveurs de relais en cas d'échec de la communication peer-to-peer

Le contournement NAT, le réseau peer-to-peer et les exigences pour créer une application serveur de découverte et de signalisation des utilisateurs dépassent le cadre de cet article. Il suffit de dire que le protocole STUN et son extension, TURN, sont utilisés par le framework ICE pour permettre à RTCPeerConnection de gérer le balayage NAT et d'autres aléas réseau.

ICE est un framework permettant de connecter des pairs, tels que deux clients de chat vidéo. Au départ, ICE tente de connecter les pairs directement avec la latence la plus faible possible via UDP. Dans ce processus, les serveurs STUN ont une seule tâche: permettre à un pair derrière un NAT de connaître son adresse et son port publics. (Pour en savoir plus sur STUN et TURN, consultez Créer les services backend nécessaires à une application WebRTC.)

Trouver des candidats à la connexion
Rechercher des connexions potentielles

Si UDP échoue, ICE tente d'utiliser TCP. Si la connexion directe échoue, en particulier en raison du NAT traversal et des pare-feu d'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, utilise un serveur de relais TURN. L'expression trouver des 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

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

Un client de chat vidéo simple

La démonstration de chat vidéo sur appr.tc est un bon moyen d'essayer WebRTC, avec la signalisation et le balayage NAT/pare-feu à l'aide d'un serveur STUN. Cette application utilise adapter.js, un shim qui protège les applications des modifications de spécifications et des différences de préfixes.

Le code est délibérément verbeux dans sa journalisation. Consultez la console pour comprendre l'ordre des événements. Vous trouverez ci-dessous une procédure détaillée du code.

Topologies de réseaux

WebRTC, tel qu'il est actuellement implémenté, ne prend en charge que la communication individuelle, mais peut être utilisé dans des scénarios réseau plus complexes, par exemple avec plusieurs pairs communiquant entre eux directement ou via un Multipoint Control Unit (MCU), un serveur capable de gérer un grand nombre de participants et d'effectuer un transfert sélectif de flux, ainsi que de mixer ou d'enregistrer des contenus audio et vidéo.

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

De nombreuses applications WebRTC existantes ne montrent que la communication entre les navigateurs Web, mais 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 RNIS) et les systèmes VOIP. En mai 2012, Doubango Telecom a rendu Open Source le client SIP sipml5 créé avec WebRTC et WebSocket, qui permet (entre autres utilisations potentielles) de passer des appels vidéo entre les navigateurs et les applications exécutées sur iOS et Android. Lors de Google I/O, Tethr et Tropo ont présenté un framework de communications en cas de catastrophe dans une mallette à l'aide d'une cellule OpenBTS pour permettre les communications entre les téléphones standards et les ordinateurs via WebRTC. Communication téléphonique sans opérateur

Démo de Tethr/Tropo lors de la conférence Google I/O 2012
Tethr/Tropo: communications de crise dans une mallette

API RTCDataChannel<

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

L'API RTCDataChannel permet d'échanger des données arbitraires en pair à pair avec une faible latence et un débit élevé. Pour obtenir des démonstrations sur une seule page et découvrir comment créer une application de transfert de fichiers simple, consultez les exemples WebRTC et l'atelier de programmation WebRTC, respectivement.

L'API présente de nombreux cas d'utilisation potentiels, y compris les suivants:

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

L'API dispose de plusieurs fonctionnalités pour exploiter pleinement RTCPeerConnection et permettre une communication peer-to-peer puissante et flexible:

  • Utilisation de la configuration de la session RTCPeerConnection
  • Plusieurs canaux simultanés avec hiérarchisation
  • Sémantique de diffusion fiable et non fiable
  • Sécurité intégrée (DTLS) et contrôle de la congestion
  • Possibilité d'utiliser les filtres avec ou sans audio ou vidéo

La syntaxe est délibérément semblable à celle de 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. RTCDataChannel peut donc être beaucoup plus rapide que WebSocket, même si un serveur de relais (TURN) est requis lorsque le perçage de trous pour faire face aux pare-feu et aux NAT échoue.

RTCDataChannel est disponible dans Chrome, Safari, Firefox, Opera et Samsung Internet. Le jeu Cube Slam utilise l'API pour communiquer l'état du jeu. Jouez le rôle d'un ami ou de l'ours. La plate-forme innovante Sharefest a permis le partage de fichiers via RTCDataChannel, et peerCDN a donné un aperçu de la façon dont WebRTC pourrait permettre la distribution de contenu en pair à pair.

Pour en savoir plus sur RTCDataChannel, consultez la spécification de protocole provisoire de l'IETF.

Sécurité

Un plug-in ou une application 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 les navigateurs ou entre un navigateur et un serveur.
  • Une application peut enregistrer et distribuer des vidéos ou des contenus audio à l'insu de l'utilisateur.
  • Des logiciels malveillants ou des virus peuvent être installés avec un plug-in ou une application apparemment inoffensifs.

WebRTC dispose de 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 signalisation.
  • 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 distincte et sont mis à jour chaque fois que le navigateur est mis à jour.
  • L'accès à l'appareil photo et au micro doit être accordé de manière explicite. Lorsque l'appareil photo ou le micro sont en cours d'exécution, l'interface utilisateur l'indique clairement.

Cet article ne traite pas de la sécurité des contenus multimédias en streaming. Pour en savoir plus, consultez l'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 et de communication de contenus, y compris la téléphonie, les jeux, la production vidéo, la création musicale et la collecte d'actualités.

La technologie n'a jamais été aussi révolutionnaire.

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

Outils pour les développeurs

En savoir plus

Normes et protocoles

Résumé 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 (basé sur le 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 11.1 ou version ultérieure sur 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 11.1 ou version ultérieure sur MacOS
  • Samsung Internet 4 ou version ultérieure

API RTCDataChannel

  • Version expérimentale dans Chrome 25, mais plus stable (et avec interopérabilité avec Firefox) dans Chrome 26 et versions ultérieures, Chrome pour Android 29 et versions ultérieures
  • Version stable (et avec interopérabilité avec Firefox) dans Opera 18 et versions ultérieures, Opera pour Android 20 et versions ultérieures
  • 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 État de la plate-forme Chrome.

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