https://a.storyblok.com/f/270183/315766/437283b71d/tw_opentok_react.png

Crie um chat de vídeo personalizado com componentes React e a Vonage

Publicado em November 6, 2020

Tempo de leitura: 9 minutos

Observe que o React não é oficialmente compatível com a Video API da Vonage

Recentemente, comecei a experimentar a plataforma de Video API da Vonage e a criar alguns aplicativos básicos com chat por vídeo.

tweet of playing with Vonage Video API for first timetweet of playing with Vonage Video API for first time

E, embora seja divertido e meio bobo adicionar rapidamente uma transmissão ao vivo do meu rosto a um aplicativo no qual estou trabalhando, logo fiquei curioso sobre outros casos de uso. Ou melhor, qual é a vantagem de desenvolver isso por conta própria em vez de usar uma das muitas outras opções de videoconferência disponíveis no mercado?

Para explorar todas as funcionalidades da API, pensei em criar um aplicativo para os alunos do bootcamp do qual participei, Ada Developers Academy.

O Ada é um programa gratuito com duração de um ano, voltado para mulheres e pessoas de diversas identidades de gênero, com o objetivo de ensiná-las a programar. Sinto-me incrivelmente sortuda por ter participado e por ter recebido as ferramentas necessárias para fazer a transição de professora de inglês para engenheira de software em apenas um ano. Então, pensei que uma ótima maneira de retribuir seria criar um portal para que os alunos pudessem entrar em contato com tutores e receber ajuda em tempo real e pessoalmente de mentores do setor. Além disso, eu poderia aprender mais sobre a Video API da Vonage ao mesmo tempo!

Enquanto desenvolvia esse portal, logo descobri o que tantos engenheiros já haviam percebido antes: como é incrível ter total autonomia e controle sobre a funcionalidade do código dentro do seu aplicativo. Eu podia adaptar o aplicativo e meu código às necessidades dos alunos e tutores, o que me deu uma sensação de enorme poder. Eu estava experimentando especificamente o wrapper React da Video API chamado OpenTok React, que é essencialmente um componente web para o SDK do JavaScript. Ele torna incrivelmente simples integrar streaming de vídeo e áudio de alta qualidade a qualquer aplicativo React. Ele oferece componentes personalizáveis que são flexíveis o suficiente para serem incorporados com bastante facilidade a qualquer um dos meus aplicativos React.

Este é um tutorial sobre como usar esse React Wrapper e dividir o código em componentes React modulares e reutilizáveis para incorporar em qualquer um ou em todos os seus futuros aplicativos React!

Pré-requisitos

Como criar um chat de vídeo personalizado com a Video API da Vonage e componentes React

Você vai realizar as seguintes tarefas para criar seu aplicativo:

  1. Criar um projeto da Video API

  2. Crie um aplicativo React com create-react-app

  3. Criar componentes React reutilizáveis:

    • Editora

    • Assinante

    • Status da conexão

    • Caixa de seleção

  4. Execute seu aplicativo de chat por vídeo

Este tutorial vai guiá-lo por todo o processo, do zero. No entanto, se você quiser ver o código final, pode clonar o repositório Git deste projeto.

Criar um projeto da Video API da Vonage

Depois de fazer login na sua conta da Video API da Vonage, no canto esquerdo da página, selecione Projects e, no menu suspenso, clique em Create New Project.

where to click new project demowhere to click new project demo

A partir daí, selecione Create Custom Project e dê a ele o nome que quiser. Depois de criar o projeto, clique View Project e salve a chave de API na parte superior.
Em seguida, role a página para baixo até a seção intitulada Project Tools e clique no botão azul para Create Session ID.

what to click to generate a sessionIDwhat to click to generate a sessionID

Copie e cole esse sessionID na seção abaixo Generate Token. Fique à vontade para prolongar o tempo de validade além do padrão de 1 hora, se desejar.
Em seguida, clique no botão azul Generate Token e salve o token gerado.

Crie um aplicativo React com create-react-app

Antes de começarmos, Verify que você tenha uma versão atualizada do Node instalada no seu computador (5.2, no mínimo), executando node -v no seu terminal.

Em seguida, no diretório onde você deseja que este projeto fique, execute o comando:

npx create-react-app react-components-tokbox

Chamei meu projeto de react-components-tokbox, mas você pode dar o nome que quiser.

Acesse o diretório do seu projeto e instale as duas dependências que usaremos neste projeto:

cd react-components-tokbox && npm install opentok-react lodash

A opentok-react biblioteca é um wrapper do React composto por alguns componentes que usaremos hoje:

  • Componente OTSession

  • Componente OTPublisher

  • Componente OTStreams

  • Componente OTSubscriber

  • Ajudante createSession

  • Componente de ordem superior `preloadScript`

Execute npm start para garantir que tudo foi instalado corretamente. localhost:3000 Deve abrir automaticamente e estar executando o código padrão do starter do React.

Configuração

Vá para a src pasta e crie um config.js arquivo:

cd src && touch config.js

Abra esse novo arquivo e adicione as credenciais que você gerou há pouco, ao criar um projeto no TokBox:

// src/config.js
export default {
  API_KEY: 'XYZ',
  SESSION_ID: 'XYZ',
  TOKEN: 'XYZ'
};

Agora, abra o src/index.js arquivo e importe o congfig.js arquivo:

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import config from './config';

Agora, para realmente usar essas credenciais, certifique-se de passá-las para o <App /> componente:

// src/index.js
ReactDOM.render(<App
  apiKey={config.API_KEY}
  sessionId={config.SESSION_ID}
  token={config.TOKEN}
  />, document.getElementById('root'));

No src/App.js arquivo, vamos importar alguns dos componentes do wrapper do React:

// src/App.js
import { OTSession, OTStreams, preloadScript } from 'opentok-react';

Criar componentes React reutilizáveis

Crie uma nova components pasta dentro de src. Nessa pasta, crie seus componentes:

mkdir components && touch Publisher.js Subscriber.js ConnectionStatus.js CheckBox.js

Agora, novamente no seu src/App.js arquivo, importe três desses componentes:

// src/App.js
import ConnectionStatus from './components/ConnectionStatus';
import Publisher from './components/Publisher';
import Subscriber from './components/Subscriber';

Vamos alterar o <App /> componente nesse arquivo para que seja baseado em classes, em vez de funcional.

// src/App.js
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
  };
  render() {
    return (
      <div>
        TokBox
      </div>
    );
  }
}
export default preloadScript(App);

Dentro do construtor, adicione um estado e dois sessionEvents para detectar o status da conectividade:

// src/App.js
constructor(props) {
  super(props);
  this.state = {
    error: null,
    connected: false
  };
  this.sessionEvents = {
    sessionConnected: () => {
      this.setState({ connected: true });
    },
    sessionDisconnected: () => {
      this.setState({ connected: false });
    }
  };
}

Fora do construtor, crie uma função onError():

// src/App.js
  onError = (err) => {
    this.setState({ error: `Failed to connect: ${err.message}` });
  }

Dentro da render() função, insira o <OTSession /> componente que passa as credenciais do src/index.js arquivo:

// src/App.js
render() {
  return (
      <OTSession
        apiKey={this.props.apiKey}
        sessionId={this.props.sessionId}
        token={this.props.token}
        eventHandlers={this.sessionEvents}
        onError={this.onError}
        >
      </OTSession>
    );
  }

Agora, dentro do <OTSession /> vamos lidar preventivamente com os erros e chamar os componentes, <ConnectionStatus />, <Publisher />, e <Subscriber />:

// src/App.js
  {this.state.error ? <div id="error">{this.state.error}</div> : null}
  <ConnectionStatus />
  <Publisher />
  <OTStreams>
    <Subscriber />
  </OTStreams>

Criar o componente ConnectionStatus

No src/components/ConnectionStatus.js arquivo, vamos pensar na melhor maneira de exibir o status da conexão para o usuário:

// src/components/ConnectionStatus.js
import React from 'react';

class ConnectionStatus extends React.Component {
  render() {
    let status = this.props.connected ? 'Connected' : 'Disconnected';
    return (
      <div className="connectionStatus">
        <strong>Status:</strong> {status}
      </div>
    );
  }
}
export default ConnectionStatus;

Agora, de volta ao src/App.js arquivo, passe o estado para o <ConnectionStatus /> componente:

// src/App.js
<ConnectionStatus connected={this.state.connected} />

Desenvolver o componente Publisher

Agora, no início do seu src/components/Publisher.js arquivo, importe os arquivos e o OTPublisher de opentok-react:

// src/components/Publisher.js
import React from 'react';
import { OTPublisher } from 'opentok-react';
import CheckBox from './CheckBox';

A seguir, vamos criar um componente baseado em classe Publisher:

// src/components/Publisher.js
class Publisher extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      audio: true,
      video: true,
      videoSource: 'camera'
    };
  }
  setAudio()
  setVideo()
  setVideoSource()
  onError()

  render() {
    return (
      <div>
        <OTPublisher />
      </div>
    );
  }
}
export default Publisher;

Vamos preencher essas funções com algum estado:

// src/components/Publisher.js
  setAudio = (audio) => {
    this.setState({ audio });
  }

  setVideo = (video) => {
    this.setState({ video });
  }

  changeVideoSource = (videoSource) => {
    (this.state.videoSource !== 'camera') ? this.setState({videoSource: 'camera'}) : this.setState({ videoSource: 'screen' })
  }

  onError = (err) => {
    this.setState({ error: `Failed to publish: ${err.message}` });
  }

E dentro do <OTPublisher /> vamos passar publishAudio, publishVideo, e videoSource para o properties prop e à função onError() para a onError prop:

// src/components/Publisher.js
render() {
  return (
    <div className="publisher">
      Publisher
      {this.state.error ? <div id="error">{this.state.error}</div> : null}
      <OTPublisher
        properties={{
          publishAudio: this.state.audio,
          publishVideo: this.state.video,
          videoSource: this.state.videoSource === 'screen' ? 'screen' : undefined
        }}
        onError={this.onError}
      />
    </div>
  };

Desenvolver o componente de assinantes

Agora, no src/components/Subscriber.js arquivo, vamos importar os arquivos e componentes e criar um componente baseado em classe Subscriber com subscribeToAudio e subscribeToVideo como properties dentro do <OTSubscriber />:

// src/components/Subscriber.js
import React from 'react';
import { OTSubscriber } from 'opentok-react';
import CheckBox from './CheckBox';

class Subscriber extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      error: null,
      audio: true,
      video: true
    };
  }

  setAudio = (audio) => {
    this.setState({ audio });
  }

  setVideo = (video) => {
    this.setState({ video });
  }

  onError = (err) => {
    this.setState({ error: `Failed to subscribe: ${err.message}` });
  }

  render() {
    return (
      <div className="subscriber">
        Subscriber
        {this.state.error ? <div id="error">{this.state.error}</div> : null}
        <OTSubscriber
          properties={{
            subscribeToAudio: this.state.audio,
            subscribeToVideo: this.state.video
          }}
          onError={this.onError}
        />
      </div>
    );
  }
}
export default Subscriber;

Desenvolver o componente CheckBox

Vamos usar o <CheckBox /> componente tanto no <Publisher /> e <Subscriber /> :

// src/components/CheckBox.js
import React from 'react';
import { uniqueId } from 'lodash';

class CheckBox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      id: uniqueId('Checkbox'),
      isChecked: this.props.initialChecked
    };
  }

  onChange = (event) => {
    let isChecked = event.currentTarget.checked;
    this.setState({ isChecked });
  }

  componentDidUpdate(prevProps, prevState) {
    if (
      prevState.isChecked !== this.state.isChecked &&
      typeof this.props.onChange === 'function'
    ) {
      this.props.onChange(this.state.isChecked);
    }
  }

  render() {
    return (
      <div>
        <label htmlFor={this.state.id}>
          {this.props.label}
        </label>
        <input
          type="checkbox"
          checked={this.state.isChecked}
          id={this.state.id}
          onChange={this.onChange}
        />
      </div>
    );
  }
}
export default CheckBox;

Vamos agora usar tanto o <CheckBox /> componente no src/components/Publisher.js arquivo:

// src/components/Publisher.js
<CheckBox
  label="Share Screen"
  onChange={this.changeVideoSource}
/>
<CheckBox
  label="Publish Audio"
  initialChecked={this.state.audio}
  onChange={this.setAudio}
/>
<CheckBox
  label="Publish Video"
  initialChecked={this.state.video}
  onChange={this.setVideo}
/>

E também no src/components/Subscriber.js arquivo:

// src/components/Subscriber.js
<CheckBox
  label="Subscribe to Audio"
  initialChecked={this.state.audio}
  onChange={this.setAudio}
/>
<CheckBox
  label="Subscribe to Video"
  initialChecked={this.state.video}
  onChange={this.setVideo}
/>

E, por fim, vamos adicionar um CSS simples para o aplicativo no src/App.css arquivo:

/* src/App.css */
body, html {
  background-color: pink;
  height: 100%;
  font-family: Verdana, Geneva, sans-serif
}
.connectionStatus {
  padding-top: 20px;
  margin-left: 5%;
  font-size: 1.5em;
}
.subscriber {
  margin-left: 10%;
}
.publisher {
  float: right;
  margin-right: 10%;
}
.OTPublisherContainer {
  width: 80vh !important;
  height: 80vh !important;
}
#error {
  color: red;
}

Execute seu aplicativo de chat por vídeo

Você já criou todos os 4 componentes do React:

  • Editora

  • Assinante

  • Status da conexão

  • Caixa de seleção

Você pode testar seu aplicativo executando npm start no terminal, a partir da raiz do seu projeto.

view after running npm startview after running npm start

Parabéns! Esses componentes são modulares e reutilizáveis em qualquer aplicativo React futuro.

Agora você pode integrá-los de forma fácil e rápida ao seu aplicativo para habilitar o recurso de chat por vídeo. Não é demais?! Eu, pelo menos, estou bem empolgado 😆 e já comecei a procurar todas as oportunidades possíveis no meu dia a dia para usar o chat por vídeo!

🌟Vamos colaborar!🌟

Se você tiver uma ideia criativa, nova, engraçada ou inovadora sobre como usar o chat por Video, compartilhe conosco!

Eu ficaria MUITO animado em colaborar e criar novos aplicativos junto com vocês.

Compartilhar:

https://a.storyblok.com/f/270183/250x250/708316e4e8/laurenlee.png
Lauren LeeEx-funcionários da Vonage

Um professor de inglês que se tornou um engenheiro de software empático. Um otimista curioso, apaixonado por criar conteúdo acessível e ajudar desenvolvedores a aprimorar suas habilidades.