Transmissão de vídeo com RTCPeerConnection

event 17 de setembro de 2018 às 4:37 am

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 .

  1. 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);
  1. 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.');
  1. O manipulador onicecandidate da etapa 1. é chamado quando os candidatos da rede se tornam disponíveis.
  2. 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.
  3. 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:

  1. 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);
  1. 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.
  2. Bob define a descrição que Alice lhe envio como uma descrição remota usando  setRemoteDescription().
  3. 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 promessa createAnswer() transmite uma RTCSessionDescription: Bob define isso como a descrição local e envia para Alice.
  4.  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);
}
  1. Ping!

Pontos Bônus

  1. 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.)
  2. 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.
  1. No console do Chrome Dev Tools, procure por localStreamlocalPeerConnection e remotePeerConnection.
  2. 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: appcode. 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

Deixe uma resposta

Formulário Respondeu!