WebRTC es un nuevo frente en la larga guerra por una Web abierta y sin restricciones.
Brendan Eich, inventor de JavaScript
Comunicación en tiempo real sin complementos
Imagina un mundo en el que tu teléfono, tu TV y tu computadora puedan comunicarse en una plataforma común. Imagina que fuera fácil agregar chat de video y uso compartido de datos punto a punto a tu aplicación web. Esa es la visión de WebRTC.
¿Quieres probarlo? WebRTC está disponible en 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 tu 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 el código?
- Para obtener una descripción general de WebRTC, mira el siguiente video de Google I/O o consulta estas diapositivas:
- Si no usaste la API de
getUserMedia
, consulta Cómo capturar audio y video en HTML5 y simpl.info getUserMedia. - Para obtener información sobre la API de
RTCPeerConnection
, consulta el siguiente ejemplo y "simpl.info RTCPeerConnection". - Para obtener información sobre cómo WebRTC usa servidores para la señalización y el recorrido de firewall y NAT, consulta el código y los registros de la consola de appr.tc.
- ¿No puedes esperar y quieres probar WebRTC ahora mismo? Prueba algunas de las más de 20 demostraciones que ejercitan las APIs de JavaScript de WebRTC.
- ¿Tienes problemas con tu máquina y WebRTC? Visita el Solucionador de problemas de WebRTC.
También puedes ir directamente al codelab de WebRTC, una guía paso a paso que explica cómo compilar una app de chat de video completa, incluido un servidor de señalización simple.
Una breve historia de WebRTC
Uno de los últimos desafíos importantes para la Web es permitir la comunicación humana a través de la voz y el video: la comunicación en tiempo real o RTC, para abreviar. La RTC debería ser tan natural en una app web como ingresar texto en un campo de entrada de texto. Sin ella, tu capacidad de innovar y desarrollar nuevas formas de interacción para las personas es limitada.
Históricamente, la RTC ha sido corporativa y compleja, y ha requerido licenciar o desarrollar internamente tecnologías de audio y video costosas. Integrar la tecnología de RTC con el contenido, los datos y los servicios existentes ha sido difícil y ha llevado mucho tiempo, en especial en la Web.
El chat de video de Gmail se hizo popular en 2008 y, en 2011, Google presentó Hangouts, que usa Talk (al igual que Gmail). Google compró GIPS, una empresa que desarrolló muchos componentes necesarios para las RTC, como códecs y técnicas de cancelación de eco. Google lanzó como código abierto las tecnologías desarrolladas por GIPS y se involucró con los organismos de estándares pertinentes en el Grupo de trabajo de ingeniería de Internet (IETF) y el Consorcio World Wide Web (W3C) para garantizar el consenso de la industria. En mayo de 2011, Ericsson creó la primera implementación de WebRTC.
WebRTC implementó estándares abiertos para la comunicación de video, audio y datos en tiempo real sin complementos. La necesidad era real:
- Muchos servicios web usaban RTC, pero necesitaban descargas, apps nativas o complementos. Entre ellos, se encontraban 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 con tecnología compleja y costosa. A menudo, 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 los 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 apps nativas de WebKitGTK+ y Qt.
WebRTC implementa estas tres APIs:
- MediaStream
(también conocida como getUserMedia
)
- RTCPeerConnection
- RTCDataChannel
Las APIs se definen en estas dos especificaciones:
Las tres APIs son compatibles con Chrome, Safari, Firefox, Edge y Opera en dispositivos móviles y computadoras.
getUserMedia
: Para ver demostraciones y código, consulta Ejemplos de WebRTC o prueba los increíbles ejemplos de Chris Wilson que usan getUserMedia
como entrada para el audio web.
RTCPeerConnection
: Para ver una demostración simple y una app de chat de video completamente funcional, consulta Ejemplos de WebRTC: Conexión entre pares y appr.tc, respectivamente. Esta app usa adapter.js, un shim de JavaScript que mantiene Google con la ayuda de la comunidad de WebRTC, para abstraer las diferencias entre los navegadores y los cambios en las especificaciones.
RTCDataChannel
: Para ver esto en acción, consulta las muestras de WebRTC y mira 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 para el chat de video y el uso compartido de archivos.
Tu primer WebRTC
Las apps de WebRTC deben hacer varias cosas:
- Obtener audio, video o cualquier otro tipo de datos de transmisión
- Obtener información de la red, como direcciones IP y puertos, e intercambiarla con otros clientes de WebRTC (conocidos como peers) para habilitar la conexión, incluso a través de NAT y firewalls
- Coordina la comunicación de señalización para informar errores y cerrar o iniciar sesiones.
- Intercambiar información sobre la capacidad del cliente y los medios, como la resolución y los códecs
- Comunicar audio, video o datos de transmisión
Para adquirir y comunicar datos de transmisión, WebRTC implementa las siguientes APIs:
MediaStream
obtiene acceso a transmisiones de datos, como las de la cámara y el micrófono del usuario.RTCPeerConnection
permite realizar llamadas de audio o video con funciones de encriptación y administración de ancho de banda.RTCDataChannel
habilita la comunicación de datos genéricos de punto a punto.
(Más adelante, se analizarán en detalle los aspectos de la red y la señalización de WebRTC).
API de MediaStream
(también conocida como API de getUserMedia
)
La API de MediaStream
representa transmisiones sincronizadas de contenido multimedia. Por ejemplo, una transmisión tomada de la entrada de la cámara y el micrófono tiene pistas de audio y video 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
es verla en acción:
- En tu navegador, ve a Ejemplos de WebRTC
getUserMedia
. - Abre la consola.
- Inspecciona la variable
stream
, que se encuentra en el alcance global.
Cada MediaStream
tiene una entrada, que puede ser un MediaStream
generado por getUserMedia()
, y una salida, que se puede pasar a un elemento de video o a un RTCPeerConnection
.
El método getUserMedia()
toma un parámetro de objeto MediaStreamConstraints
y devuelve un Promise
que se resuelve en un objeto MediaStream
.
Cada MediaStream
tiene un label
, como 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. Los métodos getAudioTracks()
y getVideoTracks()
devuelven un array de MediaStreamTrack
.
En el ejemplo de getUserMedia
, stream.getAudioTracks()
devuelve un array vacío (porque no hay audio) y, suponiendo que hay una cámara web en funcionamiento conectada, stream.getVideoTracks()
devuelve 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
(algo como '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 de 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 configurando el atributo srcObject
. Anteriormente, esto se hacía configurando el atributo src
en una URL de objeto creada con URL.createObjectURL()
, pero esta opción dejó de estar disponible.
getUserMedia
también se puede usar como un 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
. Agregar permisos audioCapture
o videoCapture
al manifiesto permite que se soliciten y otorguen permisos solo una vez durante la instalación. A partir de entonces, no se le solicita permiso al usuario para acceder a la cámara o al micrófono.
Solo se debe otorgar el permiso una vez para getUserMedia()
. La primera vez, se muestra un botón Permitir en la barra de información del navegador. Chrome dejó de admitir el acceso HTTP para getUserMedia()
a fines de 2015 porque se clasificó como una función potente.
La intención es, potencialmente, habilitar un MediaStream
para cualquier fuente de datos de transmisión, no solo una cámara o un micrófono. Esto permitiría la transmisión desde datos almacenados o fuentes de datos arbitrarias, como sensores o 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 facial creado con headtrackr.js.
- ASCII Camera 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 admitir otras restricciones, como la relación de aspecto, el modo de orientación (cámara frontal o posterior), la velocidad de fotogramas, la altura y el ancho, y un método applyConstraints()
.
Para ver un ejemplo, consulta Ejemplos de WebRTC getUserMedia
: Selecciona la resolución.
Si se establece un valor de restricción no permitido, se devuelve un DOMException
o un OverconstrainedError
si, por ejemplo, no está disponible la resolución solicitada. Para ver esto en acción, consulta Ejemplos de WebRTC getUserMedia
: Selecciona la resolución para ver 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 obtener una demostración y más información, consulta Compartir pantalla con WebRTC. El artículo tiene algunos años, pero sigue siendo interesante.
También es posible usar la captura de pantalla como fuente de MediaStream
en Chrome con la restricción experimental chromeMediaSource
. Ten en cuenta que la captura de pantalla requiere HTTPS y solo se debe usar para el desarrollo, ya que se habilita a través de una marca de línea de comandos, como se explica en esta publicación.
Señalización: Control de sesión, red e información de 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 ni los protocolos de señalización. La señalización no forma parte de la API de RTCPeerConnection
.
En cambio, 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 de appr.tc usa XHR y la API de Channel como mecanismo de señalización. El codelab usa Socket.io que se ejecuta en un servidor de Node.
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 y registrar errores.
- Configuración de red: ¿Cuál es la dirección IP y el puerto de tu computadora para el mundo exterior?
- Capacidades de medios: ¿Qué códecs y resoluciones pueden controlar tu navegador y el navegador con el que se quiere comunicar?
El intercambio de información a través de la señalización debe completarse correctamente antes de que pueda comenzar la transmisión de punto a punto.
Por ejemplo, imagina que Alicia quiere comunicarse con Roberto. Aquí tienes un ejemplo de código de la especificación de WebRTC de W3C, que muestra el proceso de señalización en acción. El código supone la existencia de algún mecanismo de señalización creado en el método createSignalingChannel()
. También ten en cuenta que, en Chrome y Opera, RTCPeerConnection
actualmente tiene un prefijo.
// 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 búsqueda de candidatos se refiere al proceso de búsqueda de interfaces y puertos de red con el framework de ICE).
- Alice crea un objeto
RTCPeerConnection
con un controladoronicecandidate
, que se ejecuta cuando hay candidatos de red disponibles. - Alicia envía datos serializados de candidatos a Bob a través del canal de señalización que estén usando, como WebSocket o algún otro mecanismo.
- Cuando Bob recibe un mensaje de candidato de Alice, llama a
addIceCandidate
para agregar el candidato a la descripción del par remoto.
Los clientes de WebRTC (también conocidos como pares, o Alice y Bob en este ejemplo) también deben determinar e intercambiar información de medios de audio y video locales y remotos, como la resolución y las capacidades del códec. La señalización para intercambiar información de configuración de medios se realiza intercambiando una oferta y una respuesta con el Protocolo de descripción de sesiones (SDP):
- Alicia ejecuta el método
RTCPeerConnection
createOffer()
. El valor que se devuelve de esta función se pasa a unRTCSessionDescription
, que es la 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 esta descripción de la sesión a Bob a través de su canal de señalización. Ten en cuenta queRTCPeerConnection
no comenzará a recopilar candidatos hasta que se llame asetLocalDescription()
. Esto se codifica en el borrador de JSEP de IETF. - Bob establece la descripción que le envió Alice como la descripción remota con
setRemoteDescription()
. - Roberto ejecuta el método
RTCPeerConnection
createAnswer()
y le pasa la descripción remota que obtuvo de Alicia para que se pueda generar una sesión local compatible con la de ella. A la devolución de llamadacreateAnswer()
se le pasa unRTCSessionDescription
. Bob establece esa descripción como la local y se la envía a Alice. - Cuando Alice recibe la descripción de la sesión de Bob, la establece como la descripción remota con
setRemoteDescription
. - ¡Ping!
Los objetos RTCSessionDescription
son BLOBs que cumplen con el Protocolo de descripción de sesión (SDP). Cuando se serializa, 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 red y de medios se pueden realizar de forma simultánea, pero ambos procesos deben completarse antes de que pueda comenzar la transmisión de audio y video entre pares.
La arquitectura de oferta/respuesta que se describió anteriormente se denomina JavaScript Session Establishment Protocol o JSEP. (Hay una excelente animación que 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 completa correctamente, los datos se pueden transmitir directamente de punto a punto, entre el llamador y el receptor, o, si eso falla, a través de un servidor de retransmisión intermediario (más sobre eso más adelante). La transmisión es el trabajo de RTCPeerConnection
.
RTCPeerConnection
RTCPeerConnection
es el componente de WebRTC que controla la comunicación estable y eficiente de los datos de transmisión entre pares.
A continuación, se muestra un diagrama de arquitectura de WebRTC en el que se indica el rol de RTCPeerConnection
. Como notarás, las partes verdes son complejas.

Desde la perspectiva de JavaScript, lo principal que se debe comprender de este diagrama es que RTCPeerConnection
protege a los desarrolladores web de la gran cantidad de complejidades que se ocultan debajo. Los códecs y protocolos que usa WebRTC realizan una gran cantidad de trabajo para hacer posible la comunicación en tiempo real, incluso en redes poco confiables:
- Ocultamiento de 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 anterior del W3C muestra un ejemplo simplificado de WebRTC desde una perspectiva de señalización. A continuación, se incluyen explicaciones detalladas de dos apps de WebRTC en funcionamiento. El primero es un ejemplo simple para demostrar RTCPeerConnection
, y el segundo es un cliente de chat de video completamente operativo.
RTCPeerConnection sin servidores
El siguiente código se tomó de WebRTC samples Peer connection, que tiene RTCPeerConnection
local y remoto (y video local y remoto) en una página web. Esto no constituye nada muy útil (el llamador y el llamado están en la misma página), pero sí aclara un poco el funcionamiento de la API de RTCPeerConnection
, ya que los objetos RTCPeerConnection
de la página pueden intercambiar datos y mensajes directamente sin tener que usar mecanismos de señalización intermedios.
En este ejemplo, pc1
representa el par local (llamador) y pc2
representa el par remoto (llamado).
Emisor
- Crea un nuevo
RTCPeerConnection
y agrega la transmisión desdegetUserMedia()
: ```js // Servers is an optional configuration file. (Consulta la explicación sobre TURN y STUN más adelante). pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
- Crea una oferta y configúrala como la descripción local para
pc1
y como la descripción remota parapc2
. Esto se puede hacer directamente en el código sin usar señalización, ya que tanto el llamador como el receptor 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
Servidores y API
En el mundo real, WebRTC necesita servidores, por más simples que sean, por lo que puede ocurrir lo siguiente:
- Los usuarios se descubren entre sí y comparten detalles del mundo real, como nombres.
- Las apps cliente (pares) de WebRTC intercambian información de red.
- Los pares intercambian datos sobre los medios, como el formato y la resolución de video.
- Las apps cliente de WebRTC atraviesan puertas de enlace NAT y firewalls.
En otras palabras, WebRTC necesita cuatro tipos de funcionalidad del servidor:
- Descubrimiento y comunicación con el usuario
- Señalización
- Recorrido de NAT/firewall
- Servidores de retransmisión en caso de que falle la comunicación entre pares
El recorrido de NAT, las redes punto a punto y los requisitos para compilar una app de servidor para la detección y la señalización de usuarios están fuera del alcance de este artículo. Basta con decir que el marco de trabajo ICE usa el protocolo STUN y su extensión, TURN, para permitir que RTCPeerConnection
haga frente al recorrido de NAT y otras incertidumbres de la red.
ICE es un framework para conectar pares, como dos clientes de chat de video. Inicialmente, ICE intenta conectar pares directamente con la menor latencia posible a través de UDP. En este proceso, los servidores STUN tienen una sola tarea: permitir que un par detrás de una NAT descubra su dirección y puerto públicos. (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 falla la conexión directa, en particular debido al firewall y al recorrido de NAT empresarial, ICE usa un servidor TURN intermedio (de retransmisión). En otras palabras, ICE primero usa STUN con UDP para conectar directamente a los pares y, si eso falla, recurre a un servidor de retransmisión TURN. La expresión encontrar 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 brindan ejemplos de implementaciones de servidores TURN y STUN).
Un cliente de chat de video simple
Un buen lugar para probar WebRTC, con señalización y recorrido de NAT/firewall con un servidor STUN, es la demostración de chat de video en appr.tc. Esta app usa adapter.js, un shim para aislar las apps de los cambios en las 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, tal como se implementa actualmente, solo admite 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 controlar una gran cantidad de participantes y realizar el reenvío, la mezcla o la grabación selectivos de audio y video.

Muchas apps de WebRTC existentes solo demuestran la comunicación entre navegadores web, pero los servidores de puerta de enlace pueden permitir que una app de WebRTC que se ejecuta en un navegador interactúe con dispositivos, como teléfonos (también conocidos como PSTN) y con sistemas de VOIP. En mayo de 2012, Doubango Telecom lanzó como código abierto el cliente SIP sipml5 creado con WebRTC y WebSocket, que (entre otros usos posibles) permite realizar videollamadas entre navegadores y apps que se ejecutan en iOS y Android. En Google I/O, Tethr y Tropo demostraron un marco de trabajo para las comunicaciones en caso de desastre en un maletín con una celda OpenBTS para habilitar las comunicaciones entre teléfonos básicos 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 de datos arbitrarios punto a punto 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 Ejemplos de WebRTC y el codelab de WebRTC, respectivamente.
Existen muchos casos de uso posibles 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 al máximo RTCPeerConnection
y permitir una comunicación punto a punto potente y flexible:
- Aprovechamiento de la configuración de la sesión de
RTCPeerConnection
- Varios canales simultáneos con priorización
- Semántica de entrega confiable y no confiable
- Seguridad integrada (DTLS) y control de congestión
- Capacidad de usar con o sin audio o video
La sintaxis es deliberadamente 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 falla la perforación de agujeros para hacer frente a los firewalls y las NAT.
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 un amigo o con el oso. La innovadora plataforma Sharefest habilitó el uso compartido de archivos a través de RTCDataChannel
y peerCDN ofreció un vistazo de cómo WebRTC podría habilitar la distribución de contenido peer-to-peer.
Para obtener más información sobre RTCDataChannel
, consulta la especificación del protocolo en borrador del IETF.
Seguridad
Existen varias formas en que un complemento o una app de comunicación en tiempo real pueden comprometer la seguridad. Por ejemplo:
- Es posible que se intercepten los datos o el contenido multimedia sin encriptar entre navegadores, o entre un navegador y un servidor.
- Una app puede grabar y distribuir audio o video sin que el usuario lo sepa.
- Es posible que se instalen software malicioso o virus junto con un complemento o una app aparentemente inofensivos.
WebRTC tiene 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 separado. Los componentes no requieren una instalación independiente y se actualizan cada vez que se actualiza el navegador.
- El acceso a la cámara y al micrófono se debe otorgar de forma explícita y, cuando la cámara o el micrófono están en funcionamiento, la interfaz de usuario lo muestra claramente.
En este artículo, no se aborda en detalle la seguridad del contenido multimedia en transmisión. Para obtener más información, consulta la Arquitectura de seguridad de WebRTC propuesta por el IETF.
Conclusión
Las APIs y los estándares de WebRTC pueden democratizar y descentralizar las herramientas para la creación de contenido y la comunicación, incluidas la telefonía, los juegos, la producción de video, la creación de música y la recopilación de noticias.
La tecnología no puede ser mucho más revolucionaria que esto.
Como dijo el bloguero Phil Edholm, "Potencialmente, WebRTC y HTML5 podrían permitir la misma transformación para 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 la siguiente ubicación:
- about://webrtc-internals en Chrome
- opera://webrtc-internals en Opera
- about:webrtc en Firefox
Captura de pantalla de chrome://webrtc-internals
- Notas de interoperabilidad entre navegadores
- adapter.js es un shim de JavaScript para WebRTC que Google mantiene con la ayuda de la comunidad de WebRTC y que abstrae los prefijos de proveedores, las diferencias entre navegadores y los cambios en las especificaciones.
- Para obtener más información sobre los procesos de señalización de WebRTC, consulta el registro de salida de appr.tc en la consola.
- Si todo esto es demasiado, tal vez prefieras usar un framework de WebRTC o incluso un servicio de WebRTC completo.
- Siempre se agradecen los informes de errores y las solicitudes de funciones:
Más información
- Sesión de Justin Uberti sobre WebRTC en Google I/O 2012
- Alan B. Johnston y Daniel C. Burnett mantiene un libro sobre WebRTC, que ahora está en su tercera edición en formatos impreso y de libro electrónico en webrtcbook.com.
- En webrtc.org, encontrarás todo lo relacionado con WebRTC, incluidas demostraciones, documentación y debates.
- discuss-webrtc es un grupo de Google para debates técnicos sobre WebRTC.
- @webrtc
- La documentación de la charla 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
- Borrador del editor de WebRTC de W3C
- Borrador del editor del W3C: Captura y transmisiones de medios (también conocido como
getUserMedia
) - IETF Working Group Charter (Carta del Grupo de Trabajo del IETF)
- Borrador del protocolo de canal de datos de WebRTC del IETF
- Borrador de JSEP del IETF
- Estándar propuesto por IETF para ICE
- Borrador de Internet del Grupo de trabajo RTCWEB del IETF: Web Real-Time Communication Use-cases and Requirements
Resumen de 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 y Opera Mobile 12 (basados 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
- Chrome para computadoras 20 y versiones posteriores; Chrome para Android 29 y versiones posteriores (sin marcas)
- Opera 18 y versiones posteriores (activado de forma predeterminada); Opera para Android 20 y versiones posteriores (activado de forma predeterminada)
- Firefox 22 y versiones posteriores (activado 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 de Firefox) en Chrome 26 y versiones posteriores; Chrome para Android 29 y versiones posteriores
- Versión estable (y con interoperabilidad de Firefox) en Opera 18 y versiones posteriores; Opera para Android 20 y versiones posteriores
- Firefox 22 y versiones posteriores (activado de forma predeterminada)
Para obtener información más detallada sobre la compatibilidad multiplataforma de las APIs, como getUserMedia
y RTCPeerConnection
, consulta caniuse.com y el Estado de la plataforma de Chrome.
Las APIs nativas para RTCPeerConnection
también están disponibles en la documentación de webrtc.org.