Como implementar o compartilhamento de tela no seu app de Vídeo da Twilio

January 28, 2018
Escrito por
Phil Nash
Twilion

Como implementar o compartilhamento de tela no seu app de Vídeo da Twilio

Em posts recentes vimos como gravar a tela de um usuário usando o Chrome e o Firefox. Agora está na hora de combinarmos esta funcionalidade com uma aplicação de videoconferência, agregando o compartilhamento de tela com nosso chat de vídeo.

O que estamos construindo

Neste post, vamos começar pelo quickstart de aplicação de vídeo da Twilio e adicionar o compartilhamento de tela nele. Quando terminarmos, a aplicação vai te permitir fazer chamadas entre navegadores e compartilhar a tela entre eles.

Exemplo do projeto final em execução

Do que você vai precisar

Para construir esta aplicação, você vai precisar de algumas coisas:

Para começar, clone o repositório do GitHub e faça um checkout para o branch build-screen-sharing:

git clone -b building-screen-sharing https://github.com/philnash/screen-capture.git
cd screen-capture

Este repositório é um pouco diferente do repositório do quickstart, ele inclui o trabalho dos últimos dois posts do blog, incluindo a extensão do Chrome necessária para a captura da tela no Chrome. Você pode seguir estas instruções para instalar a extensão do post anterior.

Para preparar o app de chat de vídeo, vá para o diretório vídeo-chat e instale as dependências:

cd video-chat
npm install

Uma vez que fizer isso, adicione algumas credenciais para que possamos nos conectar ao serviço de Vídeo da Twilio. Primeiro, copie o arquivo .env.example para .env. Abra o .env e preencha os detalhes. Você vai precisar da sua conta Twilio Sid do console da Twilio e de uma chave de API e segredo.

Quando terminar, rode:

npm start

Abre http://localhost:3000/ e você deve estar conseguindo colocar o nome de usuário e o nome de uma sala para entrar. Repita o processo em outro navegador e você estará em um chat de vídeo com você mesmo. Se tudo estiver funcionando, você já pode começar a adicionar a funcionalidade de compartilhamento de tela.

Exemplo de dois navegadores conectados na sala de videoconferência e compartilhando a tela.

Adicionando compartilhamento de tela

Para adicionar o compartilhamento de tela, temos algumas tarefas adiante. Primeiro, verifique se o navegador tem suporte para a captura de tela, ou não conseguiremos prosseguir. Depois, quando um usuário quiser compartilhar a tela, precisamos descobrir qual navegador está sendo usado e usar o código dos dois últimos posts para conseguir o stream. Depois adicionamos o stream à sala e finalmente precisamos criar uma maneira de parar o compartilhamento da tela.

Vamos começar.

Verificando suporte

Normalmente, eu gosto de escrever melhorias progressivas, com padrões baseados no JavaScript para detectar funcionalidades como esta. No entanto, como você viu nos posts anteriores, a captura de tela ainda não é padronizada, então vamos precisar um pouco de... “código sugo”.

Suporte para a captura de tela no Firefox é baseado no suporte da restrição da mediaSource na API mediaDevices. Podemos começar os testes com:

!!navigator.mediaDevices.getSupportedConstraints().mediaSource

Esta é uma boa funcionalidade para testar, infelizmente ela não faz todo o trabalho. O Firefox vai reclamar que a mediaSource é suportada desde a versão 33, no entanto este suporte foi limitado para um conjunto pequeno de sites confiáveis. Então, também precisamos verificar se a versão do Firefox que temos é a partir da 52. Podemos ler este dado do agente de usuário com uma expressão regular.

var matchData = navigator.userAgent.match(/Firefox/(d )/);
var firefoxVersion = 0;
if (matchData && matchData[1]) {
  firefoxVersion = parseInt(matchData[1], 10);
}

Abre o arquivo vídeo-chat/src/index.js e adicione no topo a função para testar o suporte do Firefox.

// src/index.js
var roomName;

function isFirefox() {
  var mediaSourceSupport = !!navigator.mediaDevices.getSupportedConstraints().mediaSource;
  var matchData = navigator.userAgent.match(/Firefox/(d )/);
  var firefoxVersion = 0;
  if (matchData && matchData[1]) {
    firefoxVersion = parseInt(matchData[1], 10);
  }
  return mediaSourceSupport && firefoxVersion >= 52;
}

Existem várias maneiras de se detectar se uma extensão do Chrome está instalada, mas isso está fora do escopo deste post. Para o propósito deste post, vou checar se estamos fazendo chamadas ao objeto chrome na window.

  return mediaSourceSupport && firefoxVersion >= 52;
}

function isChrome() {
  return 'chrome' in window;
}

Também precisamos de uma maneira para saber se podemos usar a captura de tela.

  return 'chrome' in window;
}

function canScreenShare() {
  return isFirefox() || isChrome();
}

Pegando a tela do usuário

Usando as funções acima e com o conhecimento dos dois posts anteriores podemos agora pegar a tela do usuário nos navegadores que são suportados. Você vai precisar do ID da sua extensão do Chrome para esta parte. Adicione as seguintes linhas em seu vídeo-chat/src/index.js e substitua o valor da YOUR_EXTENSION_ID com o seu ID:

function getUserScreen() {
  var extensionId = 'YOUR_EXTENSION_ID';
  if (!canScreenShare()) {
    return;
  }
  if (isChrome()) {
    return new Promise((resolve, reject) => {
      const request = {
        sources: ['screen']
      };
      chrome.runtime.sendMessage(extensionId, request, response => {
        if (response && response.type === 'success') {
          resolve({ streamId: response.streamId });
        } else {
          reject(new Error('Could not get stream'));
        }
      });
    }).then(response => {
      return navigator.mediaDevices.getUserMedia({
        video: {
          mandatory: {
            chromeMediaSource: 'desktop',
            chromeMediaSourceId: response.streamId
          }
        }
      });
    });
  } else if (isFirefox()) {
    return navigator.mediaDevices.getUserMedia({
      video: {
        mediaSource: 'screen'
      }
    });
  }
}

Agora podemos usar esta função quando o usuário quiser compartilhar a tela.

Juntando tudo

Para finalizar o código, vamos ligar a interface à função acima. Existe um botão escondido que vai ser ativado quando entrarmos em uma sala. Na função roomJoined já temos alguns botões se escondendo e aparecendo, então adicione o seguinte:

  document.getElementById('button-join').style.display = 'none';
  document.getElementById('button-leave').style.display = 'inline';
  if (canScreenShare()) {
    document.getElementById('button-share-screen').style.display = 'inline';
  }

Abaixo do event handler para o botão de sair da sala, crie handlers para os botões de compartilhar e parar de compartilhar:

    document.getElementById('button-leave').onclick = function() {
      log('Leaving room...');
      activeRoom.disconnect();
    };
    
    document.getElementById('button-share-screen').onclick = function() {
    };

    document.getElementById('button-unshare-screen').onclick = function() {
    };

Dentro do handler do botão de compartilhar, queremos usar nossa função getUserScreen para pegar a stream de mídia da tela do usuário e pegar a trilha de vídeo. Vamos então publicar esta trilha para o localParticipant na sala. Se tudo der certo, vamos mudar a visibilidade de alguns botões.

    document.getElementById('button-share-screen').onclick = function() {
      getUserScreen().then(function(stream) {
        var screenTrack = stream.getVideoTracks()[0];
        activeRoom.localParticipant.publishTrack(screenTrack);
        document.getElementById('button-share-screen').style.display = 'none';
        document.getElementById('button-unshare-screen').style.display = 'inline';
      });
    };

Para o botão de "parar de compartilhar", queremos parar de publicar a faixa novamente. Para isso, vamos precisar de uma referência da trilha de compartilhamento de tela. No topo do arquivo, declare uma nova variável screenTrack.


var activeRoom;
var previewTracks;
var identity;
var roomName;
var screenTrack;

No call-back do getUserScreen, remova a chave var.

    document.getElementById('button-share-screen').onclick = function() {
      getUserScreen().then(function(stream) {
        screenTrack = stream.getVideoTracks()[0];
        activeRoom.localParticipant.publishTrack(screenTrack);
        document.getElementById('button-share-screen').style.display = 'none';
        document.getElementById('button-unshare-screen').style.display = 'inline';
      });
    };

Para o handler do botão de "parar de compartilhar", use a variável screenTrack para parar de publicar a trilha do localParticipant.

    document.getElementById('button-unshare-screen').onclick = function() {
      activeRoom.localParticipant.unpublishTrack(screenTrack);
      screenTrack = null;
      document.getElementById('button-share-screen').style.display = 'inline';
      document.getElementById('button-unshare-screen').style.display = 'none';
    };

E isso é todo o código que vamos precisar!

Compartilhe a tela

Inicie a aplicação novamente, se já não estiver rodando, com `npm start´. Se você quiser testar no Firefox, você vai precisar fazer com que a página esteja disponível em HTTPS. Você pode conseguir isso facilmente rodando ngrok e usando o túnel de URL HTTPS para seu localhost. Se estiver no Chrome, pode apenas ir em http://localhost:3000.

Configure um chat de vídeo com um amigo (você pode enviar o link do ngrok) ou com você mesmo usando dois navegadores. Uma vez que você tiver entrado, clique no botão de compartilhar tela e uma vez que você tiver selecionado qual tela compartilhar, ela vai aparecer no outro chat de vídeo.

Tela com exemplo final do projeto em execução

Compartilhe o quanto quiser, dentro dos navegadores certos

Com as técnicas desses três posts, agora você pode compartilhar seus chats de vídeo no Firefox e Chrome (e Opera, com a mesma extensão do Chrome, por acaso).

Existem várias coisas que podem ser feitas, desde construir um aplicativo de colaboração de apresentações, até aumentar o suporte ao cliente com o navegador compartilhando telas. Uma funcionalidade fácil para começar seria adicionar um preview local da tela do usuário para que ele possa ver o que está compartilhando.

Verifique o repositório no GitHub para ver todo o código de hoje e dos posts anteriores e adicione mais colaborações aos seus apps de chat de vídeo!

Vou adorar saber o que você construiu com essa funcionalidade! Me envie um e-mail em lleao@twilio.com ou fale comigo no Twitter @lleao.

Este artigo foi traduzido do original "Add screen sharing to your Twilio Video application".