paint-brush
Comment créer une mise en page dynamique pour les diffusions multi-hôtes avec Amazon IVSpar@amazonivs
2,313 lectures
2,313 lectures

Comment créer une mise en page dynamique pour les diffusions multi-hôtes avec Amazon IVS

Trop long; Pour lire

Dans le dernier article, nous avons examiné comment créer une application de chat en direct multi-hôtes avec Amazon Interactive Video Service (Amazon IVS). Dans cet article, j'ai un peu triché et codé en dur les valeurs qui indiquent au client de diffusion la taille et la position du participant. vidéo sur le client. Nous allons examiner une approche que vous pourriez utiliser pour faciliter un peu la création d'une mise en page dynamique.
featured image - Comment créer une mise en page dynamique pour les diffusions multi-hôtes avec Amazon IVS
Amazon Interactive Video Service (IVS)  HackerNoon profile picture

J'ai récemment écrit quelques articles sur les flux en direct multi-hôtes avec Amazon Interactive Video Service (Amazon IVS). C'est une fonctionnalité passionnante qui ouvre des mondes de possibilités qui n'étaient tout simplement pas disponibles jusqu'à récemment. Nous avons d'abord regardé comment créer une application de chat en direct multi-hôtes .


Ensuite, nous avons vu comment diffuser cette session de chat en direct sur un canal Amazon IVS.


Lorsque nous avons envisagé d'ajouter des participants au chat au client de diffusion dans ce dernier message, vous avez probablement remarqué que j'ai un peu triché et codé en dur les valeurs VideoComposition qui indiquent au client de diffusion la taille et la position de la vidéo du participant sur le client.


Eh bien - triché est un mot fort - disons que j'ai intentionnellement simplifié le code pour me concentrer sur le processus de diffusion d'une session de chat en direct.


Essentiellement, ce que nous recherchons ici est de modifier la taille et la position de la vidéo du participant dans la diffusion afin que lorsqu'il y a une vidéo, la mise en page ressemble à ceci :



Mais lorsqu'il y a deux vidéos, la mise en page changera pour ressembler à ceci :



Et quand il y en a cinq :



Vous avez l'idée - une mise en page dynamique qui change en fonction du nombre de participants.


Dans cet article, nous examinerons une approche que vous pourriez utiliser pour faciliter un peu la création d'une mise en page dynamique. Nous allons construire à partir de la solution dans le dernier article, donc si vous n'avez pas encore lu cet article, c'est probablement une bonne idée de le faire maintenant.


Dans le dernier message, nous avons écouté un événement appelé STAGE_PARTICIPANT_STREAMS_ADDED . Dans le gestionnaire d'événements de cet événement, nous avons ajouté nos participants au DOM et rendu l'audio et la vidéo à l'instance IVSBroadcastClient .


Afin de rendre une mise en page dynamique, nous devrons suivre le nombre de participants actuellement dans la session, nous allons donc ajouter un tableau appelé participantIds en tant que variable globale. Modifions le gestionnaire d'événements pour envoyer l'identifiant du participant actuel à ce tableau.


 stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => { //add participant id to array participantIds.push(participant.id); renderParticipant(participant, streams); renderVideosToClient(participant, streams.find(s => s.streamType === StreamType.VIDEO)); renderAudioToClient(participant, streams.find(s => s.streamType === StreamType.AUDIO)); updateVideoCompositions(); });


Dans le dernier message, j'ai mentionné que la méthode updateVideoCompositions() n'était pas affichée car l'implémentation varierait. Nous parlerons d'une mise en œuvre possible dans un instant.


Pour l'instant, regardons comment nous pouvons obtenir une configuration de mise en page dynamique au lieu de la coder en dur comme nous l'avons fait dans le dernier article.


Une façon d'obtenir une taille et une position dynamiques consiste à boucler sur le tableau des participants et à les calculer en fonction du nombre de participants, de la taille du <canvas> et de la quantité souhaitée de lignes, de colonnes et de remplissage. Mais, pourquoi ?


Cela ressemble à beaucoup de code difficile et de travail inutile lorsque vous réalisez que ces valeurs ne changent jamais. Si vous avez un participant, la vidéo sera de taille fixe et centrée dans le <canvas> .


Peu importe le nombre de participants ajoutés - la mise en page de chaque vidéo sera toujours la même pour un nombre donné de participants. Alors pourquoi perdre du temps et des cycles CPU alors que nous pourrions pré-calculer ces valeurs et les stocker dans un tableau de tableaux ?


Pour ma démo, j'ai passé du temps à déterminer les meilleures valeurs avec 30 minutes intensives avec un stylo, du papier et une calculatrice pour déterminer les valeurs de composition pour chaque mise en page possible. Veuillez noter : je n'étais pas étudiant en mathématiques ou en art, comme en témoigne le croquis suivant.



Pour cette démo, j'ai limité mon flux en direct à l'affichage de vidéos uniquement pour les 6 premiers participants. Votre cas d'utilisation peut dicter quelque chose de différent, mais avoir plus de 6 vidéos de participants dans un flux en direct devient un peu trop occupé d'après mon expérience.


Voici le résultat de mes calculs :


 const layouts = [ [{ height: 720, width: 1280, x: 320, y: 180 }], [{ height: 450, width: 800, x: 80, y: 315 }, { height: 450, width: 800, x: 1040, y: 315 }], [{ height: 450, width: 800, x: 80, y: 45 }, { height: 450, width: 800, x: 1040, y: 45 }, { height: 450, width: 800, x: 560, y: 585 }], [{ height: 450, width: 800, x: 80, y: 45 }, { height: 450, width: 800, x: 1040, y: 45 }, { height: 450, width: 800, x: 80, y: 585 }, { height: 450, width: 800, x: 1040, y: 585 }], [{ height: 337, width: 600, x: 20, y: 100 }, { height: 337, width: 600, x: 650, y: 100 }, { height: 337, width: 600, x: 1280, y: 100 }, { height: 337, width: 600, x: 340, y: 640 }, { height: 337, width: 600, x: 980, y: 640 }], [{ height: 337, width: 600, x: 20, y: 100 }, { height: 337, width: 600, x: 650, y: 100 }, { height: 337, width: 600, x: 1280, y: 100 }, { height: 337, width: 600, x: 20, y: 640 }, { height: 337, width: 600, x: 650, y: 640 }, { height: 337, width: 600, x: 1280, y: 640 }] ];


Cela peut sembler écrasant, mais considérez que chaque élément de l'élément de tableau externe contient un tableau de compositions pour chaque vidéo.


S'il y a 3 participants, nous pouvons référencer le troisième élément dans le tableau externe, et la position de l'identifiant du participant dans le tableau participantIds déterminera quelle composition s'appliquera à cette vidéo.


Nous pouvons modifier notre fonction renderVideosToClient() pour saisir la composition appropriée et utiliser ces valeurs lorsque nous ajoutons la vidéo au client de diffusion.


 const renderVideosToClient = async (participant, stream) => { const participantId = participant.id; const videoId = `video-${participantId}`; // get the index of this participantId const pIdx = participantIds.indexOf(participantId); let composition = layouts[participantIds.length - 1][pIdx]; config.index = 2; const mediaStream = new MediaStream(); mediaStream.addTrack(stream.mediaStreamTrack); broadcastClient.addVideoInputDevice(mediaStream, videoId, composition); };


Mais rappelez-vous - si nous ne faisons cela que lorsqu'un participant est ajouté, les compositions vidéo précédentes refléteront toujours la composition qui a été appliquée lors de leur ajout. C'est là que la fonction updateVideoCompositions() entre en scène.


Ici, nous parcourons le tableau participantIds , récupérons la composition appropriée à partir layouts et utilisons updateVideoDeviceComposition() ( documents ) méthode de broadcastClient .


 const updateVideoCompositions = async () => { let idx = 0; for (const p of participantIds) { const videoId = `video-${p}`; let config = layouts[filteredParticipantIds.length - 1][idx]; config.index = 2; broadcastClient.updateVideoDeviceComposition(videoId, config); idx = idx + 1; } };


Nous devons également nous assurer que lorsqu'un participant quitte la scène, nous supprimons l'identifiant du participant du tableau et mettons à nouveau à jour la composition de toutes les vidéos.


 stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED, (participant, streams) => { const participantId = participant.id; // remove participant id from array const pIdx = participantIds.findIndex(id => id === participantId); participantIds.splice(pIdx, 1); const videoTrackId = `video-${participantId}`; const audioTrackId = `audio-${participantId}`; if (broadcastClient.getVideoInputDevice(videoTrackId)) broadcastClient.removeVideoInputDevice(videoTrackId); if (broadcastClient.getAudioInputDevice(audioTrackId)) broadcastClient.removeAudioInputDevice(audioTrackId); const videoId = `${participantId}-video`; document.getElementById(videoId).closest('.participant-col').remove(); updateVideoCompositions(); });


Comme mentionné ci-dessus, vous souhaiterez probablement limiter le nombre de vidéos ajoutées au flux en direct via le client de diffusion. Vous pouvez ajouter une image statique au lieu de la vidéo finale pour montrer qu'il y a plus de participants que ce qui est affiché :


Résumé

Dans cet article, nous avons appris une approche pour les mises en page dynamiques lors de la diffusion d'une étape multi-hôte avec Amazon IVS. Dans un prochain article, nous examinerons des options supplémentaires pour la diffusion avec plusieurs hôtes. Comme toujours, si vous avez des questions ou des commentaires, veuillez les laisser ci-dessous.


Également publié ici