O WebRTC é uma nova frente na longa guerra por uma Web aberta e livre.
Brendan Eich, inventor do JavaScript
Comunicação em tempo real sem plug-ins
Imagine um mundo onde seu smartphone, sua TV e seu computador possam se comunicar em uma plataforma comum. Imagine que foi fácil adicionar o chat por vídeo e o compartilhamento de dados ponto a ponto ao seu app da Web. Essa é a visão do WebRTC.
Quer fazer um teste? O WebRTC está disponível para computador e dispositivos móveis no Google Chrome, Safari, Firefox e Opera. Um bom ponto de partida é o aplicativo simples de chat por vídeo em appr.tc:
- Abra appr.tc no navegador.
- Clique em Participar para entrar em uma sala de chat e permitir que o app use a webcam.
- Abra o URL exibido no final da página em uma nova guia ou, melhor ainda, em outro computador.
Início rápido
Não tem tempo para ler este artigo ou só quer um código?
- Para ter uma visão geral do WebRTC, assista ao vídeo do Google I/O a seguir ou veja estes slides:
- Se você não usou a API
getUserMedia
, consulte Capturar áudio e vídeo em HTML5 e simpl.info getUserMedia. - Para saber mais sobre a API
RTCPeerConnection
, consulte o exemplo a seguir e 'simpl.info RTCPeerConnection'. - Para saber como o WebRTC usa servidores para sinalização e travessia de firewall e NAT, consulte os registros de código e console de appr.tc.
- Não pode esperar e só quer testar o WebRTC agora? Teste algumas das mais de 20 demonstrações que usam as APIs JavaScript do WebRTC.
- Está tendo problemas com sua máquina e o WebRTC? Acesse o solucionador de problemas de WebRTC.
Se preferir, vá direto para o codelab de WebRTC, um guia explicativo que explica como criar um app de chat por vídeo completo, incluindo um servidor de sinalização simples.
Uma história muito curta do WebRTC
Um dos últimos grandes desafios para a Web é possibilitar a comunicação humana por voz e vídeo: comunicação em tempo real ou RTC. O RTC deve ser tão natural em um aplicativo da web quanto inserir texto em uma entrada de texto. Sem ele, você fica limitado na capacidade de inovar e desenvolver novas maneiras de interagir.
Historicamente, o RTC é empresarial e complexo, exigindo tecnologias caras de áudio e vídeo para serem licenciadas ou desenvolvidas internamente. Integrar a tecnologia RTC aos conteúdos, dados e serviços existentes tem sido difícil e demorado, principalmente na Web.
O bate-papo por vídeo do Gmail se tornou popular em 2008 e, em 2011, o Google lançou o Hangouts, que usa o Talk (assim como o Gmail). O Google comprou o GIPS, uma empresa que desenvolveu vários componentes necessários para o RTC, como codecs e técnicas de cancelamento de eco. O Google abriu o código das tecnologias desenvolvidas pelo GIPS e interagiu com órgãos de normalização relevantes da Internet Engineering Task Force (IETF) e do World Wide Web Consortium (W3C) para garantir o consenso do setor. Em maio de 2011, a Ericsson criou a primeira implementação do WebRTC.
O WebRTC implementou padrões abertos para comunicação de vídeo, áudio e dados em tempo real sem plug-ins. A necessidade era real:
- Muitos serviços da Web usavam o RTC, mas precisavam de downloads, aplicativos nativos ou plug-ins. Entre elas, o Skype, o Facebook e o Hangouts.
- Fazer o download, instalar e atualizar plug-ins é complexo, propenso a erros e irritante.
- Os plug-ins são difíceis de implantar, depurar, solucionar problemas, testar e manter, e podem exigir licenciamento e integração com tecnologia complexa e cara. Muitas vezes, é difícil persuadir as pessoas a instalar plug-ins.
Os princípios orientadores do projeto WebRTC são que as APIs devem ser de código aberto, sem custo financeiro, padronizadas, incorporadas a navegadores da Web e mais eficientes do que as tecnologias existentes.
Onde estamos agora?
O WebRTC é usado em vários apps, como o Google Meet. O WebRTC também foi integrado ao WebKitGTK+ e aos apps nativos do Qt.
O WebRTC implementa estas três APIs:
- MediaStream
(também conhecido como getUserMedia
)
- RTCPeerConnection
- RTCDataChannel
As APIs são definidas nestas duas especificações:
As três APIs são compatíveis com dispositivos móveis e computadores no Chrome, Safari, Firefox, Edge e Opera.
getUserMedia
: para ver demonstrações e códigos, consulte os exemplos de WebRTC (em inglês) ou os exemplos incríveis de Chris Wilson que usam getUserMedia
como entrada para o áudio da Web.
RTCPeerConnection
: para ver uma demonstração simples e um app de chat por vídeo totalmente funcional, consulte WebRTC exemplos de conexão de peering e appr.tc, respectivamente. Esse app usa o adapter.js, um paliativo JavaScript mantido pelo Google com a ajuda da comunidade WebRTC, para abstrair as diferenças do navegador e as mudanças nas especificações.
RTCDataChannel
: para ver isso em ação, consulte exemplos de WebRTC para conferir uma das demonstrações do canal de dados.
O codelab de WebRTC mostra como usar as três APIs para criar um app simples para chat por vídeo e compartilhamento de arquivos.
Seu primeiro WebRTC
Os apps WebRTC precisam fazer várias coisas:
- Receber streaming de áudio, vídeo e outros dados.
- Receba informações de rede, como endereços IP e portas, e as troque com outros clientes WebRTC (conhecidos como peers) para permitir a conexão, mesmo por meio de NATs e firewalls.
- Coordene a comunicação da sinalização para relatar erros e iniciar ou encerrar sessões.
- Troque informações sobre a mídia e a capacidade do cliente, como resolução e codecs.
- Transmitir streaming de áudio, vídeo ou dados.
Para adquirir e comunicar dados de streaming, o WebRTC implementa as seguintes APIs:
- O
MediaStream
tem acesso a fluxos de dados, como da câmera e do microfone do usuário. - O
RTCPeerConnection
permite fazer chamadas de áudio ou videochamadas com recursos de criptografia e gerenciamento de largura de banda. - O
RTCDataChannel
permite a comunicação ponto a ponto de dados genéricos.
Você verá uma discussão detalhada sobre os aspectos de rede e sinalização do WebRTC posteriormente.
API MediaStream
(também conhecida como API getUserMedia
)
A API MediaStream
representa fluxos de mídia sincronizados. Por exemplo, um stream feito com a câmera e o microfone tem faixas de vídeo e áudio sincronizadas. Não confunda MediaStreamTrack
com o elemento <track>
, que é totalmente diferente.
Provavelmente, a maneira mais fácil de entender a API MediaStream
é analisá-la:
- No navegador, acesse os exemplos de WebRTC
getUserMedia
. - Abra o console.
- Inspecione a variável
stream
, que está no escopo global.
Cada MediaStream
tem uma entrada, que pode ser uma MediaStream
gerada por getUserMedia()
, e uma saída, que pode ser transmitida para um elemento de vídeo ou um RTCPeerConnection
.
O método getUserMedia()
usa um parâmetro de objeto MediaStreamConstraints
e retorna um Promise
que se refere a um objeto MediaStream
.
Cada MediaStream
tem um label
, como 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. Uma matriz de MediaStreamTrack
s é retornada pelos métodos getAudioTracks()
e getVideoTracks()
.
No exemplo de getUserMedia
, stream.getAudioTracks()
retorna uma matriz vazia (porque não há áudio) e, supondo que uma webcam esteja conectada, stream.getVideoTracks()
retorna uma matriz de uma MediaStreamTrack
representando a transmissão da webcam. Cada MediaStreamTrack
tem um tipo ('video'
ou 'audio'
), um label
(algo como 'FaceTime HD Camera (Built-in)'
) e representa um ou mais canais de áudio ou vídeo. Nesse caso, há apenas uma faixa de vídeo e nenhum áudio, mas é fácil imaginar casos de uso em que há mais, como um app de chat que recebe streamings da câmera frontal, da câmera traseira, do microfone e de um app que compartilha a tela.
Para anexar um MediaStream
a um elemento de vídeo, defina o atributo srcObject
. Antes, isso era feito definindo o atributo src
como um URL de objeto criado com URL.createObjectURL()
, mas isso foi descontinuado.
getUserMedia
também pode ser usado como um nó de entrada para a 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);
});
Apps e extensões baseados no Chromium também podem incorporar getUserMedia
. A adição de permissões audioCapture
e/ou videoCapture
ao manifesto permite que ela seja solicitada e concedida apenas uma vez na instalação. Depois disso, a permissão de acesso à câmera ou ao microfone não vai ser solicitada.
A permissão só precisa ser concedida uma vez para getUserMedia()
. Na primeira vez, um botão "Permitir" é exibido na barra de informações do navegador. O acesso HTTP para getUserMedia()
foi descontinuado pelo Chrome no final de 2015 por ser classificado como um recurso avançado.
A intenção é ativar um MediaStream
para qualquer fonte de dados de streaming, não apenas para uma câmera ou um microfone. Isso permitiria o streaming de dados armazenados ou fontes de dados arbitrárias, como sensores ou outras entradas.
O getUserMedia()
realmente ganha vida em combinação com outras APIs e bibliotecas JavaScript:
- O Webcam Toy é um app de cabine de fotos que usa WebGL para adicionar efeitos estranhos e maravilhosos às fotos que podem ser compartilhadas ou salvas localmente.
- O FaceKat é um jogo de rastreamento facial criado com headtrackr.js.
- A câmera ASCII usa a API Canvas para gerar imagens ASCII.
Restrições
Restrições podem ser usadas para definir valores de resolução de vídeo para getUserMedia()
. Isso também permite suporte a outras restrições, como proporção, modo voltado (câmera frontal ou traseira), frame rate, altura e largura e um método applyConstraints()
.
Por exemplo, consulte Exemplos de WebRTC getUserMedia
: selecionar resolução.
Definir um valor de restrição não permitido vai fornecer uma DOMException
ou um OverconstrainedError
se, por exemplo, uma resolução solicitada não estiver disponível. Para ver isso em ação, consulte Exemplos de WebRTC getUserMedia
: selecionar resolução para ver uma demonstração.
Captura de tela e guia
Os apps do Chrome também permitem compartilhar um vídeo ao vivo de uma única guia do navegador ou de toda a área de trabalho usando as APIs chrome.tabCapture
e chrome.desktopCapture
. Para uma demonstração e mais informações, consulte Compartilhamento de tela com WebRTC. O artigo tem alguns anos, mas ainda é interessante.)
Também é possível usar a captura de tela como uma fonte MediaStream
no Chrome com a restrição experimental chromeMediaSource
. A captura de tela exige HTTPS e só deve ser usada para desenvolvimento por ser ativada por uma sinalização de linha de comando, conforme explicado nesta postagem.
Sinalização: informações de controle de sessão, rede e mídia
O WebRTC usa RTCPeerConnection
para comunicar dados de streaming entre navegadores (também conhecidos como pares), mas também precisa de um mecanismo para coordenar a comunicação e enviar mensagens de controle, um processo conhecido como sinalização. Os métodos e protocolos de sinalização não são especificados pelo WebRTC. A sinalização não faz parte da API RTCPeerConnection
.
Em vez disso, os desenvolvedores de aplicativos WebRTC podem escolher o protocolo de mensagens que preferirem, como SIP ou XMPP, e qualquer canal de comunicação duplex (duplex) adequado. O exemplo appr.tc usa o XHR e a API Channel como mecanismo de sinalização. O codelab usa o Socket.io (em inglês) em execução em um servidor de nó.
A sinalização é usada para trocar três tipos de informações:
- Mensagens de controle de sessão: para inicializar ou fechar a comunicação e relatar erros.
- Configuração de rede: para o mundo exterior, qual é o endereço IP e a porta do seu computador?
- Recursos de mídia: quais codecs e resoluções podem ser manipulados pelo seu navegador e pelo navegador com o qual ele deseja se comunicar?
A troca de informações por sinalização precisa ter sido concluída com sucesso antes que o streaming ponto a ponto possa começar.
Por exemplo, imagine que Alice quer se comunicar com Bob. Veja um exemplo de código da especificação WebRTC do W3C (em inglês), que mostra o processo de sinalização em ação. O código pressupõe a existência de algum mecanismo de sinalização criado no método createSignalingChannel()
. No Chrome e no Opera, RTCPeerConnection
é prefixado atualmente.
// 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);
}
};
Primeiro, Alice e Beto trocam informações de rede. A expressão encontrar candidatos refere-se ao processo de encontrar interfaces e portas de rede usando o framework ICE.
- Alice cria um objeto
RTCPeerConnection
com um gerenciadoronicecandidate
, que é executado quando os candidatos à rede ficam disponíveis. - Alice envia dados de candidatos serializados para Bob por qualquer canal de sinalização que estiver usando, como WebSocket ou outro mecanismo.
- Quando Bob recebe uma mensagem candidata a Alice, ele chama
addIceCandidate
para adicionar o candidato à descrição do peering remoto.
Os clientes WebRTC (também conhecidos como peers, ou Alice e Bob, neste exemplo) também precisam verificar e trocar informações locais e remotas de mídia de áudio e vídeo, como resolução e recursos de codec. A sinalização para trocar informações de configuração de mídia troca uma oferta e uma resposta usando o protocolo de descrição da sessão (SDP, na sigla em inglês):
- Alice executa o método
RTCPeerConnection
createOffer()
. O retorno recebe umRTCSessionDescription
, que é a descrição da sessão local de Alice. - No callback, Alice define a descrição local usando
setLocalDescription()
e, em seguida, envia a descrição dessa sessão a Bob pelo canal de sinalização. Observe queRTCPeerConnection
não começará a reunir candidatos até quesetLocalDescription()
seja chamado. Isso está codificado no rascunho do JSEP IETF. - Bob define a descrição que Alice enviou como a descrição remota usando
setRemoteDescription()
. - Bob executa o método
createAnswer()
RTCPeerConnection
, transmitindo a descrição remota que ele recebeu da Alice para que seja gerada uma sessão local compatível com a dela. O callbackcreateAnswer()
recebe umRTCSessionDescription
. Bob define isso como a descrição local e a envia para Alice. - Quando Alice recebe a descrição da sessão de Bob, ela a define como a descrição remota com
setRemoteDescription
. - Ping!
Os objetos RTCSessionDescription
são blobs que estão em conformidade com o Protocolo de descrição da sessão (SDP). Serializado, um objeto SDP tem a seguinte aparência:
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
A aquisição e a troca de informações de rede e mídia podem ser feitas simultaneamente, mas ambos os processos precisam ser concluídos antes que o streaming de áudio e vídeo entre os pares possa começar.
A arquitetura de oferta/resposta descrita anteriormente é chamada JavaScript Session Estament Protocol, ou JSEP. Há uma excelente animação explicando o processo de sinalização e streaming no vídeo de demonstração do Ericsson (em inglês) para a primeira implementação do WebRTC.
Quando o processo de sinalização é concluído com sucesso, os dados podem ser transmitidos diretamente ponto a ponto, entre o autor da chamada e o recebedor da chamada ou, se isso falhar, por um servidor de redirecionamento intermediário (vamos saber mais sobre isso depois). O streaming é o job de RTCPeerConnection
.
RTCPeerConnection
RTCPeerConnection
é o componente WebRTC que lida com a comunicação estável e eficiente de dados de streaming entre pares.
Veja a seguir um diagrama de arquitetura WebRTC que mostra o papel de RTCPeerConnection
. Como você notará, as partes verdes são complexas!
Do ponto de vista do JavaScript, o principal elemento a entender nesse diagrama é que o RTCPeerConnection
protege os desenvolvedores da Web das inúmeras complexidades que estão por trás. Os codecs e protocolos usados pelo WebRTC fazem um enorme trabalho para possibilitar a comunicação em tempo real, mesmo em redes não confiáveis:
- Ocultação da perda de pacotes
- Cancelamento de eco
- Adaptabilidade da largura de banda
- Buffer de instabilidade dinâmica
- Controle automático de ganho
- Redução e supressão de ruído
- Limpeza de imagens
O código W3C anterior mostra um exemplo simplificado de WebRTC de uma perspectiva de sinalização. Confira a seguir instruções de dois apps WebRTC que funcionam. O primeiro é um exemplo simples para demonstrar RTCPeerConnection
, e o segundo é um cliente de chat por vídeo totalmente operacional.
RTCPeerConnection sem servidores
O código a seguir foi retirado de exemplos de WebRTC para conexão de peering, que tem RTCPeerConnection
local e remoto (e vídeo local e remoto) em uma página da Web. Isso não é muito útil, porque o autor da chamada e o recebedor da chamada estão na mesma página, mas deixa o funcionamento da API RTCPeerConnection
um pouco mais claro, porque os objetos RTCPeerConnection
na página podem trocar dados e mensagens diretamente, sem precisar usar mecanismos de sinalização intermediários.
Neste exemplo, pc1
representa o peering local (autor da chamada) e pc2
representa o peering remoto (recebedor da chamada).
Autor da chamada
- Crie um novo
RTCPeerConnection
e adicione o stream degetUserMedia()
: ```js // "Servidores" é um arquivo de configuração opcional. (Consulte a discussão sobre TURN e STUN mais tarde.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEvery((track) => { pc1.addTrack(track, localStream); });
- Crie uma oferta e a defina como a descrição local para
pc1
e como a descrição remota parapc2
. Isso pode ser feito diretamente no código sem usar sinalização, porque o autor da chamada e o recebedor da chamada estão na mesma página:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
Destinatário da chamada
- Crie
pc2
e, quando o stream depc1
for adicionado, mostre-o em um elemento de vídeo:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
API RTCPeerConnection
mais servidores
No mundo real, o WebRTC precisa de servidores, por mais simples que seja, então pode acontecer o seguinte:
- Os usuários se descobrem e trocam detalhes do mundo real, como nomes.
- Apps clientes WebRTC (pares) trocam informações de rede.
- Os pares trocam dados sobre mídia, como formato e resolução do vídeo.
- Os apps cliente WebRTC passam por gateways NAT e firewalls.
Em outras palavras, o WebRTC precisa de quatro tipos de funcionalidade do lado do servidor:
- Descoberta e comunicação de usuários
- Sinalização
- Travessia de NAT/firewall
- Servidores de redirecionamento caso a comunicação ponto a ponto falhe
A travessia de NAT, a rede ponto a ponto e os requisitos para criar um aplicativo de servidor para descoberta e sinalização de usuários estão além do escopo deste artigo. Basta dizer que o protocolo STUN e sua extensão, TURN, são usados pelo framework ICE para permitir que o RTCPeerConnection
lide com a travessia de NAT e outras variações da rede.
A ICE é um framework para conectar pontos, como dois clientes de chat por vídeo. Inicialmente, a ICE tenta conectar pares diretamente com a menor latência possível por UDP. Nesse processo, os servidores STUN têm uma única tarefa: permitir que um terminal atrás de um NAT descubra seu endereço público e porta. Para mais informações sobre o STUN e o TURN, consulte Criar os serviços de back-end necessários para um app WebRTC.
Se o UDP falhar, o ICE tentará usar o TCP. Se a conexão direta falhar, principalmente devido à travessia de NAT empresarial e a firewalls, o ICE usa um servidor TURN intermediário (redirecionamento). Em outras palavras, o ICE primeiro usa o STUN com UDP para conectar pontos diretamente e, em caso de falha, recorre a um servidor de redirecionamento TURN. A expressão encontrar candidatos refere-se ao processo de encontrar interfaces e portas de rede.
O engenheiro do WebRTC Justin Uberti fornece mais informações sobre ICE, STUN e TURN na apresentação WebRTC do Google I/O de 2013 (em inglês). Os slides da apresentação mostram exemplos de implementações de servidores TURN e STUN.
Um cliente simples de chat por vídeo
Um bom lugar para testar o WebRTC, completo com sinalização e travessia de NAT/firewall usando um servidor STUN, é a demonstração de chat por vídeo em appr.tc. Esse app usa o adapter.js, um paliativo para isolar apps de mudanças de especificações e diferenças de prefixo.
O registro do código é deliberadamente detalhado. Verifique o console para entender a ordem dos eventos. Confira a seguir um tutorial detalhado do código.
Topologias de rede
O WebRTC, atualmente implementado, só oferece suporte à comunicação um para um, mas pode ser usado em cenários de rede mais complexos, como quando vários pares se comunicam diretamente entre si ou por uma unidade de controle multiponto (MCU, na sigla em inglês), um servidor que pode lidar com um grande número de participantes e fazer o encaminhamento seletivo de stream, além de misturar ou gravar áudio e vídeo.
Muitos aplicativos WebRTC existentes demonstram apenas a comunicação entre navegadores da Web, mas os servidores de gateway podem permitir que um aplicativo WebRTC em execução em um navegador interaja com dispositivos, como telefones (também conhecidos como RPTC) e com sistemas VOIP. Em maio de 2012, a Doubango Telecom abriu o código do cliente SIP SIP5 criado com WebRTC e WebSocket, que (entre outros possíveis usos) permite videochamadas entre navegadores e apps em execução no iOS e no Android. No Google I/O, a Tethr e a Tropo demonstraram um framework para comunicações de desastres em uma pasta usando uma célula OpenBTS para possibilitar a comunicação entre feature phone e computadores pelo WebRTC. Comunicação telefônica sem operadora!
API RTCDataChannel
<
Assim como áudio e vídeo, o WebRTC suporta comunicação em tempo real para outros tipos de dados.
A API RTCDataChannel
permite a troca ponto a ponto de dados arbitrários com baixa latência e alta capacidade. Para ver demonstrações de uma única página e aprender a criar um app simples de transferência de arquivos, consulte os exemplos de WebRTC e o codelab de WebRTC, respectivamente.
Existem muitos casos de uso potenciais para a API, incluindo:
- Jogos
- Apps da Área de trabalho remota
- Bate-papo por texto em tempo real
- Transferência de arquivo
- Redes descentralizadas
A API tem vários recursos para aproveitar ao máximo o RTCPeerConnection
e possibilitar a comunicação ponto a ponto avançada e flexível:
- Uso da configuração de sessão de
RTCPeerConnection
- Vários canais simultâneos com priorização
- Semântica de entrega confiável e não confiável
- Segurança integrada (DTLS) e controle de congestionamento
- Uso com ou sem áudio ou vídeo
A sintaxe é deliberadamente semelhante à WebSocket, com um método send()
e um 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);
};
A comunicação ocorre diretamente entre os navegadores, de modo que o RTCDataChannel
pode ser muito mais rápido que o WebSocket, mesmo que um servidor de redirecionamento (TURN) seja necessário quando a furação para lidar com firewalls e NATs falhar.
O RTCDataChannel
está disponível para Chrome, Safari, Firefox, Opera e Samsung Internet. O jogo Cube Slam usa a API para comunicar o estado do jogo. Jogue com um amigo ou com o urso! A plataforma inovadora Sharefest permitiu o compartilhamento de arquivos por RTCDataChannel
e peerCDN, deu uma ideia de como o WebRTC poderia permitir a distribuição de conteúdo ponto a ponto.
Para mais informações sobre o RTCDataChannel
, confira a especificação do protocolo de rascunho (em inglês) do IETF.
Segurança
Um app ou plug-in de comunicação em tempo real pode comprometer a segurança de várias maneiras. Exemplo:
- Mídias ou dados não criptografados podem ser interceptados entre navegadores ou entre um navegador e um servidor.
- Um app pode gravar e distribuir vídeo ou áudio sem que o usuário saiba.
- Malware ou vírus podem ser instalados junto com um plug-in ou app aparentemente inofensivo.
O WebRTC tem vários recursos para evitar esses problemas:
- As implementações WebRTC usam protocolos seguros, como DTLS e SRTP.
- A criptografia é obrigatória para todos os componentes WebRTC, incluindo mecanismos de sinalização.
- WebRTC não é um plug-in. Os componentes dele são executados na sandbox do navegador e não em um processo separado. Os componentes não exigem instalação separada e são atualizados sempre que o navegador é atualizado.
- O acesso à câmera e ao microfone precisa ser concedido explicitamente e, quando a câmera ou o microfone estão em execução, isso é claramente mostrado pela interface do usuário.
Uma discussão completa sobre segurança para streaming de mídia está fora do escopo deste artigo. Para mais informações, consulte a Arquitetura de segurança WebRTC proposta proposta pelo IETF.
Conclusão
As APIs e os padrões do WebRTC podem democratizar e descentralizar ferramentas para criação e comunicação de conteúdo, incluindo telefonia, jogos, produção de vídeo, criação de músicas e coleta de notícias.
A tecnologia não é muito mais disruptiva do que isso.
Como afirmou o blogueiro Phil Edholm, "Potencialmente, o WebRTC e o HTML5 poderiam permitir a mesma transformação para comunicação em tempo real que o navegador original fazia para informações".
Ferramentas para desenvolvedores
- As estatísticas do WebRTC para uma sessão em andamento podem ser encontradas em:
- about://webrtc-internals no Chrome
- opera://webrtc-internals no Opera
- about:webrtc no Firefox
- Observações sobre a interoperabilidade em vários navegadores
- adapter.js é um paliativo JavaScript para WebRTC mantido pelo Google com a ajuda da comunidade WebRTC que abstrai os prefixos do fornecedor, diferenças de navegador e alterações de especificações.
- Para saber mais sobre os processos de sinalização do WebRTC, verifique a saída do registro appr.tc no console.
- Se for tudo, você pode usar uma estrutura WebRTC ou até mesmo um serviço WebRTC completo.
- Relatórios de bugs e solicitações de recursos são sempre bem-vindos:
Saiba mais
- Sessão WebRTC de Justin Uberti no Google I/O 2012
- Alan B. Johnston e Daniel C. Burnett mantém um livro WebRTC agora na terceira edição em formatos impressos e de e-books em webrtcbook.com.
- O webrtc.org (link em inglês) abriga tudo sobre WebRTC, inclusive demonstrações, documentação e discussões.
- discuss-webrtc é um Grupo do Google para discussões técnicas sobre WebRTC.
- @webrtc (link em inglês)
- A documentação do Google Talk para desenvolvedores fornece mais informações sobre travessia de NAT, STUN, servidores de redirecionamento e coleta de candidatos.
- WebRTC no GitHub
- O Stack Overflow é um bom lugar para procurar respostas e fazer perguntas sobre o WebRTC.
Padrões e protocolos
- Rascunho do editor do WebRTC W3C
- Rascunho do editor do W3C: captura e streams de mídia (também conhecido como
getUserMedia
) - Termo do Grupo de Trabalho da IETF (em inglês)
- Rascunho do protocolo de canal de dados WebRTC do IETF
- Rascunho do IETF JSEP
- Padrão proposto pela IETF para a ICE
- Rascunho da Internet do grupo de trabalho do IETF RTCWEB: casos de uso e requisitos de comunicação em tempo real na Web
Resumo do suporte WebRTC
APIs MediaStream
e getUserMedia
- Chrome para computador 18.0.1008 e superior; Chrome para Android 29 e superior
- Opera 18 e mais recentes; Opera para Android 20 e versões mais recentes
- Opera 12, Opera Mobile 12 (com base no mecanismo Presto)
- Firefox 17 e mais recentes
- Microsoft Edge 16 e versões mais recentes
- Safari 11.2 e mais recente no iOS e 11.1 e mais recente no MacOS
- UC 11.8 e versões mais recentes no Android
- Samsung Internet 4 ou superior
API RTCPeerConnection
.
- Chrome para computador 20 e superior; Chrome para Android 29 e superior (sem sinalização)
- Opera 18 e mais recentes (ativado por padrão); Opera para Android 20 e mais recentes (ativado por padrão)
- Firefox 22 e mais recentes (ativado por padrão)
- Microsoft Edge 16 e versões mais recentes
- Safari 11.2 e mais recente no iOS e 11.1 e mais recente no MacOS
- Samsung Internet 4 ou superior
API RTCDataChannel
.
- Versão experimental no Chrome 25, mas mais estável (e com interoperabilidade com o Firefox) no Chrome 26 e superior; Chrome para Android 29 e superior
- Versão estável (com interoperabilidade com o Firefox) no Opera 18 e mais recentes; Opera para Android 20 e mais recentes
- Firefox 22 e mais recentes (ativado por padrão)
Para informações mais detalhadas sobre o suporte multiplataforma para APIs, como getUserMedia
e RTCPeerConnection
, consulte caniuse.com (em inglês) e Status da plataforma do Chrome.
As APIs nativas para RTCPeerConnection
também estão disponíveis na documentação em webrtc.org (em inglês).