WebRTC es un nuevo frente en la larga guerra para una Web abierta y sin obstrucciones.
Brendan Eich, inventor de JavaScript
Comunicación en tiempo real sin complementos
Imagina un mundo en el que tu teléfono, TV y computadora puedan comunicarse en una plataforma común. Imagina que a tu aplicación web le resultó fácil agregar videochat y compartir datos entre pares. Esa es la visión de WebRTC.
¿Quieres probarlo? WebRTC está disponible para computadoras y dispositivos móviles en Google Chrome, Safari, Firefox y Opera. Un buen punto de partida es la app de videochat simple en appr.tc:
- Abre appr.tc en el navegador.
- Haz clic en Unirse para unirte a una sala de chat y permitir que la app use tu cámara web.
- Abre la URL que se muestra al final de la página en una pestaña nueva o, mejor aún, en otra computadora.
Inicio rápido
¿No tienes tiempo para leer este artículo o solo quieres código?
- Para obtener una descripción general de WebRTC, mira el siguiente video de Google I/O o estas diapositivas:
- Si no usaste la API de
getUserMedia
, consulta Cómo capturar audio y video en HTML5 y simpl.info getUserMedia. - Para obtener más información sobre la API de
RTCPeerConnection
, consulta el siguiente ejemplo y "simpl.info RTCPeerConnection". - Si deseas obtener información sobre cómo WebRTC usa los servidores para la señalización y el firewall y el recorrido de NAT, consulta el código y los registros de la consola de appr.tc.
- ¿No puedo esperar y solo quiero probar WebRTC ahora? Prueba algunas de las más de 20 demostraciones que ejercitan las APIs de JavaScript de WebRTC.
- ¿Tienes problemas con la máquina y con WebRTC? Visita el Solucionador de problemas de WebRTC.
Como alternativa, puedes ir directamente al codelab de WebRTC, una guía paso a paso en la que se explica cómo compilar una app de videochat completa, incluido un servidor de señalización simple.
Una muy breve historia de WebRTC
Uno de los últimos desafíos importantes para la Web es permitir la comunicación humana a través de voz y video: comunicación en tiempo real o RTC. La RTC debe ser tan natural en una aplicación web como ingresar texto en una entrada de texto. Sin ella, tu capacidad para innovar y desarrollar nuevas formas de interacción será limitada.
Históricamente, la RTC ha sido corporativa y compleja, y requiere que las tecnologías de audio y video costosas se obtengan con licencia o se desarrollen internamente. La integración de la tecnología de RTC con el contenido, los datos y los servicios existentes ha sido difícil y requiere mucho tiempo, especialmente en la Web.
El chat de video de Gmail se hizo popular en 2008 y, en 2011, Google presentó Hangouts, que utiliza Talk (al igual que Gmail). Google compró GIPS, una empresa que desarrolló muchos componentes necesarios para la RTC, como códecs y técnicas de cancelación del eco. Google creó la tecnología de código abierto que desarrolló el GIPS y se asoció con los organismos de estándares relevantes del Internet Engineering Task Force (IETF) y World Wide Web Consortium (W3C) para garantizar el consenso de la industria. En mayo de 2011, Ericsson compiló la primera implementación de WebRTC.
WebRTC implementó estándares abiertos para comunicación de datos, audio y video en tiempo real y sin complementos. La necesidad era real:
- Muchos servicios web utilizaban la RTC, pero necesitaban descargas, aplicaciones nativas o complementos. Estas incluyen Skype, Facebook y Hangouts.
- Descargar, instalar y actualizar complementos es un proceso complejo, propenso a errores y molesto.
- Los complementos son difíciles de implementar, depurar, solucionar problemas, probar y mantener, y pueden requerir licencias e integración en tecnología compleja y costosa. Por lo general, es difícil persuadir a las personas para que instalen complementos.
Los principios rectores del proyecto WebRTC son que sus APIs deben ser de código abierto, gratuitas, estandarizadas, integradas en navegadores web y más eficientes que las tecnologías existentes.
¿Dónde estamos ahora?
WebRTC se usa en varias apps, como Google Meet. WebRTC también se integró con las aplicaciones nativas de WebKitGTK+ y Qt.
WebRTC implementa estas tres APIs:
- MediaStream
(también conocido como getUserMedia
)
- RTCPeerConnection
- RTCDataChannel
Las APIs se definen en estas dos especificaciones:
Las tres APIs son compatibles con dispositivos móviles y computadoras de escritorio con Chrome, Safari, Firefox, Edge y Opera.
getUserMedia
: Para ver demostraciones y código, consulta las muestras de WebRTC o prueba los asombrosas ejemplos de Chris Wilson que usan getUserMedia
como entrada para audio web.
RTCPeerConnection
: Para ver una demostración sencilla y una app de videochat completamente funcional, consulta Muestras de WebRTC Peer connection y appr.tc, respectivamente. Esta app usa adapter.js, una corrección de compatibilidad de JavaScript que mantiene Google con la ayuda de la comunidad de WebRTC, para abstraer las diferencias en el navegador y los cambios de especificaciones.
RTCDataChannel
: Si quieres ver esto en acción, consulta las muestras de WebRTC para probar una de las demostraciones de canales de datos.
En el codelab de WebRTC, se muestra cómo usar las tres APIs para compilar una app simple de videochat y uso compartido de archivos.
Tu primer WebRTC
Las apps de WebRTC deben realizar varias acciones:
- Reproduce audio, video y otros datos.
- Obtén información de la red, como direcciones IP y puertos, y, luego, intercámbiala con otros clientes de WebRTC (conocidos como intercambios de tráfico) para habilitar la conexión, incluso mediante NAT y firewalls.
- Coordinar la comunicación de señalización para informar errores e iniciar o cerrar sesiones
- Intercambia información sobre el contenido multimedia y la capacidad del cliente, como la resolución y los códecs.
- Comunicar transmisiones de audio, video o datos.
Para adquirir y comunicar datos de transmisión, WebRTC implementa las siguientes APIs:
MediaStream
obtiene acceso a los flujos de datos, como los de la cámara y el micrófono del usuario.RTCPeerConnection
habilita las llamadas de audio o video con recursos para la encriptación y la administración del ancho de banda.RTCDataChannel
permite la comunicación entre pares de datos genéricos.
(Más adelante, se analizará en detalle la red y se indicarán los aspectos de WebRTC).
API de MediaStream
(también conocida como API de getUserMedia
)
La API de MediaStream
representa transmisiones de contenido multimedia sincronizadas. Por ejemplo, una transmisión tomada de la entrada de la cámara y el micrófono tiene pistas de video y audio sincronizadas. (No confundas MediaStreamTrack
con el elemento <track>
, que es algo completamente diferente).
Probablemente, la forma más fácil de comprender la API de MediaStream
sea mirarla en un entorno real:
- En el navegador, ve a Muestras de WebRTC
getUserMedia
. - Abre la consola.
- Inspecciona la variable
stream
, que se encuentra en permiso global.
Cada MediaStream
tiene una entrada, que puede ser un MediaStream
generado por getUserMedia()
, y una salida, que puede pasarse a un elemento de video o a un RTCPeerConnection
.
El método getUserMedia()
toma un parámetro de objeto MediaStreamConstraints
y muestra un Promise
que se resuelve en un objeto MediaStream
.
Cada MediaStream
tiene un label
, como 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. Los métodos getAudioTracks()
y getVideoTracks()
muestran un array de MediaStreamTrack
.
Para el ejemplo de getUserMedia
, stream.getAudioTracks()
muestra un array vacío (porque no hay audio) y, si está conectada una cámara web que funciona, stream.getVideoTracks()
muestra un array de un MediaStreamTrack
que representa la transmisión de la cámara web. Cada MediaStreamTrack
tiene un tipo ('video'
o 'audio'
), un label
(similar a 'FaceTime HD Camera (Built-in)'
) y representa uno o más canales de audio o video. En este caso, solo hay una pista de video y no hay audio, pero es fácil imaginar casos de uso en los que hay más, como una app de chat que recibe transmisiones desde la cámara frontal, la cámara posterior, el micrófono y una app que comparte su pantalla.
Se puede adjuntar un MediaStream
a un elemento de video si se configura el atributo srcObject
. Anteriormente, esto se hacía mediante la configuración del atributo src
en una URL de objeto creada con URL.createObjectURL()
, pero quedó obsoleto.
getUserMedia
también se puede usar como nodo de entrada para la API de 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);
});
Las apps y extensiones basadas en Chromium también pueden incorporar getUserMedia
. Si agregas los permisos audioCapture
o videoCapture
al manifiesto, podrás solicitar y otorgar el permiso solo una vez durante la instalación. Posteriormente, no se solicita permiso al usuario para acceder a la cámara o al micrófono.
Solo se debe otorgar permiso una vez para getUserMedia()
. La primera vez, se muestra el botón Permitir en la barra de información del navegador. Chrome dio de baja el acceso HTTP para getUserMedia()
a fines del 2015 porque se clasificó como una función potente.
La intención es habilitar un MediaStream
para cualquier fuente de datos de transmisión, no solo para una cámara o un micrófono. Esto permitiría la transmisión de datos almacenados o fuentes de datos arbitrarias, como sensores y otras entradas.
getUserMedia()
realmente cobra vida en combinación con otras APIs y bibliotecas de JavaScript:
- Webcam Toy es una app de cabina de fotos que usa WebGL para agregar efectos extraños y maravillosos a las fotos que se pueden compartir o guardar de forma local.
- FaceKat es un juego de seguimiento de rostros creado con headtrackr.js.
- La cámara ASCII usa la API de Canvas para generar imágenes ASCII.
Limitaciones
Se pueden usar restricciones para establecer valores de resolución de video para getUserMedia()
. Esto también permite compatibilidad con otras restricciones, como la relación de aspecto. modo orientado (frontal o trasera); velocidad de fotogramas, alto y ancho; y un método applyConstraints()
.
Para ver un ejemplo, consulta Muestras de WebRTC getUserMedia
: Selecciona la resolución.
Establecer un valor de restricción no permitido otorga una DOMException
o una OverconstrainedError
si, por ejemplo, la resolución solicitada no está disponible. Para ver esto en acción, consulta Muestras de WebRTC getUserMedia
: Selecciona la resolución para una demostración.
Captura de pantalla y de pestañas
Las apps de Chrome también permiten compartir un video en vivo de una sola pestaña del navegador o de todo el escritorio a través de las APIs de chrome.tabCapture
y chrome.desktopCapture
. (Para ver una demostración y obtener más información, consulta Cómo compartir pantalla con WebRTC. El artículo es de hace unos años, pero aún es interesante).
También es posible usar la captura de pantalla como una fuente MediaStream
en Chrome mediante la restricción chromeMediaSource
experimental. Ten en cuenta que la captura de pantalla requiere HTTPS y solo debe usarse para el desarrollo, ya que está habilitada a través de una marca de línea de comandos, como se explica en esta entrada.
Señalización: control de la sesión, información de la red y de los medios
WebRTC usa RTCPeerConnection
para comunicar datos de transmisión entre navegadores (también conocidos como pares), pero también necesita un mecanismo para coordinar la comunicación y enviar mensajes de control, un proceso conocido como señalización. WebRTC no especifica los métodos y protocolos de señalización. La señalización no forma parte de la API de RTCPeerConnection
.
En su lugar, los desarrolladores de apps de WebRTC pueden elegir el protocolo de mensajería que prefieran, como SIP o XMPP, y cualquier canal de comunicación dúplex (bidireccional) adecuado. El ejemplo appr.tc usa XHR y la API de canal como mecanismo de señalización. El codelab usa Socket.io que se ejecuta en un servidor de nodos.
La señalización se usa para intercambiar tres tipos de información:
- Mensajes de control de sesión: para inicializar o cerrar la comunicación, e informar errores.
- Configuración de red: Para el mundo exterior, ¿cuál es la dirección IP y el puerto de su computadora?
- Capacidades multimedia: ¿Qué códecs y resoluciones puede controlar tu navegador y el navegador con el que quiere comunicarse?
El intercambio de información a través de la señalización debe haberse completado correctamente antes de que pueda comenzar la transmisión entre pares.
Por ejemplo, imagina que Alicia quiere comunicarse con Roberto. Esta es una muestra de código de la especificación de W3C WebRTC, que muestra el proceso de señalización en acción. El código asume la existencia de algún mecanismo de señalización creado en el método createSignalingChannel()
. Además, ten en cuenta que, en Chrome y Opera, actualmente se usa el prefijo RTCPeerConnection
.
// 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);
}
};
Primero, Alicia y Roberto intercambian información de la red. (La expresión encuentra candidatos hace referencia al proceso de buscar interfaces y puertos de red con el framework de ICE).
- Alice crea un objeto
RTCPeerConnection
con un controladoronicecandidate
, que se ejecuta cuando los candidatos de red están disponibles. - Alice envía datos de candidatos serializados a Roberto a través de cualquier canal de señalización que esté usando, como WebSocket o algún otro mecanismo.
- Cuando Roberto recibe un mensaje candidato de Alice, llama a
addIceCandidate
para agregarlo a la descripción del par remoto.
Los clientes de WebRTC (también conocidos como pares, o Alicia y Roberto en este ejemplo) también deben determinar e intercambiar información de medios locales y remotos de audio y video, como las capacidades de resolución y códec. La señalización para intercambiar información de configuración de medios se realiza intercambiando una oferta y una respuesta mediante el Protocolo de descripción de sesión (SDP):
- Alice ejecuta el método
createOffer()
deRTCPeerConnection
. El resultado de esto recibe unaRTCSessionDescription
: descripción de la sesión local de Alice. - En la devolución de llamada, Alice establece la descripción local con
setLocalDescription()
y, luego, envía la descripción de esta sesión a Bob a través del canal de señalización. Ten en cuenta queRTCPeerConnection
no comenzará a recopilar candidatos hasta que se llame asetLocalDescription()
. Esto está codificado en el borrador de IETF de JSEP. - Roberto establece la descripción que Alicia le envió como descripción remota mediante
setRemoteDescription()
. - Roberto ejecuta el método
RTCPeerConnection
createAnswer()
y le pasa la descripción remota que obtuvo de Alice para que se pueda generar una sesión local compatible con la suya. La devolución de llamadacreateAnswer()
recibe unRTCSessionDescription
. Roberto establece eso como la descripción local y se la envía a Alice. - Cuando Alice obtiene la descripción de la sesión de Bob, la establece como la descripción remota con
setRemoteDescription
. - ¡Ping!
Los objetos RTCSessionDescription
son BLOB que cumplen con el Session Description Protocol (Protocolo de descripción de sesiones) SDP. En serializado, un objeto SDP se ve de la siguiente manera:
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
La adquisición y el intercambio de información de redes y medios pueden realizarse simultáneamente, pero ambos procesos deben haberse completado para poder comenzar la transmisión de audio y video entre pares.
La arquitectura de oferta/respuesta descrita anteriormente se denomina protocolo de establecimiento de sesiones de JavaScript o JSEP. (Hay una animación excelente en la que se explica el proceso de señalización y transmisión en el video de demostración de Ericsson para su primera implementación de WebRTC).
Una vez que el proceso de señalización se haya completado correctamente, los datos se pueden transmitir directamente entre pares (entre el emisor y el destinatario) o, si eso falla, a través de un servidor de retransmisión intermediario (más adelante hablaremos de este tema). La transmisión es el trabajo de RTCPeerConnection
.
RTCPeerConnection
RTCPeerConnection
es el componente de WebRTC que controla la comunicación estable y eficiente de datos de transmisión entre pares.
A continuación, se muestra un diagrama de arquitectura de WebRTC que muestra la función de RTCPeerConnection
. Como notarás, ¡las partes verdes son complejas!
Desde la perspectiva de JavaScript, lo más importante que se debe comprender en este diagrama es que RTCPeerConnection
protege a los desarrolladores web de las innumerables complejidades que se ocultan debajo. Los códecs y protocolos que utiliza WebRTC hacen una gran cantidad de trabajo para posibilitar la comunicación en tiempo real, incluso en redes poco confiables:
- Ocultamiento de la pérdida de paquetes
- Cancelación de eco
- Adaptabilidad del ancho de banda
- Almacenamiento en búfer de Jitter dinámico
- Control automático de ganancia
- Reducción y supresión de ruido
- Limpieza de imágenes
El código W3C anterior muestra un ejemplo simplificado de WebRTC desde una perspectiva de señalización. A continuación, se explican dos apps de WebRTC en funcionamiento. El primero es un ejemplo sencillo para demostrar RTCPeerConnection
y el segundo es un cliente de videochat completamente operativo.
RTCPeerConnection sin servidores
El siguiente código se tomó de la conexión de intercambio de tráfico de muestras de WebRTC, que tiene RTCPeerConnection
local y remoto (y video local y remoto) en una página web. Esto no constituye nada muy útil (el emisor y el destinatario están en la misma página), pero hace que el funcionamiento de la API de RTCPeerConnection
sea un poco más claro, ya que los objetos RTCPeerConnection
de la página pueden intercambiar datos y mensajes directamente sin tener que usar mecanismos de señalización intermediarios.
En este ejemplo, pc1
representa el par local (emisor) y pc2
representa el par remoto (destinatario).
Emisor
- Crea un
RTCPeerConnection
nuevo y agrega la transmisión desdegetUserMedia()
: ```js // Servers es un archivo de configuración opcional. (Consulta la discusión sobre TURN y STUN más adelante). pc1 = nueva RTCPeerConnection(servidores); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
- Crea una oferta y establécela como descripción local de
pc1
y como descripción remota depc2
. Esto se puede hacer directamente en el código sin usar la señalización, ya que el emisor y el destinatario están en la misma página:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
Callee
- Crea
pc2
y, cuando se agregue la transmisión depc1
, muéstrala en un elemento de video:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
RTCPeerConnection
API más servidores
En el mundo real, WebRTC necesita servidores, aunque sean simples, por lo que puede suceder lo siguiente:
- Los usuarios se descubren entre sí e intercambian detalles del mundo real, como nombres.
- Las apps cliente de WebRTC (intercambios de tráfico) intercambian información de red.
- Estas apps intercambian datos sobre el contenido multimedia, como el formato y la resolución de los videos.
- Las apps cliente de WebRTC recorren las puertas de enlace NAT y los firewalls.
En otras palabras, WebRTC necesita cuatro tipos de funcionalidad del servidor:
- Descubrimiento y comunicación de usuarios
- Señalización
- Recorrido de NAT y firewall
- Retransmite los servidores en caso de que falle la comunicación entre pares
El recorrido de NAT, las redes entre pares y los requisitos de compilación de una app de servidor para el descubrimiento y la señalización de usuarios están fuera del alcance de este artículo. Basta con decir que el framework ICE usa el protocolo STUN y su extensión, TURN, para permitir que RTCPeerConnection
se encargue del recorrido de NAT y otros vagarios de la red.
ICE es un marco para conectar a pares, como dos clientes de videochat. Inicialmente, ICE intenta conectar los intercambios de tráfico directamente con la menor latencia posible a través del UDP. En este proceso, los servidores STUN tienen una sola tarea: habilitar un par detrás de una NAT para averiguar su dirección pública y puerto. (Para obtener más información sobre STUN y TURN, consulta Cómo compilar los servicios de backend necesarios para una app de WebRTC).
Si UDP falla, ICE intenta usar TCP. Si la conexión directa falla, en particular debido a los firewalls y el recorrido de NAT empresarial, ICE usa un servidor TURN intermedio (retransmisión). En otras palabras, ICE primero usa STUN con UDP para conectar directamente los intercambios de tráfico y, si eso falla, recurre a un servidor de retransmisión TURN. La expresión encuentra candidatos se refiere al proceso de encontrar interfaces y puertos de red.
El ingeniero de WebRTC, Justin Uberti, proporciona más información sobre ICE, STUN y TURN en la presentación de WebRTC de Google I/O 2013. (Las diapositivas de la presentación proporcionan ejemplos de implementaciones de servidores TURN y STUN).
Un cliente sencillo de videochat
Un buen lugar para probar WebRTC, junto con la señalización y el recorrido de NAT/firewall con un servidor STUN, es la demostración de videochat en appr.tc. Esta app usa adapter.js, una corrección de compatibilidad para aislar las apps de los cambios de especificaciones y las diferencias de prefijos.
El código es deliberadamente detallado en su registro. Consulta la consola para comprender el orden de los eventos. A continuación, se incluye una explicación detallada del código.
Topologías de red
WebRTC, como se implementa actualmente, solo es compatible con la comunicación uno a uno, pero podría usarse en situaciones de red más complejas, como con varios pares que se comunican entre sí directamente o a través de una unidad de control multipunto (MCU), un servidor que puede manejar grandes cantidades de participantes y realizar reenvíos de transmisiones selectivos, y mezclar o grabar audio y video.
Muchas apps de WebRTC existentes solo demuestran la comunicación entre navegadores web, pero los servidores de puerta de enlace pueden habilitar una app de WebRTC que se ejecuta en un navegador para interactuar con dispositivos, como teléfonos (también conocidos como PSTN) y sistemas VoIP. En mayo de 2012, Doubango Telecom configuró con código abierto el cliente SIP sipml5 creado con WebRTC y WebSocket, que (entre otros usos posibles) permite realizar videollamadas entre navegadores y aplicaciones que se ejecutan en iOS y Android. En Google I/O, Tethr y Tropo demostraron un framework para las comunicaciones ante desastres en un maletín con una celda de OpenBTS para habilitar la comunicación entre teléfonos de gama media y computadoras a través de WebRTC. Comunicación telefónica sin operador
API de RTCDataChannel
<
Además de audio y video, WebRTC admite la comunicación en tiempo real para otros tipos de datos.
La API de RTCDataChannel
permite el intercambio entre pares de datos arbitrarios con baja latencia y alta capacidad de procesamiento. Para ver demostraciones de una sola página y aprender a compilar una app simple de transferencia de archivos, consulta las muestras de WebRTC y el codelab de WebRTC, respectivamente.
Existen muchos casos de uso potenciales para la API, incluidos los siguientes:
- Videojuegos
- Apps de escritorio remoto
- Chat de texto en tiempo real
- Transferencia de archivos
- Redes descentralizadas
La API tiene varias funciones para aprovechar RTCPeerConnection
al máximo y permitir una comunicación entre pares potente y flexible:
- Aprovecha la configuración de sesiones de
RTCPeerConnection
- Varios canales simultáneos con priorización
- Semántica de entrega confiable y poco confiable
- Seguridad integrada (DTLS) y control de congestión
- Posibilidad de uso con o sin audio o video
La sintaxis es similar a WebSocket con un método send()
y un evento 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 comunicación se produce directamente entre los navegadores, por lo que RTCDataChannel
puede ser mucho más rápido que WebSocket, incluso si se requiere un servidor de retransmisión (TURN) cuando la perforación de agujeros para hacer frente a los firewalls y las NAT fallan.
RTCDataChannel
está disponible en Chrome, Safari, Firefox, Opera y Samsung Internet. El juego Cube Slam usa la API para comunicar el estado del juego. Juega con tus amigos o con el oso. La innovadora plataforma Sharefest permitió el uso compartido de archivos a través de RTCDataChannel
, y peerCDN ofreció una idea de cómo WebRTC podía habilitar la distribución de contenido entre pares.
Para obtener más información sobre RTCDataChannel
, consulta la especificación de protocolo en borrador de la IETF.
Seguridad
Existen varias formas en las que una app o un complemento de comunicación en tiempo real puede comprometer la seguridad. Por ejemplo:
- Es posible que se intercepten contenido multimedia o datos no encriptados entre navegadores o entre un navegador y un servidor.
- Una app podría grabar y distribuir video o audio sin que el usuario lo sepa.
- Es posible que se instale software malicioso o virus junto con una app o un complemento aparentemente inocuo.
WebRTC cuenta con varias funciones para evitar estos problemas:
- Las implementaciones de WebRTC usan protocolos seguros, como DTLS y SRTP.
- La encriptación es obligatoria para todos los componentes de WebRTC, incluidos los mecanismos de señalización.
- WebRTC no es un complemento. Sus componentes se ejecutan en la zona de pruebas del navegador y no en un proceso independiente. Los componentes no requieren una instalación por separado y se actualizan cada vez que se actualiza el navegador.
- El acceso a la cámara y al micrófono debe otorgarse de manera explícita y, cuando estos se encuentren en ejecución, la interfaz de usuario lo mostrará claramente.
El análisis completo de la seguridad para la transmisión de contenido multimedia está fuera del alcance de este artículo. Para obtener más información, consulta la arquitectura de seguridad de WebRTC propuesta por la IETF.
Conclusión
Las APIs y los estándares de WebRTC pueden democratizar y descentralizar las herramientas de creación de contenido y comunicación, como la telefonía, los videojuegos, la producción de videos, la creación de música y la recopilación de noticias.
La tecnología no es mucho más disruptiva que esta.
Como lo expresó el blogger Phil Edholm: "Potencialmente, WebRTC y HTML5 podrían permitir la misma transformación de la comunicación en tiempo real que el navegador original hizo para la información".
Herramientas para desarrolladores
- Puedes encontrar las estadísticas de WebRTC de una sesión en curso en:
- about://webrtc-internals en Chrome
- opera://webrtc-internals en Opera
- about:webrtc en Firefox
- Notas de interoperabilidad entre navegadores
- adapter.js es una corrección de compatibilidad de JavaScript para WebRTC, que Google mantiene con la ayuda de la comunidad de WebRTC, en la que se resumen los prefijos de los proveedores, las diferencias de navegadores y los cambios de especificaciones.
- Para obtener más información sobre los procesos de señalización de WebRTC, consulta el resultado del registro appr.tc en la consola.
- Si son demasiados, puedes usar un framework de WebRTC o incluso un servicio de WebRTC completo.
- Los informes de errores y las solicitudes de funciones son siempre bienvenidos:
Más información
- Sesión de WebRTC de Justin Uberti en Google I/O 2012
- Alberto B. Johnston y Daniel C. Burnett mantiene un libro de WebRTC ahora en su tercera edición en formato impreso y de libro electrónico en webrtcbook.com.
- webrtc.org contiene todo lo relacionado con WebRTC, lo que incluye demostraciones, documentación y debates.
- describe-webrtc es un Grupo de Google para debates técnicos sobre WebRTC.
- @webrtc
- La documentación de Talk de Google Developers proporciona más información sobre el recorrido de NAT, STUN, los servidores de retransmisión y la recopilación de candidatos.
- WebRTC en GitHub
- Stack Overflow es un buen lugar para buscar respuestas y hacer preguntas sobre WebRTC.
Estándares y protocolos
- El borrador del editor de WebRTC W3C
- Borrador del editor de W3C: captura y transmisiones de contenido multimedia (también conocido como
getUserMedia
) - Estatuto del Grupo de Trabajo de IETF
- Borrador de protocolo para canal de datos de WebRTC de IETF
- Borrador de IETF JSEP
- Estándar propuesto por la IETF para ICE
- Borrador de Internet del grupo de trabajo de RTCWEB de IETF: Casos de uso y requisitos de comunicación web en tiempo real
Resumen de la compatibilidad con WebRTC
APIs de MediaStream
y getUserMedia
- Chrome para computadoras de escritorio 18.0.1008 y versiones posteriores Chrome para Android 29 y versiones posteriores
- Opera 18 y versiones posteriores Opera para Android 20 y versiones posteriores
- Opera 12, Opera Mobile 12 (basado en el motor Presto)
- Firefox 17 y versiones posteriores
- Microsoft Edge 16 y versiones posteriores
- Safari 11.2 y versiones posteriores en iOS, y 11.1 y versiones posteriores en MacOS
- UC 11.8 y versiones posteriores en Android
- Samsung Internet 4 y versiones posteriores
API RTCPeerConnection
- Computadora de escritorio Chrome 20 y versiones posteriores Chrome para Android 29 y versiones posteriores (sin marca)
- Opera 18 y versiones posteriores (activadas de forma predeterminada) Opera para Android 20 y versiones posteriores (activado de forma predeterminada)
- Firefox 22 y versiones posteriores (activados de forma predeterminada)
- Microsoft Edge 16 y versiones posteriores
- Safari 11.2 y versiones posteriores en iOS, y 11.1 y versiones posteriores en MacOS
- Samsung Internet 4 y versiones posteriores
API RTCDataChannel
- Versión experimental en Chrome 25, pero más estable (y con interoperabilidad con Firefox) en Chrome 26 y versiones posteriores. Chrome para Android 29 y versiones posteriores
- Versión estable (y con interoperabilidad con Firefox) en Opera 18 y versiones posteriores Opera para Android 20 y versiones posteriores
- Firefox 22 y versiones posteriores (activados de forma predeterminada)
Para obtener información más detallada sobre la compatibilidad multiplataforma con las APIs, como getUserMedia
y RTCPeerConnection
, consulta caniuse.com y Estado de la plataforma Chrome.
Las APIs nativas para RTCPeerConnection
también están disponibles en la documentación de webrtc.org.