https://d226lax1qjow5r.cloudfront.net/blog/blogposts/stream-video-chat-with-texting-using-vonage-video-api-dr/Dev_Stream-Video_Texting_1200x600.png

Transmite Video Chat Con Mensajes De Texto Usando La API De Video De Vonage

Publicado el May 5, 2021

Tiempo de lectura: 4 minutos

Esta serie de tutoriales explorará la Video API de Vonage (anteriormente TokBox OpenTok) y lo que puedes crear con ella. La Video API es muy robusta y altamente personalizable, y en cada publicación, mostraremos cómo implementar una función específica usando la API. En esta ocasión veremos cómo ofrecer una opción para que la gente vea una transmisión de tu videochat e interactúen entre sí a través del chat de texto.

Como esta aplicación requerirá algo de código del lado del servidor, utilizaremos Glitch para facilitar la configuración. También puede descargar el código de este proyecto Glitch y desplegarlo en su servidor o plataforma de alojamiento de su elección (probablemente puede requerir algunos ajustes de configuración basados en los requisitos de su plataforma).

No vamos a utilizar ningún marco de front-end para esta serie, sólo Javascript vainilla, para mantener el foco en la propia Video API. Al final de este tutorial, usted será capaz de unirse a la charla de vídeo, ya sea como un Visor o como Participante. La diferencia entre estos dos roles es que espectadores pueden ver todas las secuencias de vídeo publicadas e interactuar con los demás a través del chat de texto, mientras que los participante pueden además publicar su vídeo en el chat.

Screenshot of viewer page with text chat open

El código final de esta aplicación se puede encontrar en este repositorio GitHub o en remezclado en Glitch.

Requisitos previos

Antes de comenzar, necesitarás una cuenta de Video API de Vonage, que puedes crear gratis aquí. También necesitarás Node.js instalado (si no estás usando Glitch).

Este tutorial se basa en un tutorial anterior: Agregar funcionalidad de mensajes de texto a un Video Chat. Cubre cómo usar la API de señalización para enviar mensajes de texto en su Video Chat.

Si es la primera vez que utiliza la Video API, le recomendamos encarecidamente que lea la primera entrada introductoria de la serie: Construyendo un Video Chat Básicoporque cubre la siguiente configuración básica:

  • Crear un proyecto de Video API de Vonage

  • Instalación en Glitch

  • Estructura básica del proyecto

  • Iniciar una sesión

  • Conectarse a la sesión, suscribirse y publicar

  • Estilos básicos de diseño para un chat de vídeo

Configuración inicial

Como estamos construyendo un videochat básico con capacidades de envío de mensajes de texto, empieza por remezclar el proyecto construido en el tutorial anterior. Haga clic en el botón grande Remix abajo para hacerlo. 👇

Remix this

Su estructura de carpetas debe parecerse a algo como esto:

Folder structure of the project

Como mencionamos al principio, TokBox OpenTok es ahora Vonage Video API. No hemos hecho ningún cambio en los nombres de nuestros paquetes, por lo que seguirás haciendo referencia a OpenTok en tu código.

Para poner en marcha el chat de vídeo, vaya al archivo .env e ingresa tu clave de API y el secreto de tu proyecto, que puedes encontrar en el panel de la Video API de Vonage. Una vez hecho esto, haremos algunas adiciones al proyecto para proporcionar una interfaz para los espectadores.

Añadir el marcado obligatorio

Nuestra aplicación constará de tres páginas: una página de inicio para que los usuarios creen o se unan a una sesión, así como para que seleccionen si quieren ser espectadores o participantes, y las dos páginas de chat de vídeo para cada rol, respectivamente.

Necesitaremos crear una página adicional para el visor. Añadamos un archivo viewer.html archivo a la carpeta views haciendo clic en el botón Nuevo archivo de la barra lateral izquierda. Nombre del archivo views/viewer.html y pegue la siguiente marca en la página. Esta página es casi igual que el archivo index.html salvo que no tiene un div para el editor.

Add a viewer.html to the views folder

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Stream your video chat (enhanced)</title>
    <meta
      name="description"
      content="Stream a basic audio-video chat plus texting with Vonage Video API in Node.js"
    />
    <link
      id="favicon"
      rel="icon"
      href="https://tokbox.com/developer/favicon.ico"
      type="image/x-icon"
    />
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <link rel="stylesheet" href="/style.css" />
  </head>

  <body>
    <header>
      <h1>Viewer</h1>
    </header>

    <main>
      <div id="subscriber" class="subscriber"></div>
    </main>

    <footer>
      <p>
        <small
          >Built on <a href="https://glitch.com">Glitch</a> with the
          <a href="https://tokbox.com/developer/">Vonage Video API</a>.</small
        >
      </p>
    </footer>

    <script src="https://static.opentok.com/v2/js/opentok.min.js"></script>
    <script src="/client.js"></script>
  </body>
</html>

También tendremos que añadir un conjunto de botones de opción para que los usuarios seleccionen sus funciones en la página landing.html página.

<form id="registration" class="registration">
  <label>
    <span>Room</span>
    <input
      type="text"
      name="room-name"
      placeholder="Enter room name"
      required
    />
  </label>

  <!-- Add the user type radio buttons -->
  <p>Select your role:</p>
  <fieldset>
    <label>
      <input type="radio" name="user-type" value="viewer" checked />
      <span>Viewer</span>
    </label>

    <label>
      <input type="radio" name="user-type" value="participant" />
      <span>Participant</span>
    </label>
  </fieldset>

  <label>
    <span>User name</span>
    <input
      type="text"
      name="user-name"
      placeholder="Enter your name"
      required
    />
  </label>

  <button>Enter</button>
</form>

Estilizar el nuevo conjunto de campos

Puede añadir los siguientes estilos para que el conjunto de campos y el diseño de los botones de radio sean algo más agradables. O cambiar el estilo de todos ellos en función de sus preferencias.

fieldset {
  border: 0;
  display: flex;
  justify-content: space-between;
  margin-bottom: 1em;
}

fieldset label {
  padding: 0.25em 0em;
  cursor: pointer;
}

Refactorizar el Javascript del lado del cliente

El script de la parte inferior de la página de destino debe modificarse para redirigir a los usuarios a la página correcta en función del tipo de usuario que hayan seleccionado.

const form = document.getElementById("registration");
form.addEventListener("submit", event => {
  event.preventDefault();
  const isViewer = form.elements["user-type"].value === "viewer";

  if (isViewer) {
    location.href = `/session/viewer/${form.elements["room-name"].value}?username=${form.elements["user-name"].value}&type=viewer`;
  } else {
    location.href = `/session/participant/${form.elements["room-name"].value}?username=${form.elements["user-name"].value}&type=participant`;
  }
});

En cuanto al archivo client.js las variables declaradas en la parte superior del archivo también necesitan algunos ajustes, ya que nuestro formato de URL es ligeramente diferente en este tutorial.

let session;
const url = new URL(window.location.href);
// Room name is now the fourth item
const roomName = url.pathname.split("/")[3];
const userName = url.searchParams.get("username");
// Additional variable for user type
const userType = url.searchParams.get("type");

Las distintas funciones del archivo server.js generarán tokens de suscriptor y editor, por lo que esta información se incluirá en la petición POST cuando se cargue la página.

fetch(location.pathname, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ username: userName, type: userType })
})
  .then(res => {
    return res.json();
  })
  .then(res => {
    const apiKey = res.apiKey;
    const sessionId = res.sessionId;
    const token = res.token;
    const streamName = res.streamName;
    initializeSession(apiKey, sessionId, token, streamName);
  })
  .catch(handleCallback);

El último ajuste se realiza en la función initializeSession() ya que sólo los participantes deben crear un editor y publicar en la sesión.

function initializeSession(apiKey, sessionId, token, streamName) {
  // Create a session object with the sessionId
  session = OT.initSession(apiKey, sessionId);
  
  // Check if user type is participant
  if (userType === 'participant') {
    // If so, create a publisher
    const publisher = OT.initPublisher(
      "publisher",
      {
        insertMode: "append",
        width: "100%",
        height: "100%",
        name: streamName
      },
      handleCallback
    );
    
    // Connect to the session
    session.connect(token, error => {
      // If the connection is successful, initialize the publisher and publish to the session
      if (error) {
        handleCallback(error);
      } else {
        session.publish(publisher, handleCallback);
      }
    });
  } else {
    // Connect to the session as a viewer
    session.connect(token, error => handleCallback(error));
  }

  initiateSessionListeners(session);
}

Gestión de rutas en el servidor

En el archivo server.js tendremos que hacer algunos cambios adicionales para servir los archivos correctos para los espectadores y los participantes, respectivamente.

app.get("/session/participant/:room", (request, response) => {
  response.sendFile(__dirname + "/views/index.html");
});

app.get("/session/viewer/:room", (request, response) => {
  response.sendFile(__dirname + "/views/viewer.html");
});

Como ahora tenemos dos páginas de las que ocuparnos, vamos a trasladar la funcionalidad del controlador POST a una función separada, que toma como parámetro userType como parámetro para que podamos usarlo durante la generación de tokens.

app.post("/session/participant/:room", (request, response) => {
  initSession(request, response, "publisher");
});

app.post("/session/viewer/:room", (request, response) => {
  initSession(request, response, "subscriber");
});

function initSession(request, response, userType) {
  const roomName = request.params.room;
  const streamName = request.body.username;
  const isExistingSession = checkSession(roomName);

  isExistingSession.then(sessionExists => {
    if (sessionExists) {
      sessionDb
        .get(roomName)
        .then(sessionInfo => {
          generateToken(roomName, streamName, userType, sessionInfo, response);
        })
        .catch(error => error);
    } else {
      OT.createSession((error, session) => {
        if (error) {
          console.log("Error creating session:", error);
        } else {
          const sessionInfo = {
            _id: roomName,
            sessionId: session.sessionId,
            messages: []
          };
          sessionDb.put(sessionInfo);
          generateToken(roomName, streamName, userType, sessionInfo, response);
        }
      });
    }
  });
}

La función generateToken() incluye ahora userType para diferenciar el tole token para espectadores y participantes.

function generateToken(roomName, streamName, userType, sessionInfo, response) {
  const tokenOptions = {
    role: userType,
    data: `roomname=${roomName}?streamname=${streamName}`
  };
  let token = OT.generateToken(sessionInfo.sessionId, tokenOptions);
  response.status(200);
  response.send({
    sessionId: sessionInfo.sessionId,
    token: token,
    apiKey: process.env.API_KEY,
    streamName: streamName
  });
}

Si todo ha ido bien, deberías poder entrar en una sala como participante y chatear por vídeo con otros participantes, así como interactuar con los espectadores a través del chat de texto. Si ha entrado en la sala como espectador, debería poder ver una videoconferencia en curso (siempre que haya una en curso) y chatear con todos los participantes en la sesión a través del chat de texto.

Screenshot of viewer page with text chat open

Consulte el código final en Glitch o en GitHub y siéntete libre de remezclar o clonar el código y jugar con él tú mismo.

¿Y ahora qué?

Existen funcionalidades adicionales que podemos crear con la Video API de Vonage, que se tratarán en futuros tutoriales. Mientras tanto, puedes obtener más información en nuestro sitio de documentación integral. Si tienes algún problema o alguna pregunta, comunícate con nosotros en nuestra Slack de la comunidad. Gracias por leernos.

Compartir:

https://a.storyblok.com/f/270183/384x384/46621147f0/huijing.png
Hui Jing ChenAntiguos alumnos de Vonage

Hui Jing es defensora de los desarrolladores en Nexmo. Tiene un amor desmesurado por CSS y la tipografía, y en general es una apasionada de todo lo relacionado con la web.