O WebRTC é uma nova frente na longa guerra por uma Web aberta e sem entraves.
Brendan Eich, inventor do JavaScript
Comunicação em tempo real sem plug-ins
Imagine um mundo em que seu smartphone, TV e computador pudessem se comunicar em uma plataforma comum. Imagine que é fácil adicionar chat por vídeo e 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 em computadores e dispositivos móveis no Google Chrome, Safari, Firefox e Opera. Um bom lugar para começar é o app de chat por vídeo simples em appr.tc:
- Abra appr.tc no navegador.
- Clique em Participar para entrar em uma sala de chat e permitir que o app use sua webcam.
- Abra o URL exibido no final da página em uma nova guia ou, melhor ainda, em um computador diferente.
Início rápido
Não tem tempo para ler este artigo ou só quer o código?
- Para ter uma visão geral do WebRTC, assista o vídeo do Google I/O a seguir ou confira estes slides:
- Se você não usou a API
getUserMedia
, consulte Capturar áudio e vídeo no 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 NAT e firewall, consulte o código e os registros do console em appr.tc.
- Não quer esperar e quer testar o WebRTC agora mesmo? Teste algumas das mais de 20 demonstrações que usam as APIs JavaScript do WebRTC.
- Está com problemas com a máquina e o WebRTC? Acesse o Solucionador de problemas do WebRTC.
Como alternativa, acesse diretamente o codelab do WebRTC, um guia detalhado que explica como criar um app de chat por vídeo completo, incluindo um servidor de sinalização simples.
Uma breve história do WebRTC
Um dos últimos grandes desafios da Web é permitir a comunicação humana por voz e vídeo: comunicação em tempo real ou RTC, na sigla em inglês. O RTC precisa ser tão natural em um app da Web quanto digitar texto em uma entrada de texto. Sem ela, sua capacidade de inovar e desenvolver novas maneiras de interação das pessoas é limitada.
Historicamente, o RTC era corporativo e complexo, exigindo que tecnologias de áudio e vídeo caras fossem licenciadas ou desenvolvidas internamente. A integração da tecnologia RTC com conteúdo, dados e serviços existentes tem sido difícil e demorado, principalmente na Web.
O chat 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 a GIPS, uma empresa que desenvolveu muitos componentes necessários para o RTC, como codecs e técnicas de cancelamento de eco. O Google disponibilizou em código aberto as tecnologias desenvolvidas pelo GIPS e se envolveu com os órgãos de padrões relevantes do 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, apps nativos ou plug-ins. Isso incluiu o Skype, o Facebook e o Hangouts.
- Fazer o download, instalar e atualizar plug-ins é um processo complexo, propenso a erros e irritante.
- Os plug-ins são difíceis de implantar, depurar, resolver problemas, testar e manter e podem exigir licenciamento e integração com tecnologias complexas e caras. Muitas vezes, é difícil convencer as pessoas a instalar plugins.
Os princípios orientadores do projeto WebRTC são que as APIs precisam ser de código aberto, sem custo financeiro, padronizadas, integradas a navegadores da Web e mais eficientes do que as tecnologias atuais.
Onde estamos agora?
O WebRTC é usado em vários apps, como o Google Meet. O WebRTC também foi integrado ao WebKitGTK+ e a apps nativos do Qt.
O WebRTC implementa estas três APIs:
- MediaStream
(também conhecida como getUserMedia
)
- RTCPeerConnection
- RTCDataChannel
As APIs são definidas nestas duas especificações:
Todas as três APIs têm suporte para dispositivos móveis e computadores com Chrome, Safari, Firefox, Edge e Opera.
getUserMedia
: para demonstrações e código, consulte Exemplos do WebRTC ou confira os exemplos incríveis de Chris Wilson que usam getUserMedia
como entrada para áudio da Web.
RTCPeerConnection
: para conferir uma demonstração simples e um app de chat por vídeo totalmente funcional, consulte Exemplos de conexão entre pares do WebRTC e appr.tc, respectivamente. Esse app usa o adapter.js, um paliativo JavaScript mantido pelo Google com a ajuda da comunidade do WebRTC para abstrair as diferenças entre navegadores e mudanças de especificação.
RTCDataChannel
: para conferir isso em ação, consulte Exemplos do WebRTC para conferir uma das demonstrações de canal de dados.
O codelab do WebRTC mostra como usar as três APIs para criar um app simples de chat por vídeo e compartilhamento de arquivos.
Seu primeiro WebRTC
Os apps do WebRTC precisam fazer várias coisas:
- Receber áudio, vídeo ou outros dados por streaming.
- Receber informações de rede, como endereços IP e portas, e trocá-las com outros clientes do WebRTC (conhecidos como peers) para permitir a conexão, mesmo por NATs e firewalls.
- coordenar a comunicação de sinalização para informar erros e iniciar ou encerrar sessões.
- Troca de informações sobre mídia e recursos do cliente, como resolução e codecs.
- Transmitir áudio, vídeo ou dados.
Para adquirir e comunicar dados de streaming, o WebRTC implementa as seguintes APIs:
MediaStream
tem acesso a fluxos de dados, como da câmera e do microfone do usuário.RTCPeerConnection
ativa chamadas de áudio ou vídeo com recursos de criptografia e gerenciamento de largura de banda.RTCDataChannel
permite a comunicação ponto a ponto de dados genéricos.
Mais adiante, vamos discutir em detalhes os aspectos de rede e sinalização do WebRTC.
API MediaStream
(também conhecida como API getUserMedia
)
A API MediaStream
representa streams de mídia sincronizados. Por exemplo, um stream feito a partir da entrada da câmera e do microfone tem faixas de vídeo e áudio sincronizadas. Não confunda MediaStreamTrack
com o elemento <track>
, que é completamente diferente.
A maneira mais fácil de entender a API MediaStream
é analisando-a em ação:
- No navegador, acesse Exemplos do 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 uma RTCPeerConnection
.
O método getUserMedia()
usa um parâmetro de objeto MediaStreamConstraints
e retorna um Promise
que é resolvido como um objeto MediaStream
.
Cada MediaStream
tem um label
, como 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. Uma matriz de MediaStreamTrack
s é retornada pelos métodos getAudioTracks()
e getVideoTracks()
.
No exemplo 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 um MediaStreamTrack
que representa o stream 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 transmissões da câmera frontal, da câmera traseira, do microfone e um app que compartilha a tela.
Um MediaStream
pode ser anexado a um elemento de vídeo definindo o atributo srcObject
. Antes, isso era feito definindo o atributo src
como um URL de objeto criado com URL.createObjectURL()
, mas essa prática foi descontinuada.
O 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);
});
As extensões e os apps baseados no Chromium também podem incorporar getUserMedia
. Adicionar as permissões audioCapture
e/ou videoCapture
ao manifesto permite que a permissão seja solicitada e concedida apenas uma vez durante a instalação. Depois disso, a permissão para acessar a câmera ou o microfone não é solicitada ao usuário.
A permissão só precisa ser concedida uma vez para getUserMedia()
. Na primeira vez, um botão "Permitir" é exibido na infobar do navegador. O acesso HTTP para getUserMedia()
foi descontinuado pelo Chrome no final de 2015 porque foi classificado como um recurso poderoso.
A intenção é ativar um MediaStream
para qualquer fonte de dados de streaming, não apenas uma câmera ou um microfone. Isso permitiria o streaming de dados armazenados ou fontes de dados arbitrárias, como sensores ou outras entradas.
A getUserMedia()
ganha vida em combinação com outras APIs e bibliotecas JavaScript:
- O Webcam Toy é um app de cabine fotográfica que usa o WebGL para adicionar efeitos estranhos e incríveis a fotos que podem ser compartilhadas ou salvas localmente.
- FaceKat é um jogo de rastreamento facial criado com headtrackr.js.
- A ASCII Camera usa a API Canvas para gerar imagens ASCII.
Restrições
As 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 de orientação (câmera frontal ou traseira), frame rate, altura e largura e um método applyConstraints()
.
Para conferir um exemplo, consulte Exemplos de WebRTC getUserMedia
: selecione a resolução.
A definição de um valor de restrição não permitido gera uma DOMException
ou uma OverconstrainedError
se, por exemplo, uma resolução solicitada não estiver disponível. Para conferir isso em ação, consulte Exemplos de WebRTC getUserMedia
: selecione a resolução para conferir 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 o WebRTC. O artigo tem alguns anos, mas ainda é interessante.)
Também é possível usar a captura de tela como uma origem de MediaStream
no Chrome usando a restrição experimental chromeMediaSource
. A captura de tela exige HTTPS e só deve ser usada para desenvolvimento, porque é ativada por uma flag de linha de comando, conforme explicado neste post.
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 apps do WebRTC podem escolher o protocolo de mensagens de preferência, como SIP ou XMPP, e qualquer canal de comunicação duplex (bidirecional) adequado. O exemplo appr.tc usa XHR e a API Channel como mecanismo de sinalização. O codelab usa o Socket.io em execução em um servidor do Node.
A sinalização é usada para trocar três tipos de informações:
- Mensagens de controle de sessão: para inicializar ou encerrar a comunicação e informar erros.
- Configuração de rede: qual é o endereço IP e a porta do seu computador para o mundo externo?
- Recursos de mídia: quais codecs e resoluções podem ser processados pelo seu navegador e pelo navegador com que ele quer se comunicar?
A troca de informações por sinalização precisa ser concluída antes que o streaming ponto a ponto possa começar.
Por exemplo, imagine que Alice quer se comunicar com Bob. Confira um exemplo de código da especificação do WebRTC do W3C, 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()
. Além disso, no Chrome e no Opera, RTCPeerConnection
tem um prefixo.
// 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 Bob trocam informações de rede. A expressão encontrar candidatos se refere ao processo de encontrar interfaces de rede e portas usando a estrutura ICE.
- Alice cria um objeto
RTCPeerConnection
com um gerenciadoronicecandidate
, que é executado quando os candidatos de rede ficam disponíveis. - Alice envia dados candidatos serializados para Bob por qualquer canal de sinalização que esteja usando, como WebSocket ou outro mecanismo.
- Quando Bob recebe uma mensagem de candidato de Alice, ele chama
addIceCandidate
para adicionar o candidato à descrição do peer remoto.
Os clientes do WebRTC (também conhecidos como pares, ou Alice e Bob neste exemplo) também precisam determinar e trocar informações de mídia de áudio e vídeo locais e remotas, como resolução e recursos de codec. A sinalização para trocar informações de configuração de mídia é feita trocando uma oferta e uma resposta usando o Protocolo de Descrição de Sessão (SDP):
- Alice executa o método
createOffer()
RTCPeerConnection
. O retorno é transmitido a umRTCSessionDescription
, a descrição da sessão local de Alice. - No callback, Alice define a descrição local usando
setLocalDescription()
e envia essa descrição de sessão para Bob pelo canal de sinalização.RTCPeerConnection
não vai começar a coletar candidatos até quesetLocalDescription()
seja chamado. Isso está codificado no rascunho do JSEP IETF. - Bob define a descrição que Alice enviou a ele como a descrição remota usando
setRemoteDescription()
. - Bob executa o método
createAnswer()
RTCPeerConnection
, transmitindo a descrição remota que ele recebeu de Alice para que uma sessão local possa ser gerada e 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 de sessão (SDP). Um objeto SDP serializado tem esta 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 pares possa começar.
A arquitetura de oferta/resposta descrita anteriormente é chamada de protocolo de estabelecimento de sessão JavaScript (JSEP, na sigla em inglês). Há uma animação excelente explicando o processo de sinalização e streaming no vídeo de demonstração da Ericsson para a primeira implementação do WebRTC.
Depois que o processo de sinalização for concluído, os dados poderão ser transmitidos diretamente de um peer para outro, entre o autor da chamada e o destinatário, ou, se isso falhar, por um servidor de retransmissão intermediário (mais detalhes a seguir). O streaming é o trabalho de RTCPeerConnection
.
RTCPeerConnection
RTCPeerConnection
é o componente do WebRTC que processa a comunicação estável e eficiente de dados de streaming entre pares.
Confira a seguir um diagrama de arquitetura do WebRTC que mostra a função de RTCPeerConnection
. As partes verdes são complexas.
Do ponto de vista do JavaScript, a principal coisa a entender neste diagrama é que 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 trabalho enorme para tornar possível a comunicação em tempo real, mesmo em redes não confiáveis:
- Ocultar perda de pacotes
- Cancelamento de eco
- Adaptabilidade de largura de banda
- Armazenamento em buffer de instabilidade dinâmica
- Controle automático de ganho
- Redução e supressão de ruído
- Limpeza de imagem
O código anterior do W3C mostra um exemplo simplificado do WebRTC do ponto de vista da sinalização. Confira a seguir os tutoriais de dois apps WebRTC em funcionamento. 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 é retirado de Exemplos de conexão de peer do WebRTC, que tem RTCPeerConnection
e remoto local (e vídeo local e remoto) em uma página da Web. Isso não é muito útil, porque o autor da chamada e o chamado estão na mesma página, mas torna 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 peer local (autor da chamada) e pc2
representa o peer remoto (destinatário).
Autor da chamada
- Crie um novo
RTCPeerConnection
e adicione a transmissão degetUserMedia()
: ```js // Servers é um arquivo de configuração opcional. (Consulte a discussão sobre TURN e STUN mais adiante.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((track) => { pc1.addTrack(track, localStream); });
- Crie uma oferta e defina-a como a descrição local de
pc1
e a descrição remota depc2
. Isso pode ser feito diretamente no código sem usar sinalização, porque o autor da chamada e o destinatário 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 );
Chamada
- Crie
pc2
e, quando a transmissão depc1
for adicionada, mostre-a em um elemento de vídeo:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
RTCPeerConnection
API plus servidores
No mundo real, o WebRTC precisa de servidores, por mais simples que sejam, para que o seguinte possa acontecer:
- Os usuários se descobrem e trocam detalhes reais, como nomes.
- Os apps clientes do WebRTC (peers) trocam informações de rede.
- Os pares trocam dados sobre mídia, como formato e resolução de vídeo.
- Os apps clientes do WebRTC atravessam gateways NAT e firewalls.
Em outras palavras, o WebRTC precisa de quatro tipos de funcionalidade no servidor:
- Descoberta e comunicação de usuários
- Sinalização
- Travessia de NAT/firewall
- Redirecionar servidores em caso de falha na comunicação ponto a ponto
A travessia de NAT, a rede ponto a ponto e os requisitos para criar um app de servidor para descoberta e sinalização de usuários estão fora do escopo deste artigo. Basta dizer que o protocolo STUN e a extensão TURN são usados pelo framework ICE para permitir que RTCPeerConnection
lide com a travessia de NAT e outras variações de rede.
O ICE é um framework para conectar pares, como dois clientes de chat por vídeo. Inicialmente, o ICE tenta conectar pares diretamente com a menor latência possível pelo UDP. Nesse processo, os servidores STUN têm uma única tarefa: permitir que um peer atrás de um NAT descubra o endereço e a porta públicos. Para mais informações sobre STUN e TURN, consulte Criar os serviços de back-end necessários para um app WebRTC.
Se o UDP falhar, o ICE vai tentar o TCP. Se a conexão direta falhar, principalmente devido a travessias NAT corporativas e firewalls, o ICE vai usar um servidor TURN intermediário (relay). Em outras palavras, o ICE primeiro usa o STUN com UDP para conectar pares diretamente e, se isso falhar, volta para um servidor de retransmissão TURN. A expressão encontrar candidatos se refere 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 do WebRTC do Google I/O de 2013. 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 experimentar o WebRTC, 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 adapter.js, um paliativo para isolar apps de mudanças de especificação e diferenças de prefixo.
O código é deliberadamente detalhado no registro. Verifique o console para entender a ordem dos eventos. Confira a seguir um tutorial detalhado do código.
Topologias de rede
O WebRTC, conforme implementado atualmente, oferece suporte apenas à comunicação individual, mas pode ser usado em cenários de rede mais complexos, como com vários pares que se comunicam diretamente 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 encaminhamento de transmissão seletivo, além de mixagem ou gravação de áudio e vídeo.
Muitos apps WebRTC existentes demonstram apenas a comunicação entre navegadores da Web, mas os servidores de gateway podem permitir que um app WebRTC em execução em um navegador interaja com dispositivos, como telefones (também conhecidos como PSTN) e com sistemas VOIP. Em maio de 2012, a Doubango Telecom disponibilizou o cliente SIP sipml5 (em inglês) de código aberto, criado com WebRTC e WebSocket. Entre outros usos, ele permite fazer chamadas de vídeo entre navegadores e apps executados no iOS e no Android. No Google I/O, a Tethr e a Tropo demonstraram um framework para comunicações em caso de desastres em uma pasta usando uma célula OpenBTS para permitir a comunicação entre feature phones e computadores pelo WebRTC. Comunicação telefônica sem operadora
API RTCDataChannel
<
Além de áudio e vídeo, o WebRTC oferece suporte à 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 alto rendimento. Para demonstrações de uma página e para saber como criar um app simples de transferência de arquivos, consulte os exemplos do WebRTC e o codelab do WebRTC, respectivamente.
Há muitos casos de uso em potencial para a API, incluindo:
- Jogos
- Apps de área de trabalho remota
- Chat de texto em tempo real
- Transferência de arquivo
- Redes descentralizadas
A API tem vários recursos para aproveitar ao máximo o RTCPeerConnection
e permitir uma comunicação ponto a ponto poderosa e flexível:
- Como aproveitar a configuração da sessão
RTCPeerConnection
- Vários canais simultâneos com priorização
- Semântica de entrega confiável e não confiável
- Controle de congestionamento e segurança integrada (DTLS)
- Possibilidade de uso com ou sem áudio ou vídeo
A sintaxe é deliberadamente semelhante ao 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. Portanto, o RTCDataChannel
pode ser muito mais rápido que o WebSocket, mesmo que um servidor de retransmissão (TURN) seja necessário quando a perfuração de buracos falhar para lidar com firewalls e NATs.
O RTCDataChannel
está disponível no Chrome, Safari, Firefox, Opera e Samsung Internet. O jogo Cube Slam usa a API para comunicar o estado do jogo. Escolha um amigo ou o urso! A plataforma inovadora Sharefest permitiu o compartilhamento de arquivos por RTCDataChannel
, e o peerCDN ofereceu um vislumbre de como o WebRTC pode permitir a distribuição de conteúdo ponto a ponto.
Para mais informações sobre RTCDataChannel
, consulte o draft spec do protocolo do IETF.
Segurança
Há várias maneiras de um app ou plug-in de comunicação em tempo real comprometer a segurança. Exemplo:
- Dados ou mídias 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 com um plug-in ou app aparentemente inofensivo.
O WebRTC tem vários recursos para evitar esses problemas:
- As implementações do WebRTC usam protocolos seguros, como DTLS e SRTP.
- A criptografia é obrigatória para todos os componentes do WebRTC, incluindo mecanismos de sinalização.
- O WebRTC não é um plug-in. Os componentes são executados no sandbox do navegador, e não em um processo separado. Os componentes não precisam de 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 é mostrado claramente pela interface do usuário.
Uma discussão completa sobre a segurança de mídia de streaming está fora do escopo deste artigo. Para mais informações, consulte a proposta de arquitetura de segurança do WebRTC (link em inglês) proposta pelo IETF.
Conclusão
As APIs e os padrões do WebRTC podem democratizar e descentralizar ferramentas para criação de conteúdo e comunicação, incluindo telefonia, jogos, produção de vídeos, criação de músicas e coleta de notícias.
A tecnologia não poderia ser mais disruptiva do que isso.
Como o blogueiro Phil Edholm disse, "Em potencial, o WebRTC e o HTML5 podem permitir a mesma transformação para comunicação em tempo real que o navegador original fez 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 entre navegadores
- O adapter.js é um paliativo JavaScript para WebRTC mantido pelo Google com a ajuda da comunidade do WebRTC que abstrai os prefixos do fornecedor, as diferenças de navegador e as mudanças de especificação.
- Para saber mais sobre os processos de sinalização do WebRTC, verifique a saída de registro appr.tc no console.
- Se isso for muito, talvez seja melhor usar um framework do WebRTC ou até mesmo um serviço do WebRTC completo.
- Relatórios de bugs e solicitações de recursos são sempre bem-vindos:
Saiba mais
- Sessão de WebRTC de Justin Uberti no Google I/O 2012
- Alan B. Johnston e Daniel C. Burnett mantém um livro sobre WebRTC, agora na terceira edição, nos formatos impresso e e-book, em webrtcbook.com.
- O webrtc.org é o lar de tudo relacionado ao WebRTC, incluindo demonstrações, documentação e discussões.
- discuss-webrtc é um grupo do Google para discussões técnicas sobre WebRTC.
- @webrtc
- A documentação do Google Developers Talk (em inglês) oferece mais informações sobre a travessia de NAT, STUN, servidores de retransmissão 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
- O rascunho do editor do WebRTC W3C
- W3C Editor's Draft: Media Capture and Streams (também conhecido como
getUserMedia
) - Compromisso do grupo de trabalho do IETF
- Rascunho do protocolo do canal de dados do IETF WebRTC
- IETF JSEP Draft (em inglês)
- Padrão proposto pelo IETF para ICE
- IETF RTCWEB Working Group Internet-Draft: Web Real-Time Communication Use-Cases and Requirements
Resumo de suporte do WebRTC
APIs MediaStream
e getUserMedia
- Chrome para área de trabalho 18.0.1008 e versões mais recentes; Chrome para Android 29 e versões mais recentes
- Opera 18 e versões mais recentes; Opera para Android 20 e versões mais recentes
- Opera 12, Opera Mobile 12 (baseado na Presto)
- Firefox 17 e versões mais recentes
- Microsoft Edge 16 e versões mais recentes
- Safari 11.2 e mais recentes no iOS e 11.1 e mais recentes no MacOS
- UC 11.8 e versões mais recentes no Android
- Samsung Internet 4 e versões mais recentes
API RTCPeerConnection
.
- Chrome para área de trabalho 20 e versões mais recentes; Chrome para Android 29 e versões mais recentes (sem flag)
- Opera 18 e mais recentes (ativado por padrão); Opera para Android 20 e mais recentes (ativado por padrão)
- Firefox 22 e versões mais recentes (ativado por padrão)
- Microsoft Edge 16 e versões mais recentes
- Safari 11.2 e mais recentes no iOS e 11.1 e mais recentes no MacOS
- Samsung Internet 4 e versões mais recentes
API RTCDataChannel
.
- Versão experimental no Chrome 25, mas mais estável (e com interoperabilidade do Firefox) no Chrome 26 e versões mais recentes; Chrome para Android 29 e versões mais recentes
- Versão estável (e com interoperabilidade do Firefox) no Opera 18 e versões mais recentes; Opera para Android 20 e versões mais recentes
- Firefox 22 e versões mais recentes (ativado por padrão)
Para informações mais detalhadas sobre o suporte multiplataforma a APIs, como getUserMedia
e RTCPeerConnection
, consulte caniuse.com e Status da plataforma do Chrome.
As APIs nativas para RTCPeerConnection
também estão disponíveis na documentação em webrtc.org.