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

Stream Video Chat With Texting Using Vonage Video API (en anglais seulement)

Publié le May 5, 2021

Temps de lecture : 4 minutes

Cette série de tutoriels explorera l'API vidéo de Vonage (anciennement TokBox OpenTok). Video API de Vonage (anciennement TokBox OpenTok) et ce que vous pouvez construire avec. L'API Video est très robuste et hautement personnalisable, et dans chaque article, nous montrerons comment mettre en œuvre une fonctionnalité spécifique à l'aide de l'API. Cette fois-ci, nous allons voir comment offrir une option permettant aux gens de regarder un flux de votre chat vidéo et d'interagir les uns avec les autres par le biais d'un chat texte.

Comme cette application nécessitera un peu de code côté serveur, nous utiliserons Glitch pour faciliter l'installation. Vous pouvez également télécharger le code à partir de ce projet Glitch et le déployer sur le serveur ou la plateforme d'hébergement de votre choix (il faudra probablement modifier la configuration en fonction des exigences de votre plateforme).

Nous n'utiliserons pas de frameworks frontaux pour cette série, mais uniquement du Javascript vanille, afin de nous concentrer sur l'API Video elle-même. À la fin de ce tutoriel, vous serez en mesure de rejoindre le chat vidéo en tant que spectateur ou en tant que participant. La différence entre ces deux rôles est que téléspectateurs peuvent voir tous les flux vidéo publiés et interagir avec les autres par le biais d'un chat textuel, tandis que les participant peut en outre publier sa vidéo sur le chat.

Screenshot of viewer page with text chat open

Le code final de cette application peut être trouvé dans ce dépôt GitHub ou remixé sur Glitch.

Conditions préalables

Avant de commencer, vous aurez besoin d'un compte Video API de Vonage, que vous pouvez créer gratuitement ici. Vous aurez également besoin de Node.js installé (si vous n'utilisez pas Glitch).

Ce tutoriel s'appuie sur un tutoriel précédent : Ajouter une fonction de texto à un Video Chat. Il explique comment utiliser l API de signalisation de signalisation pour ajouter des fonctionnalités d'envoi de texte à votre Video Chat.

Si vous utilisez l'API Video pour la première fois, nous vous conseillons vivement de lire le premier article d'introduction de la série : Construire un chat vidéo de basecar il couvre la configuration de base suivante :

  • Créer un projet Video API de Vonage

  • S'installer sur Glitch

  • Structure de base du projet

  • Initialisation d'une session

  • Connexion à la session, abonnement et publication

  • Styles de mise en page de base pour un chat vidéo

Configuration initiale

Comme nous construisons sur un chat vidéo de base avec des capacités de texte, commencez par remixer le projet construit dans le tutoriel précédent. Cliquez sur le gros bouton Remix ci-dessous pour le faire. 👇

Remix this

La structure de votre dossier devrait ressembler à ceci :

Folder structure of the project

Comme nous l'avons mentionné au début, TokBox OpenTok est maintenant Video API de Vonage. Nous n'avons pas modifié les noms de nos paquets, de sorte que vous ferez toujours référence à OpenTok dans votre code.

Pour mettre en place le chat vidéo, allez dans le fichier .env et indiquez la clé API et le secret de votre projet, que vous trouverez dans le tableau de bord de l'API vidéo de Vonage. le tableau de bord de l'API Video de Vonage. Une fois que c'est fait, nous ferons quelques ajouts au projet pour fournir une interface aux téléspectateurs.

Ajouter le balisage requis

Notre application sera composée de trois pages : une page d'accueil permettant aux utilisateurs de créer ou de rejoindre une session et de choisir s'ils veulent être spectateur ou participant, et les deux pages de chat vidéo pour chaque rôle, respectivement.

Nous allons devoir créer une page supplémentaire pour le spectateur. Ajoutons un fichier viewer.html au dossier views en cliquant sur le bouton Nouveau fichier dans la barre latérale gauche. Nommez le fichier views/viewer.html et collez les balises suivantes dans la page. Cette page est presque identique au fichier index.html sauf qu'elle n'a pas de div pour l'éditeur.

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>

Nous devrons également ajouter une série de boutons radio pour que les utilisateurs puissent sélectionner leur rôle sur la page. landing.html page.

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

Style du nouvel ensemble de champs

Vous pouvez ajouter les styles suivants pour rendre la présentation des champs et des boutons radio par défaut légèrement plus agréable. Vous pouvez également les remodeler tous ensemble en fonction de vos préférences.

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

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

Refonte du Javascript côté client

Le script au bas de la page de renvoi doit être modifié pour rediriger les utilisateurs vers la bonne page en fonction du type d'utilisateur qu'ils ont sélectionné.

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`;
  }
});

Comme pour le fichier client.js les variables déclarées au début du fichier doivent également être modifiées car le format de notre URL est légèrement différent dans ce tutoriel.

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");

Différentes fonctions du fichier server.js généreront des jetons d'abonné et d'éditeur, de sorte que ces informations seront incluses dans la requête POST lors du chargement de la page.

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

La dernière modification concerne la fonction initializeSession() car seuls les participants doivent créer un éditeur et publier dans la session.

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);
}

Gestion des itinéraires sur le serveur

Dans le fichier server.js nous devrons apporter quelques modifications supplémentaires afin de servir les fichiers corrects aux spectateurs et aux participants, respectivement.

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");
});

Comme nous avons maintenant deux pages à gérer, déplaçons la fonctionnalité du POST dans une fonction séparée, qui prend en paramètre userType comme paramètre afin de pouvoir l'utiliser lors de la génération des jetons.

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 fonction generateToken() prend désormais en compte userType pour différencier le tole token pour les spectateurs et les participants.

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 tout s'est bien passé, vous devriez pouvoir entrer dans une salle en tant que participant et participer à une discussion vidéo avec d'autres participants, ainsi qu'interagir avec les spectateurs par le biais d'une discussion textuelle. Si vous êtes entré dans la salle en tant que spectateur, vous devriez pouvoir regarder une discussion vidéo en cours (s'il y en a une) et discuter avec tous les participants à la session par le biais d'une discussion textuelle.

Screenshot of viewer page with text chat open

Consultez le code final sur Glitch ou sur GitHub et n'hésitez pas à remixer ou cloner le code et à vous amuser avec.

Quelle est la prochaine étape ?

Il existe d'autres fonctionnalités que nous pouvons créer avec l'API Video de Vonage, qui seront abordées dans de futurs tutoriels. En attendant, vous pouvez en savoir plus en consultant notre site de documentation complet. Si vous rencontrez des problèmes ou si vous avez des questions, contactez-nous sur notre Communauté Slack. Merci pour votre lecture !

Partager:

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

Hui Jing est développeuse chez Nexmo. Elle a un amour immodéré pour le CSS et la typographie, et est généralement passionnée par tout ce qui touche au web.