En nuestra última publicación, aprendimos cómo crear un "escenario" virtual para crear una experiencia de chat de video en tiempo real para hasta 12 participantes con Amazon Interactive Video Service (Amazon IVS). Como función independiente, es bastante poderosa y nos permite agregar colaboración en tiempo real a nuestras aplicaciones. Sin embargo, esta función se creó para permitir a los desarrolladores crear fácilmente experiencias colaborativas de transmisión en vivo similares a la función "Estrella invitada" en Twitch. En esta publicación, nos basaremos en la demostración anterior para combinar las fuentes de audio y video de todos los participantes en una sola fuente y transmitir esa fuente a un canal de Amazon IVS.
Si aún no ha leído la publicación anterior, debe hacerlo antes de continuar con esta publicación. En resumen, en esa publicación aprendimos cómo:
Cree un recurso de etapa con AWS SDK para JavaScript (v3)
Cree tokens de participantes de una etapa con AWS SDK para JavaScript (v3)
Use el SDK de transmisión web para conectarse al escenario virtual para chatear por video en tiempo real entre los participantes
El siguiente paso para crear una experiencia colaborativa de transmisión en vivo es combinar (o "componer") a los participantes locales y remotos en una sola transmisión que se puede publicar en un canal de Amazon IVS. Para esto también podemos usar el SDK de Web Broadcast, así que veamos cómo se hace.
Si recuerda, en la última publicación teníamos varias funciones llamadas dentro de un controlador DOMContentLoaded
que habilitaba permisos, obtenía dispositivos, configuraba la instancia Stage
y manejaba unirse al escenario. Agregaremos un método más a este flujo llamado initBroadcastClient()
que podemos usar para crear una instancia de IVSBroadcastClient
. Necesitaremos un elemento <canvas>
en nuestro marcado para la transmisión combinada para que nuestros participantes puedan obtener una vista previa de lo que finalmente se transmitirá al canal Amazon IVS.
const initBroadcastClient = async () => { broadcastClient = IVSBroadcastClient.create({ streamConfig: IVSBroadcastClient.STANDARD_LANDSCAPE, ingestEndpoint: '[YOUR INGEST ENDPOINT]', }); const previewEl = document.getElementById('broadcast-preview'); broadcastClient.attachPreview(previewEl); const bgImage = new Image(); bgImage.src = '/images/stage_bg.png'; broadcastClient.addImageSource(bgImage, 'bg-image', { index: 0 }); };
Para hacer las cosas un poco más atractivas visualmente, he usado addImageSource()
para agregar una imagen de fondo a la transmisión. El método addImageSource()
recibe tres argumentos: la imagen, un nombre único para la fuente y un objeto VideoComposition
que se usa para definir el index
(o 'capa') de la fuente. Si revisas elVideoComposition
, también notará que puede contener valores para la height
, width
, la posición x
e y
para la fuente. Aprovecharemos esas propiedades en un momento cuando agreguemos nuestras capas de video para cada participante.
A continuación, agregaremos el audio y el video de cada participante al cliente de transmisión. Haremos esto dentro del controlador StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED
que definimos en la publicación anterior. Modifique esa función para agregar llamadas a dos nuevas funciones.
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => { renderParticipant(participant, streams); renderVideosToClient(participant, streams.find(s => s.streamType === StreamType.VIDEO)); renderAudioToClient(participant, streams.find(s => s.streamType === StreamType.AUDIO)); });
Ahora vamos a crear la función renderVideosToClient()
. Aquí, estoy codificando VideoComposition
a valores apropiados para un solo participante. En su aplicación, querrá calcular dinámicamente los valores de height
, width
, x
e y
según la cantidad de usuarios que participan actualmente en la conversación.
const renderVideosToClient = async (participant, stream) => { const participantId = participant.id; const videoId = `video-${participantId}`; const composition = { index: 1, height: 984, width: 1750, x: 85, y: 48 }; const mediaStream = new MediaStream(); mediaStream.addTrack(stream.mediaStreamTrack); broadcastClient.addVideoInputDevice(mediaStream, videoId, composition); };
La función renderAudioToClient()
parece similar, pero usa el método addAudioInputDevice()
del SDK para agregar la pista de audio.
const renderAudioToClient = async (participant, stream) => { const participantId = participant.id; const audioTrackId = `audio-${participantId}`; const mediaStream = new MediaStream(); mediaStream.addTrack(stream.mediaStreamTrack); broadcastClient.addAudioInputDevice(mediaStream, audioTrackId) };
En este punto, el escenario está listo para transmitirse a un canal llamando broadcastClient.startBroadcast('[YOUR STREAM KEY]')
. También tendremos que gestionar la eliminación de los participantes de broadcastClient
cuando abandonen un escenario. Para ello, actualice el controlador de StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED
.
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED, (participant, streams) => { const videoTrackId = `video-${participant.id}`; const audioTrackId = `audio-${participant.id}`; if (broadcastClient.getVideoInputDevice(videoTrackId)) broadcastClient.removeVideoInputDevice(videoTrackId); if (broadcastClient.getAudioInputDevice(audioTrackId)) broadcastClient.removeAudioInputDevice(audioTrackId); const videoId = `${participant.id}-video` document.getElementById(videoId).closest('.participant-col').remove(); updateVideoCompositions(); // function not defined in demo, implementation will vary });
Así es como se vería una implementación con un solo participante. Tenga en cuenta que cada participante de la etapa se mostrará en la pantalla inferior y la vista compuesta que se transmitirá se muestra arriba.
Y cuando varios participantes se han unido al escenario virtual, la aplicación ajusta el diseño para acomodar a cada participante.
Cuando el participante "anfitrión" haga clic en el botón "Transmitir", la conversación combinada se transmitirá al canal de Amazon IVS como una vista compuesta con el audio y el video de todos los participantes combinados en una sola transmisión.
En esta publicación, aprendimos cómo crear una transmisión en vivo con audio y video de múltiples participantes remotos. En una publicación futura, examinaremos opciones alternativas para crear la transmisión compuesta y transmitirla a un canal de Amazon IVS.