O que você vai aprender:
Nessa etapa você descobrirá como:
- Abstrair as diferenças dos navegadores com o WebRTC , usando o adapter.js.
- Usar a API RTCPeerConnection para transmissão de vídeo.
- Captura de mídia de controle e transmissão.
Uma versão completa dessa etapa está na pasta step-2.
O que é o RTCPeerConnection?
O RTCPeerConnection é uma API para fazer chamadas WebRTC para transmitir vídeo, áudio, e trocar dados.
Esse exemplo configura uma conexão entre dois objetos RTCPeerConnection (conhecidos como pontos) na mesma página.
Não há muito uso prático, mas é bom para entender como o RTCPerrConnection funciona.
Adicione elementos de vídeo e botões de controle.
Em index.html, substitua o elemento de vídeo único por dois elementos de vídeo e três botões:
<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<div>
<button id="startButton">Start</button>
<button id="callButton">Call</button>
<button id="hangupButton">Hang Up</button>
</div>
Um elemento de vídeo exibirá o fluxo degetUserMedia()e o outro mostrará o mesmo vídeo transmitido pelo RTCPeerconnection. (Em uma aplicação do mundo real, um elemento de vídeo seria a exibição da transmissão local e outro a transmissão remota).
Adicionando o adapter.js
Adicionando o adaptador de navegadores
Adicione um link da versão atual do adapter.js acima do link do main.js:
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Realtime communication with WebRTC</title>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<h1>Realtime communication with WebRTC</h1>
<video id="localVideo" autoplay playsinline></video>
<video id="remoteVideo" autoplay playsinline></video>
<div>
<button id="startButton">Start</button>
<button id="callButton">Call</button>
<button id="hangupButton">Hang Up</button>
</div>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="js/main.js"></script>
</body>
</html>
Instalar o código RTCPeerConnection
Substitua o main.js com a versão da pasta step-02.
Faça a chamada
Abra o index.html, clique no botão Start para obter o vídeo de sua webcam, e clique em chamada para fazer a conexão de ponto. Você deve ver o mesmo vídeo (de sua webcam) em ambos elementos de vídeo. Visualize o console do navegador para ver o log do WebRTC.
Como funciona
Esta etapa faz uma divisão…
Se você quiser pular a explicação abaixo, está bem. Você ainda pode continuar o codelab!
O WebRTC usa a API RTCPeerConnection para configurar uma conexão para transmitir vídeo entre clientes WebRTC, conhecidos como pontos.
Nesse exemplo, os dois objetos RTCPerrConnection estão na mesma página: pc1 e pc2. Não é muito pratico, mas é bom para demonstrar como as APIs funcionam.
Configurando uma chamada entre pontos do WebRTC envolve três tarefas:
- Crie um RTCPeerConnection para cada final da chamada e, em cada extremidade, adicione a transmissão local de
getUserMedia(). - Obtenha e compartilhe informações de rede: os pontos de extremidade de conexão em potencial são conhecidos como candidatos ICE.
- Obtenha e compartilhe descrições locais e remotas metadados sobre mídia local no formato SDP.
Imagine que Alice e Bob desejem usar o RTCPeerConnection para configurar um bate-papo por vídeo.
Primeiro, Alice e Bob trocam informações de rede. A expressão ‘encontrar candidatos’ refere-se ao processo de localizar interfaces de rede e portas usando a estrutura do ICE .
- Alice cria um objeto RTCPeerConnection com um manipulador
onicecandidate (addEventListener('icecandidate')). Isto corresponde ao código a seguir de main.js :
let localPeerConnection;
localPeerConnection = new RTCPeerConnection(servers);
localPeerConnection.addEventListener('icecandidate', handleConnection);
localPeerConnection.addEventListener(
'iceconnectionstatechange', handleConnectionChange);
- Alice chama o
getUserMedia()e adiciona a transmissão passada para isso:
navigator.mediaDevices.getUserMedia(mediaStreamConstraints).
then(gotLocalMediaStream).
catch(handleLocalMediaStreamError);
function gotLocalMediaStream(mediaStream) {
localVideo.srcObject = mediaStream;
localStream = mediaStream;
trace('Received local stream.');
callButton.disabled = false; // Enable call button.
}
localPeerConnection.addStream(localStream);
trace('Added local stream to localPeerConnection.');
- O manipulador
onicecandidateda etapa 1. é chamado quando os candidatos da rede se tornam disponíveis. - Alice envia dados serializados para o candidato Bob. Em uma aplicação real, o processo (conhecido como sinalização) ocorre através de um serviço de mensagens – você aprenderá como fazer isso em uma etapa posterior. Claro, nessa etapa, os dois objetos RTCPeerConnection estão na mesma página e podem se comunicar diretamente sem a necessidade de mensagens externas.
- Quando Bob obtêm uma mensagem do candidato Alice, ele chama
addIceCandidate(), para adicionar o candidato à descrição do ponto remoto:
function handleConnection(event) {
const peerConnection = event.target;
const iceCandidate = event.candidate;
if (iceCandidate) {
const newIceCandidate = new RTCIceCandidate(iceCandidate);
const otherPeer = getOtherPeer(peerConnection);
otherPeer.addIceCandidate(newIceCandidate)
.then(() => {
handleConnectionSuccess(peerConnection);
}).catch((error) => {
handleConnectionFailure(peerConnection, error);
});
trace(`${getPeerName(peerConnection)} ICE candidate:\n` +
`${event.candidate.candidate}.`);
}
}
Os pontos WebRTC também precisam descobrir e trocar informações de mídia áudio e vídeo locais e remotas, tal como capacidades de resolução e codec. A sinalização para trocar informações de configuração de mídia prossegue trocando blobs de metadados, conhecidos como uma oferta e uma resposta, usando o formato do Protocolo de Descrição de Sessão, conhecido como SDP:
- Alice executa o método
createOffer()do RTCPeerConnection.A promessa retornada fornece um RTCSessionDescription: Descrição da sessão local de Alice:
trace('localPeerConnection createOffer start.');
localPeerConnection.createOffer(offerOptions)
.then(createdOffer).catch(setSessionDescriptionError);
- Se bem-sucedido, Alice define a descrição local usando
setLocalDescription()e em seguida, envia esta descrição da sessão para Bob através do seu canal de sinalização. - Bob define a descrição que Alice lhe envio como uma descrição remota usando
setRemoteDescription(). - Bob executa o método
createAnswer()do RTCPeerConnection, passando a descrição remota que ele recebeu de Alice, para que possa ser gerada uma sessão local compatível com a dela. A promessacreateAnswer()transmite uma RTCSessionDescription: Bob define isso como a descrição local e envia para Alice. - Quando Alice recebe a descrição da sessão de Bob, ela define isso como uma descrição remota com
setRemoteDescription().
// Logs offer creation and sets peer connection session descriptions.
function createdOffer(description) {
trace(`Offer from localPeerConnection:\n${description.sdp}`);
trace('localPeerConnection setLocalDescription start.');
localPeerConnection.setLocalDescription(description)
.then(() => {
setLocalDescriptionSuccess(localPeerConnection);
}).catch(setSessionDescriptionError);
trace('remotePeerConnection setRemoteDescription start.');
remotePeerConnection.setRemoteDescription(description)
.then(() => {
setRemoteDescriptionSuccess(remotePeerConnection);
}).catch(setSessionDescriptionError);
trace('remotePeerConnection createAnswer start.');
remotePeerConnection.createAnswer()
.then(createdAnswer)
.catch(setSessionDescriptionError);
}
// Logs answer to offer creation and sets peer connection session descriptions.
function createdAnswer(description) {
trace(`Answer from remotePeerConnection:\n${description.sdp}.`);
trace('remotePeerConnection setLocalDescription start.');
remotePeerConnection.setLocalDescription(description)
.then(() => {
setLocalDescriptionSuccess(remotePeerConnection);
}).catch(setSessionDescriptionError);
trace('localPeerConnection setRemoteDescription start.');
localPeerConnection.setRemoteDescription(description)
.then(() => {
setRemoteDescriptionSuccess(localPeerConnection);
}).catch(setSessionDescriptionError);
}
- Ping!
Pontos Bônus
- Observe o chrome://webrtc-internals. Isto fornece os status e a depuração de dados do WebRTC . (Uma lista completa das URLs do Chrome está em chrome://about.)
- Estilize a página com CSS:
- Coloque os vídeos lado a lado.
- Faça os botões da mesma largura, com texto maior.
- Verifique se o layout funciona no celular.
- No console do Chrome Dev Tools, procure por
localStream,localPeerConnectioneremotePeerConnection. - No console, procure por
localPeerConnectionpc1.localDescription. Como é o formato SDP ?
O que você aprendeu
Nessa etapa você aprendeu como:
- Adaptar diferentes navegadores com o calço WebRTC, adapter.js.
- Usar a API RTCPeerConnection para transmitir vídeo.
- Controle de captura e transmissão de mídia.
- Compartilhar mídia e informações de rede entre os pontos para ativar uma chamada do WebRTC.
Uma versão completa dessa etapa está na pasta step-2.
Dicas
- Há muito o que aprender nesta etapa! Para encontrar outros recursos que expliquem o RTCPeerConnection em mais detalhes, consulte webrtc.org/start. Esta página inclui sugestões para estruturas de JavaScript – se você quiser usar o WebRTC, mas não quer organizar as APIs.
- Encontre mais sobre o calço adapter.js em adapter.js GitHub repo.
- Quer ver como é o melhor aplicativo de bate-papo por vídeo do mundo? Dê uma olhada no AppRTC, o aplicativo canônico do projeto WebRTC para chamadas do WebRTC: app, code. O tempo de configuração da chamada é inferior a 500 ms.
Boas praticas
- Para preparar seu código para o futuro, use as novas APIs baseadas no Promise e ative a compatibilidade com os navegadores que não os suportam usando o adapter.js.
Próximo
Esta etapa mostra como usar o WebRTC para transmitir vídeo entre pontos — mas este codelab também é sobre dados!
Na próxima etapa, descubra como transmitir dados arbitrários usando RTCDataChannel.
Referência:
Conteúdo traduzido do site : https://codelabs.developers.google.com/codelabs/webrtc-web/#4