Como criar um aplicativo de videoconferência com Laravel, PHP e Vue.js

April 14, 2020
Escrito por

Como criar um aplicativo de videoconferência com Laravel, PHP e Vue.js

Quando não podemos estar fisicamente juntos, a videoconferência ajuda a reforçar e estabelecer relacionamentos, o que permite monitorar pistas visuais que às vezes são perdidas no telefone. As teleconferências são excelentes, mas estudos mostram que se não podemos ver quem está falando, temos mais probabilidade de nos distrair com nossos aplicativos favoritos. A videoconferência não é apenas uma excelente forma de aumentar o foco durante as reuniões, mas também é um excelente método para manter contato com a família e os amigos durante a pandemia de coronavírus.

Neste tutorial, você aprenderá a criar seu próprio aplicativo de videoconferência no Vue.js, com o Laravel framework e o Twilio Programmable Video. Não há software para baixar nem tutoriais a seguir. O resultado final é um link para uma sala de chat por vídeo compatível com dispositivos móveis, que pode acomodar até 50 participantes.

OBSERVAÇÃO:Este tutorial foi escrito especificamente para Laravel 7 ou superior (embora possa funcionar em versões anteriores).

Visão geral técnica e pré-requisitos

Quando o aplicativo é carregado no navegador, um identificador exclusivo é gerado para que o usuário faça a autenticação da sua conexão na sala de chat. Uma vez verificado pelos servidores da Twilio, o usuário será adicionado à sala de chat existente.

Nosso projeto usa o Vue.js e Laravel para gerar o front-end e o back-end, respectivamente.

Para começar, é preciso configurar os seguintes requisitos e deixá-los prontos para uso:

Vamos começar a criar um novo projeto Laravel.

Como criar um novo projeto Laravel

Para criar o aplicativo base, abra a pasta onde você normalmente armazena seus projetos e execute o seguinte comando:

$ laravel new laravel-video-chat-room && cd laravel-video-chat-room

Como adicionar o Twilio PHP SDK ao projeto

Precisamos de um método fácil de conexão com a API do Twilio Video para que as salas de chat e os tokens possam ser criados e autenticados para os usuários. Felizmente, esse método já foi criado para nós no Twilio PHP SDK. Vamos adicioná-lo como um requisito do nosso projeto usando o Composer.

$ composer require twilio/sdk

Como criar um endpoint de API para gerar tokens

A criação de APIs no Laravel é um processo bastante simples. Por ser uma moderna estrutura de aplicativos de Internet, o Laravel oferece o suporte necessário para criar o controlador e a rota adequados para gerar tokens no servidor.

Como criar um novo controlador para gerar tokens de acesso

Será preciso criar um controlador ou classe que defina a lógica do aplicativo para gerar todos os tokens de acesso do usuário por meio da API do Twilio Video. Para começar, execute o comando artisan no terminal e criar novos controladores:

$ php artisan make:controller API/AccessTokenController

Este comando criou um novo arquivo em app/Http/Controllers/API/AccessTokenController.php.

Abra o controlador recém-criado e reserve um tempo para sua inspeção. Você vai notar que agora ele está vazio. Além de algumas declarações de namespace, o comando artisan gerou uma classe vazia.

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class AccessTokenController extends Controller
{
    //
}

Agora estamos prontos para adicionar alguns namespaces ao controlador que fará o carregamento automático do Twilio SDK para uso. Adicione as seguintes linhas de código abaixo do namespace use Illuminate\Http\Request;.

use Twilio\Jwt\AccessToken;
use Twilio\Jwt\Grants\VideoGrant;

As declarações anteriores oferecem o suporte necessário para conectar a API do Twilio Video e gerar um token de acesso. Agora é preciso criar um método para utilizar as classes declaradas.

Adicione o seguinte método generate_token abaixo para a classe AccessTokenController:

public function generate_token()
    {
        // Substitute your Twilio Account SID and API Key details
        $accountSid = env('TWILIO_ACCOUNT_SID');
        $apiKeySid = env('TWILIO_API_KEY_SID');
        $apiKeySecret = env('TWILIO_API_KEY_SECRET');

        $identity = uniqid();

        // Create an Access Token
        $token = new AccessToken(
            $accountSid,
            $apiKeySid,
            $apiKeySecret,
            3600,
            $identity
        );

        // Grant access to Video
        $grant = new VideoGrant();
        $grant->setRoom('cool room');
        $token->addGrant($grant);

        // Serialize the token as a JWT
        echo $token->toJWT();
    }

Observe as três primeiras linhas do método de pesquisa de variáveis de ambiente para definir as credenciais da Twilio. Essas linhas fazem referência a três variáveis que ainda não foram definidas no arquivo dotenv .env. Vamos abrir o Console da Twilio para acessar os arquivos.

Captura de tela Account SID (SID da conta) da Twilio

É preciso copiar o Account SID (SID da conta) do painel da sua conta. É preciso criar uma chave de API e um segredo de API a partir da lista de chaves de API.

Formulário da chave de API da Twilio

Todos esses três valores precisam ser copiados para o arquivo .env localizado no diretório do projeto da seguinte forma:

TWILIO_ACCOUNT_SID="Insert your Account SID"
TWILIO_API_KEY_SID="Insert your API Key"
TWILIO_API_KEY_SECRET="Insert your API Secret"

A última etapa na geração de um token de acesso é a criação de uma rota (ou endpoint de API) que se conecte ao AccessTokenController. Essa rota fornece um endpoint de acesso público para a lógica de aplicativo criada anteriormente.

Abra routes/api.php e adicione a seguinte declaração:

Route::get('access_token', 'API\AccessTokenController@generate_token');

Esta linha de código registra o endpoint http://127.0.0.1:8000/api/access_token e responde ao verbo GET.

Para testar nosso trabalho até aqui, execute o seguinte comando do artisan no seu terminal:

$ php artisan serve

O comando serve carrega o servidor de Internet PHP e implanta o aplicativo Laravel localmente.

Como instalar os pacotes Laravel UI e Vue

Como a funcionalidade de back-end está completa para nosso aplicativo, estamos prontos para dar suporte ao front-end. A partir da versão 6, o Laravel separou o JavaScript e o suporte CSS da lógica do aplicativo, por isso precisamos adicioná-lo novamente usando o novo Pacote Laravel UI. Depois de instalado, abre o aplicativo para usar com facilidade qualquer estrutura popular de estilo ou de script para modificar a interface e a experiência do usuário.

Execute o seguinte comando no seu terminal:

$ composer require laravel/ui

Agora que o pacote básico foi instalado, estamos prontos para instalar o suporte de front-end Vue.js. Para instalar, execute o seguinte comando:

$ php artisan ui vue

E depois:

$ npm install && npm run dev

Para visualizar o que foi feito e testar se o Vue está carregado e funcionando, é preciso atualizar a blade (lâmina) Laravel, responsável por exibir a página inicial em resources/views/welcome.blade.php. Abra o arquivo e substitua seu conteúdo por:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Video Chat</title>
        <link href="https://fonts.googleapis.com/css2?family=Oxygen&display=swap" rel="stylesheet">
        <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">

        <style>
            * {
                font-family: 'Oxygen', sans-serif;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <example-component></example-component>
        </div>
        <script src="{{ asset('js/app.js') }}"></script>
    </body>
</html>

OBSERVAÇÃO: Como o HTML foi modificado, é preciso compilá-lo para ver as alterações. Para visualizar as alterações, execute npm.eun.dev novamente ou npm.run.watch para recarga ativa.

Este HTML carrega o arquivo app.js, que é responsável por transformar o div #app no estágio da UI Vue.js. Por padrão, o pacote Laravel UI instala um ExampleComponent que é visto na linha como <example-component></example-component>. Este exemplo do Componente Vue simplesmente exibe alguns HTML executados como:

Example Component
I'm an example component.

Se aparecer esse comando no seu navegador, tudo está funcionando conforme esperado!

Como criar um novo componente Vue.js

Vamos criar um novo componente Vue VideoChat.vue na pasta resources/js/components que abriga a lógica de sala de chat por vídeo. Este componente é responsável por conectar-se ao endpoint criado anteriormente e renderizar a janela de chat.

Depois de criar o componente, adicione o seguinte código:

<template>
    <div class="p-5">
        <h1 class="text-2xl mb-4">Laravel Video Chat</h1>
        <div class="grid grid-flow-row grid-cols-3 grid-rows-3 gap-4 bg-black">
            <div id="my-video-chat-window"></div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'video-chat'
}
</script>

Este componente exibe apenas o título "Chat por vídeo Laravel". O Vue.js ainda não o reconhece, portanto, é preciso atualizar a blade (lâmina) welcome.blade.php novamente para exibir o componente.

Substitua a linha <example-component></example-component> em resources/views/welcome.blade.php por <video-chat></video-chat>.

Por fim, abra resources/js/app.js e adicione a seguinte linha de código abaixo de ExampleComponent para definir globalmente o novo componente:

Vue.component('video-chat', require('./components/VideoChat.vue').default);

Como conectar o componente VideoChat à rota

Antes de fazer uma solicitação AJAX para o endpoint de token de acesso, é preciso instalar o SDK de JavaScript do Twilio Programmable Video. Este SDK, escrito em JavaScript, é responsável por gerenciar todas as solicitações de API ao Twilio Programmable Video.

Em seu terminal, instale o SDK do JavaScript do Twilio Programmable Video executando o seguinte comando:

$ npm install --save twilio-video@2.0.0

Agora que o SDK está instalado, é possível adicionar o método getAccessToken() para conectá-lo ao endpoint.

Substitua o código em welcome.blade.php por:

<template>
    <div class="p-5">
        <h1 class="text-2xl mb-4">Laravel Video Chat</h1>
        <div class="grid grid-flow-row grid-cols-3 grid-rows-3 gap-4 bg-black/]">
            <div id="my-video-chat-window"></div>
        </div>
    </div>
</template>

<script>
export default {
    name: 'video-chat',
    data: function () {
        return {
            accessToken: ''
        }
    },
    methods : {
        getAccessToken : function () {

            const _this = this
            const axios = require('axios')
            
            // Request a new token
            axios.get('/api/access_token')
                .then(function (response) {
                    _this.accessToken = response.data
                })
                .catch(function (error) {
                    console.log(error);
                })
                .then(function () {
                    console.log( _this.accessToken )
                });
        }
    },
    mounted : function () {
        console.log('Video chat room loading...')

        this.getAccessToken()
    }
}
</script>

O código acima define uma variável accessToken vazia e atribui a ela uma string vazia. Uma vez o componente montadogetAccessToken() é chamado para solicitar um novo token de acesso de http://127.0.0.1:8000/api/access_token. Após uma resposta bem-sucedida , os dados são atribuídos ao accessToken.

Agora, estamos prontos para adicionar o código que nos conecta à sala definida anteriormente no controlador e exibir um feed ao vivo do dispositivo local.

Adicione o seguinte código à lista de métodos disponíveis após o método getAccessToken:

connectToRoom : function () {

            const { connect, createLocalVideoTrack } = require('twilio-video');

            connect( this.accessToken, { name:'cool room' }).then(room => {
                
                console.log(`Successfully joined a Room: ${room}`);

                const videoChatWindow = document.getElementById('video-chat-window');

                createLocalVideoTrack().then(track => {
                    videoChatWindow.appendChild(track.attach());
                });

                room.on('participantConnected', participant => {
                    console.log(`A remote Participant connected: ${participant}`);
                });
            }, error => {
                console.error(`Unable to connect to Room: ${error.message}`);
            });
        }

O método connectToRoom usa o accessToken que inicializamos em getAccessToken e cria um rastreamento de vídeo local após a autenticação bem-sucedida. Observe também que há um espaço reservado para quando um participante se conecta à sala de chat. Adicionaremos esta lógica em breve.

Por enquanto, vamos chamar esse método da última promise (promessa) then em getAccessToken da seguinte forma:

getAccessToken : function () {

            const _this = this
            const axios = require('axios')
            
            // Request a new token
            axios.get('/api/access_token')
                .then(function (response) {
                    _this.accessToken = response.data
                })
                .catch(function (error) {
                    console.log(error);
                })
                .then(function () {
                    _this.connectToRoom()
                });
        },

Por fim, estamos prontos para adicionar a lógica para exibir os outros participantes no chat por vídeo. Substitua o código room.on('participantConnected', participant => { por:

room.on('participantConnected', participant => {
                    console.log(`Participant "${participant.identity}" connected`);

                    participant.tracks.forEach(publication => {
                        if (publication.isSubscribed) {
                            const track = publication.track;
                            videoChatWindow.appendChild(track.attach());
                        }
                    });

                    participant.on('trackSubscribed', track => {
                        videoChatWindow.appendChild(track.attach());
                    });
                });

Esta função atende a quaisquer conexões novas de participantes remotos e, com a conexão, adiciona à galeria de janelas de chat.

Teste

Caso ainda não tenha executado essa ação, é necessário recompilar o código do Vue para detectar as alterações feitas. Execute o npm RUN dev, confirme se está executando o php artisan serve em um terminal separado e atualize seu navegador.

Com duas janelas ou navegadores, carregue http://127.0.0.1:8000/ e aguarde a conexão dos participantes.

Chat por vídeo com o Laravel

Conclusão

Este tutorial não só ensinou a implementar o Programmable Video da Twilio, mas também ajudou a desenvolver um aplicativo inicial de chat por vídeo. Se quiser ampliar este código ainda mais, você pode:

  • Mostrar o número de participantes
  • Ocultar a sala de chat atrás de um portal ou firewall
  • Adicionar um recurso de chat por texto

Com o mundo inteiro se voltando para o trabalho remoto e a videoconferência, não há melhor momento para ter sua implementação personalizada. Mal posso esperar para ver o que você criou!

É possível baixar o repositório completo do Github.

Este artigo foi traduzido do original "Create a Video Conference App using Laravel, PHP, and Vue.js". Enquanto melhoramos nossos processos de tradução, adoraríamos receber seus comentários em help@twilio.com - contribuições valiosas podem render brindes da Twilio.