Crear una app de videoconferencia mediante Laravel, PHP y Vue.js

April 14, 2020
Redactado por

Crear una app de videoconferencia mediante Laravel, PHP y Vue.js

En momentos en los que no podemos estar juntos físicamente, las videoconferencias ayudan a reforzar y establecer relaciones, ya que nos permiten monitorear las señales visuales que, a veces, se pierden cuando hablamos por teléfono. Las llamadas por conferencia son geniales, pero estudios demuestran que, cuando no podemos ver quién está hablando, es más probable que nos distraigamos con nuestras apps favoritas. Las videoconferencias no solo son una excelente manera de aumentar la concentración durante las reuniones, sino que también son un buen método para mantenerse en contacto con la familia y los amigos durante la pandemia por coronavirus.

En este tutorial, aprenderá a crear su propia app de videoconferencia en Vue.js, con el marco de Laravel y el video programable de Twilio. No se debe descargar ningún software ni seguir ningún tutorial. El resultado final es un enlace a una sala de chat de video compatible con dispositivos móviles, capaz de alojar hasta 50 participantes.

NOTA: Este tutorial está escrito específicamente para Laravel 7+ (aunque puede funcionar para versiones anteriores).

Descripción general técnica y requisitos previos

Cuando la aplicación se carga en el navegador, se genera un identificador único para que el usuario autentique su conexión con la sala de chat. Una vez que los servidores de Twilio lo verifiquen, se agregará al usuario a la sala de chat existente.

Nuestro proyecto utilizará Vue.js, y Laravel generará el frontend y el backend, respectivamente.

Para comenzar, necesitará los siguientes requisitos configurados y listos para usar:

Empecemos por crear un nuevo proyecto de Laravel.

Crear un nuevo proyecto de Laravel

Para crear la aplicación de base, abra la carpeta donde normalmente almacena sus proyectos y ejecute el siguiente comando:

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

Agregar el SDK de PHP de Twilio al proyecto

Necesitaremos un método sencillo para conectarnos a la API de Twilio Video para que las salas de chat y los tokens se puedan crear y autenticar para los usuarios. Afortunadamente, este método ya se creó para nosotros en el SDK de PHP de Twilio. Vamos a agregarlo como un requisito de nuestro proyecto mediante Composer.

$ composer require twilio/sdk

Crear un punto final de la API para generar tokens

Crear una API en Laravel es un proceso bastante sencillo. Como un marco moderno de aplicación web, Laravel brinda el andamiaje necesario para crear el controlador y la ruta necesarios para generar tokens en el lado del servidor.

Crear un nuevo controlador para generar tokens de acceso

Un controlador, o una clase que defina la lógica de la aplicación, deberá crearse para generar todos los tokens de acceso de los usuarios mediante la API de Twilio Video. Para comenzar, ejecute el comando artisan en su terminal para crear nuevos controladores:

$ php artisan make:controller API/AccessTokenController

Este comando creó un nuevo archivo para nosotros en app/Http/Controllers/API/AccessTokenController.php.

Abra el controlador recién creado y tómese un momento para inspeccionarlo. Notará que, ahora, está vacío. Aparte de un par de declaraciones de espacios de nombres, el comando artisan ha generado una clase vacía.

<?php

namespace App\Http\Controllers\API;

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

class AccessTokenController extends Controller
{
    //
}

Ya estamos listos para agregar un par de espacios de nombres al controlador que agregará de forma automática el SDK de Twilio para su uso. Agregue las siguientes líneas de código debajo del espacio de nombres use Illuminate\Http\Request;.

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

Las declaraciones anteriores nos brindan el soporte necesario para conectarse realmente a la API de Twilio Video y generar un token de acceso. Ahora, debe crear un método para utilizar las clases declaradas.

Agregue el siguiente método generate_token a continuación de la clase 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();
    }

Verá las tres primeras líneas de nuestro método de búsqueda de variables de entorno para definir nuestras credenciales de Twilio. Estas líneas hacen referencia a tres variables que aún no hemos definido en nuestro archivo dotenv .env. Abramos la consola de Twiliopara acceder a ellos.

Captura de pantalla SID de la cuenta de Twilio

Deberá copiar el SID de la cuenta desde el panel de control de su cuenta. Se deberá crear una clave de API y un secreto de API a partir de su lista de claves de API.

Formulario de clave de API de Twilio

Los tres valores deberán copiarse en el archivo .env ubicado en el directorio del proyecto de la siguiente manera:

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

El último paso para generar un token de acceso es crear una ruta (o punto final de la API) que se conecte a nuestro AccessTokenController. Esta ruta brindará un punto final de acceso público a la lógica de la aplicación que creamos anteriormente.

Abra routes/api.php y agregue la siguiente declaración:

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

Esta línea de código registra el punto final http://127.0.0.1:8000/api/access_token y responde al verbo GET.

Para probar nuestro trabajo hasta ahora, ejecute el siguiente comando de artisan en su terminal:

$ php artisan serve

El comando serve cargará el servidor web PHP e implementará nuestra aplicación Laravel de forma local.

Instalar la interfaz de usuario de Laravel y los paquetes de Vue

Debido a que la funcionalidad de back-end se completó para nuestra aplicación, estamos listos para hacer el andamiaje de front-end. A partir de la versión 6, Laravel separó el andamiaje de JavaScript y hojas de estilo de cascada (CSS) de la lógica de la aplicación, por lo que necesitaremos agregarlo nuevamente con el nuevo Paquete de interfaz de usuario de Laravel. Una vez instalado, abrirá nuestra aplicación para utilizar con facilidad cualquier diseño popular o marco de secuencias de comandos para modificar la interfaz y la experiencia del usuario.

Ejecute el siguiente comando en su terminal:

$ composer require laravel/ui

Ahora que se ha instalado el paquete base, estamos listos para instalar el andamiaje de front-end de Vue.js. Para instalarlo, ejecute lo siguiente:

$ php artisan ui vue

Seguido de lo siguiente:

$ npm install && npm run dev

Para ver lo que hemos hecho y probar que Vue está cargado y en funcionamiento, debemos actualizar blade de Laravel, responsable de mostrar la página de inicio en resources/views/welcome.blade.php. Abra el archivo y reemplace su contenido con lo siguiente:

<!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>

NOTA: Debido a que se modificó nuestro código HTML, debe ser compilado para ver los cambios. Para ver los cambios, vuelva a ejecutar npm run dev  o npm run watch para volver a cargarlo en vivo.

Este código HTML cargará el archivo app.js, que es responsable de transformar el div de la #app en la etapa de nuestra interfaz de usuario de Vue.js. De manera predeterminada, el paquete de interfaz de usuario de Laravel instala un ExampleComponent que se ve en la lectura de línea <example-component></example-component>. Este ejemplo Componente de Vue solo muestra código HTML representado de la siguiente manera:

Example Component
I'm an example component.

Si ve esto en su navegador, entonces ¡todo funciona como esperábamos!

Crear un componente nuevo de Vue.js

Vamos a crear un componente nuevo de Vue VideoChat.vue en la carpeta resources/js/components que albergará nuestra lógica de sala de chat de video. Este componente será responsable de conectarse al punto final que hemos creado anteriormente y de representar la ventana de chat.

Después de crear el componente, agregue el siguiente 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 solo mostrará el título “Laravel video Chat” (“Chat de video de Laravel”). Vue.js aún no lo reconoce, por lo tanto, tendremos que actualizar el Blade welcome.blade.php de nuevo para mostrar nuestro componente.

Sustituya la línea <example-component></example-component> en resources/views/welcome.blade.php con <video-chat></video-chat>.

Por último, abra resources/js/app.js y agregue la siguiente línea de código debajo de ExampleComponent para definir de forma global nuestro nuevo componente:

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

Conectar el componente de chat de video a la ruta

Antes de realizar una solicitud de AJAX a nuestro punto final de token de acceso, debe estar instalado el SDK de JavaScript de video programable de Twilio. Este SDK, escrito en JavaScript, es responsable de administrar todas las solicitudes de API de video programable de Twilio.

En su terminal, instale el SDK de JavaScript de video programable de Twilio mediante la ejecución del siguiente comando:

$ npm install --save twilio-video@2.0.0

Ahora que el SDK está instalado, podemos agregar el método getAccessToken() para la conexión a nuestro punto final.

Reemplace el código en welcome.blade.php con lo siguiente:

<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>

El código anterior define una variable vacía accessToken y le asigna una cadena vacía. Una vez que se prepara el componente, se llama a getAccessToken() para solicitar un nuevo token de acceso desde http://127.0.0.1:8000/api/access_token. Una vez que se obtiene una respuesta correcta, los datos se asignan a accessToken.

Ahora estamos listos para agregar el código que nos conectará a la sala que definimos antes en el controlador y que mostrará una transmisión en vivo desde nuestro dispositivo local.

Agregue el siguiente código a la lista de métodos disponibles después del 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}`);
            });
        }

El método connectToRoom toma el accessToken que inicializamos en getAccessToken y crea una pista de video local tras la autenticación correcta. Notará que también hay un marcador de posición para cuando un participante se conecte a la sala de chat. Agregaremos esa lógica en breve.

Por ahora, vamos a llamar a este método desde la promise then  en getAccessToken de la siguiente manera:

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 último, estamos listos para agregar la lógica para mostrar a los otros participantes en el chat de video. Reemplace el código room.on('participantConnected', participant => { con lo siguiente:

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 función captará las nuevas conexiones de los participantes remotos y, cuando se conecten, los agregará a la galería de ventanas de chat.

Pruebas

En caso de que no lo haya hecho en algún momento, deberá volver a compilar el código para que Vue detecte los cambios que hemos realizado. Ejecute npm run dev, asegúrese de que está ejecutando php artisan serve un terminal independiente y actualice su navegador.

Con el uso de dos ventanas o navegadores, cargue http://127.0.0.1:8000/ y espere a que los participantes se conecten.

Chat de video de Laravel

Conclusión

Este tutorial no solo nos ha enseñado cómo implementar el video programable de Twilio, sino que también nos ayudó a desarrollar una aplicación de chat de video de principiantes. Si está interesado en ampliar más este código, puede hacer lo siguiente:

  • Mostrar la cantidad de participantes
  • Ocultar la sala de chat detrás de un portal o muro seguro
  • Agregar una función de chat de texto

Con todo el mundo enfocado en el trabajo remoto y las videoconferencias, ya no hay mejor momento que ahora para tener su propia implementación personalizada. ¡Estoy ansioso por ver lo que es capaz de crear!

Este artículo fue traducido del original "Create a Video Conference App using Laravel, PHP, and Vue.js". Mientras estamos en nuestros procesos de traducción, nos encantaría recibir sus comentarios en help@twilio.com - las contribuciones valiosas pueden generar regalos de Twilio.