https://d226lax1qjow5r.cloudfront.net/blog/blogposts/why-experience-composer-api-is-great/experience-composer-api.png

Pourquoi l'API Experience Composer est géniale

Temps de lecture : 9 minutes

Vonage a récemment publié API Experience Composer (EC). Cette offre fournit un service cloud piloté par API pour capturer l'expérience complète de votre application web à l'aide de l'API Video de Vonage. Cela signifie que l'aspect et la convivialité de votre application web peuvent désormais être entièrement enregistrés, diffusés via HLS ou RTMP, ou publiés en tant que nouveau flux dans une session vidéo.

Dans ce billet, nous allons voir comment vous pouvez utiliser Experience Composer pour ajouter un nouveau flux vidéo à une session Vonage existante contenant le logo de votre marque, des éléments HTML personnalisés et une iframe avec Google Calendar. Vous pouvez voir une Video de l'application à la fin de cet article.

Diagram of the host's view of the stream with a calendar to the left and on the right in a column from top to bottom is the host camera feed with a Vonage logo overlay, a data table with columns, number, status and Assignee, and a video guest feedHost View Diagram

Imaginez une session de planification de projet entre un chef de produit et un développeur de logiciel. Le chef de produit, en tant qu'hôte, publiera un calendrier de planification du produit avec des échéances et un tableau HTML contenant des éléments de travail avec des attributions et des statuts. Le logo de la marque sera superposé au flux Video de l'hôte. La vue de l'hôte contiendra tous ces éléments ainsi que la vidéo de l'invité.

Le développeur de logiciels, en tant qu'invité, est un consommateur du flux de l'hôte qui comprend le calendrier, le tableau de données et la vidéo de l'hôte avec l'incrustation de la marque.

Conditions préalables

  1. Un compte Video API de Vonage. Si vous n'avez pas de compte, vous pouvez vous inscrire et en créer un.

  2. Version de Node.js >= 14.17.5

  3. Experience Composer API activé pour votre Account. Vous pouvez le faire dans le portail de l'Account.

Nous utiliserons Bootstrap du CDN et la grille CSS pour accélérer le temps de développement. Je ne vais pas entrer dans les détails du CSS, mais vous pouvez consulter les fichiers CSS ainsi que le code complet dans le dépôt GitHub GitHub.

Diagramme d'architecture

Le diagramme suivant montre l'architecture de ce que nous allons construire. Tout restera dans une seule session vidéo Vonage, la Video Session A. Pour commencer, l'hôte, le flux A, sera publié dans la session avec l'invité, le flux B. Cependant, l'invité ne s'abonnera pas encore à l'hôte. Experience Composer s'abonnera au flux A et publiera un nouveau flux, le flux A (composite), contenant la vidéo de l'hôte avec l'incrustation de marque, le calendrier Google et le tableau de données. L'invité consommera ce flux composite. Les deux utilisateurs pourront communiquer entre eux.

Diagram showing how the video feeds are fed into the Experience Composer and transformed into a composite stream.Architecture Diagram

Le serveur

Le serveur crée des salles et des sessions, génère des jetons et envoie des demandes à l'API Experience Composer pour démarrer et arrêter flux.

Remarque : L'API Experience Composer n'est pas pris en charge par le SDK Vonage Server pour le moment. Le démarrage et l'arrêt des flux Experience Composer se feront par le biais d'appels REST.

Le point de terminaison /render de notre serveur prendra les éléments sessionId et le roomName de la requête POST de notre côté client. Les sessionId est ensuite transmis à createRender qui lancera Experience Composer et renverra des données sur le rendu. Le id est alors extrait et sauvegardé dans l'objet sessions sous l'objet roomName en tant que renderId.

app.post('/render', async (req, res) => {
  try {
    const { sessionId, roomName } = req.body;
    if (sessionId && roomName) {
      const data = await createRender(sessionId);
      const { id } = data;
      sessions[roomName].renderId = id;
      res.status(200).send({ id });
    } else {
      res.status(500);
    }
  } catch (e) {
    res.status(500).send({ message: e });
  }
});

De même, pour arrêter le flux publié par l'Experience Composer, notre point de terminaison /render/stop/:id prendra le Render id nécessaire pour arrêter l'instance de l'Experience Composer.

app.get('/render/stop/:id', async (req, res) => {
  try {
    const { id } = req.params;
    if (id) {
      console.log('trying to stop render ' + id);
      const data = await deleteRender(id);
      res.status(200).send(data);
    } else {
      res.status(500);
    }
  } catch (e) {
    res.status(500).send({ message: e });
  }
});

Note : Le code pour les createRender et deleteRender se trouve dans le fichier index.js.

Pour authentifier les demandes auprès de l'API, nous devons créer un jeton Web JSON (JWT) comme expliqué dans la documentation du développeur. J'ai utilisé le paquet jsonwebtoken de npmmais vous pouvez utiliser n'importe quel autre paquet.

Pour créer le rendu, nous devons passer quelques paramètres dans le corps JSON, comme indiqué dans la la documentation. Certains paramètres sont obligatoires, tels que url, sessionId, token, et projectId. Accordez une attention particulière au paramètre url . Considérez-le comme l'URL que l'"utilisateur invisible", Experience Composer, visitera. Ensuite, le code JavaScript sera chargé afin que Experience Composer ne s'abonne qu'à l'hôte et qu'un nouveau flux soit publié dans le fichier sessionId.

Vous avez peut-être remarqué que dans la createRender fonction qu'il y a un objet supplémentaire properties qui contient un name paramètre. Ce nom s'avérera utile lorsque nous écouterons les événements streamCreated côté client. Nous y reviendrons dans un instant, mais tout ce que vous devez savoir pour l'instant, c'est qu'il s'agit du nom du flux que nous allons publier dans la session.

Notre serveur sera également chargé de servir le contenu HTML statique au client. Nous allons mettre en place quelques routes pour les différentes vues de notre application. Une route pour l'hôte (le présentateur qui publiera le calendrier, le tableau, etc.), une autre pour l'invité ou le consommateur du flux de l'hôte, et une autre pour l'Experience Composer (c'est le paramètre url que nous envoyons dans le corps JSON mentionné plus haut).

app.get('/host', (req, res) => {
  res.sendFile(__dirname + '/src/host.html');
});

app.get('/ec', (req, res) => {
  res.sendFile(__dirname + '/src/ec.html');
});

app.get('/user', (req, res) => {
  res.sendFile(__dirname + '/src/user.html');
});

Côté client

Nous allons créer un exemple d'application Vanilla JS, mais vous pouvez utiliser Experience Composer avec n'importe quel framework de votre choix. Le code côté client se trouve dans le dossier src.

Vue de l'invité

Pensez à l'invité comme à un spectateur du flux composite de l'hôte tout en envoyant sa vidéo et son audio pour communiquer avec l'hôte.

Le code de la vue invité se trouve dans le fichier HTML user.html avec le JavaScript et le CSS inclus. L'invité va publier son flux vidéo et s'abonner uniquement au flux publié par Experience Composer. Nous pouvons nous abonner sélectivement au flux publié par Experience Composer parce que nous avons défini un nom pour le flux.

Lorsque nous configurons l'écouteur d'événements streamCreated nous ne nous abonnerons au flux que si le nom du flux est EC. Cela permet d'éviter que l'invité ne s'abonne au flux vidéo normal de l'hôte (sans table, superposition et iframe).

session.on('streamCreated', function streamCreated(event) {
  if (event.stream.name === 'EC') {
    const subscriberOptions = {
      width: '800px',
      height: '500px',
    };
    session.subscribe(
      event.stream,
      'subscriber',
      subscriberOptions,
      handleError
    );
  }
});

Voici à quoi ressemble la vue de l'invité. Vous pouvez voir deux flux différents. À gauche, l'invité publie son flux Video tandis qu'à droite, il s'abonne au flux composite publié par l'Experience Composer qui contient le flux vidéo de l'hôte, le calendrier, l'incrustation et le tableau de données.

Diagram of the Guest View with the guest's video feed on the left and in a box on the right that contains a calendar to the left and on the right in a column from top to bottom is the host camera feed with a Vonage logo overlay, a data table with columns, number, status and AssigneeGuest View Diagram

Vue de l'hôte

L'hôte, dans ce cas, est la personne qui publiera le flux Video avec quelques éléments personnalisés spécifiques à l'application. Dans cette vue, l'hôte dispose de son flux vidéo et s'abonne au flux vidéo de l'invité. La mise en page de la vue de l'hôte comprendra également les éléments personnalisés (calendrier Google, tableau de données et superposition de marque) qui seront publiés dans la session par l'Experience Composer.

La vue de l'hôte sera chargée sur la route de notre application. /host de notre application. J'ai également décidé d'ajouter un paramètre de requête pour identifier l'hôte et l'Experience Composer. Ainsi, la route complète de notre hôte sera ${applicationUrl}/host?role=host.

Encore une fois, voici à quoi ressemblera la vue de l'hôte.

Diagram of the host's view of the stream with a calendar to the left and on the right in a column from top to bottom is the host camera feed with a Vonage logo overlay, a data table with columns, number, status and Assignee, and a video guest feedHost View Diagram

L'hôte et Experience Composer partageront le même fichier fichier JavaScript mais auront des fichiers HTML distincts. Le fichier de balisage de l'hôte se trouve ici. Pour déterminer s'il s'agit d'un hôte ou d'un CE, j'ai créé deux fonctions, isHost et isExperienceComposer.

function isHost() {
  return queryString === '?role=host' && window.location.pathname === '/host';
}

function isExperienceComposer() {
  return (
    queryString === '?role=experience_composer' &&
    window.location.pathname === '/ec'
  );
}

Cela nous permettra de nous abonner sélectivement aux flux dont nous avons besoin. L'hôte n'a pas besoin de s'abonner au flux créé par l'Experience Composer, car il s'abonnerait alors à son propre flux. Nous pouvons donc nous abonner de manière sélective au flux dont le nom est différent de EC.

session.on('streamCreated', function (event) {
  if (isHost() && event.stream.name !== 'EC') {
    subscribe(event.stream);
  }
});

La fonction subscribe décidera de l'endroit où ajouter l'éditeur selon qu'il s'agit de l'hôte ou de l'Experience Composer qui s'abonne au flux. Si c'est l'hôte qui essaie de s'abonner, nous voudrons ajouter la Video de l'autre utilisateur (invité) à l'élément DOM dont l'id est subscriberc'est-à-dire en bas à droite de la vue de l'hôte.

function subscribe(stream) {
  session.subscribe(
    stream,
    isExperienceComposer() ? 'publisher' : 'subscriber',
    {
      width: '100%',
      height: '100%',
    },
    handleError
  );
}

Comme il s'agit d'un exemple d'application, j'ai également ajouté, par commodité, deux boutons pour démarrer et arrêter le flux Experience Composer. Ces boutons ne seront visibles que par l'hôte, mais vous pouvez publier le flux Experience Composer par programme une fois que l'événement streamCreated de l'hôte.

Les appels de récupération pour démarrer et arrêter le flux Experience Composer sont implémentés dans le fichier src/index.js et les fonctions sont appelées en cliquant sur les boutons dans le fichier host.html.

Une autre différence importante entre l'hôte et l'Experience Composer est que nous devons explicitement demander à l'hôte de publier. Ainsi, une fois connecté à la session, nous ne publierons que s'il s'agit de l'hôte.

session.connect(token, function (error) {
  if (error) {
    handleError(error);
  } else {
    if (isHost()) {
      const publisher = OT.initPublisher(
        'publisher',
        {
          width: '100%',
          height: '100%',
          name: 'host',
        },
        handleError
      );
      publish(publisher);
    }
  }
 });

L'Experience Composer publiera automatiquement dans la session, de sorte que notre code JavaScript n'a pas besoin de demander à l'Experience Composer de publier.

Vue du compositeur d'expérience

L'Experience Composer chargera l'URL transmise côté serveur lors de l'appel à l'API. Il chargera le code JavaScript et le publiera dans la session (également transmise en tant que paramètre). Imaginez l'Experience Composer comme un utilisateur invisible qui joint l'URL, capture l'écran et publie le résultat sous forme de nouveau flux dans la session.

Puisque nous avons créé quelques fonctions d'aide pour savoir si c'est l'Experience Composer ou l'hôte qui se joint, nous pouvons empêcher l'Experience Composer de publier grâce à notre code JavaScript une fois qu'il se connecte à la session. Voir la section précédente.

Il est également important de prendre en compte le fait que l'Experience Composer n'a besoin que de s'abonner au flux de l'hôte car nous voulons que le flux publié ne contienne que le flux vidéo composite de l'hôte.

session.on('streamCreated', function (event) {
  if (isExperienceComposer() && event.stream.name === 'host') {
    subscribe(event.stream);
  }
});

Si vous regardez la mise en page souhaitée depuis la vue Experience Composer, nous devons ajouter l'abonné dans le coin supérieur droit de la page, ce qui correspond à l'élément publisher élément DOM

function subscribe(stream) {
  session.subscribe(
    stream,
    isExperienceComposer() ? 'publisher' : 'subscriber',
    {
      width: '100%',
      height: '100%',
    },
    handleError
  );
}

Il s'agit de la vue Experience Composer avec le flux abonné de l'hôte en haut à droite.

Diagram of the Experience Composer's view of the stream with a calendar to the left and on the right in a column from top to bottom is the host camera feed with a Vonage logo overlay, a data table with columns, number, status and AssigneeExperience Composer View Diagram

##Video Demo

La vidéo suivante vous montre la vue de l'hôte et la vue de l'invité.

Enregistrement et diffusion

Cette application ne prévoit pas d'archivage/enregistrement. Cependant, vous pouvez le faire en réglant le streamMode en mode "manuel" lorsque vous lancez l'archivage puis en ajoutant les flux que vous souhaitez inclure dans l'enregistrement. l'enregistrement.

Dans ce cas, nous voulons seulement que le flux d'Experience Composer et le flux de l'invité soient archivés. Sinon, si nous ajoutons les trois flux ou si nous définissons l'option streamMode à auto, nous aurions 3 flux dans l'enregistrement, dont 2 pour l'hôte.

Le flux publié par Experience composer peut également être diffusé via HLS ou RTMP à un public plus large.

Conclusion

Experience composer est une offre très puissante qui vous permet d'offrir une expérience plus riche à vos appels vidéo en publiant des flux avec à peu près tout ce à quoi vous pouvez penser, du moment que le rendu se fait sur une page web.

Vous allez essayer le nouveau Experience Composer ? Nous vous invitons à nous faire part de vos commentaires sur le Communauté Vonage Slack.

Partager:

https://a.storyblok.com/f/270183/384x384/6007824739/javier-molina-sanz.png
Javier Molina Sanz

Javier studied Industrial Engineering back in Madrid where he's from. He is now one of our Solution Engineers, so if you get into trouble using our APIs he may be the one that gives you a hand. Out of work he loves playing football and travelling as much as he can.