
Compartir:
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.
Por qué es genial la API de Experience Composer
Tiempo de lectura: 9 minutos
Vonage ha lanzado recientemente API Experience Composer (EC). Esta oferta proporciona un servicio en la nube basado en API para capturar toda la experiencia de tu aplicación web usando la Video API de Vonage. Esto significa que la apariencia de tu aplicación web ahora se puede grabar por completo, transmitir a través de HLS o RTMP, o publicar como una nueva transmisión en una sesión de video.
En esta publicación, veremos cómo puedes usar Experience Composer para agregar una nueva transmisión de video a una sesión existente de Vonage que contenga el logotipo de tu marca, elementos HTML personalizados y un iframe con Google Calendar. Puedes ver un Video de cómo se ve la aplicación al final de esta publicación.
Host View Diagram
Imagina una sesión de planificación de proyectos entre un gestor de productos y un desarrollador de software. El jefe de producto, como anfitrión, publicará un calendario de planificación del producto con fechas límite y una tabla HTML con elementos de trabajo con asignados y estados. El vídeo del anfitrión incluirá el logotipo de la marca. La vista del anfitrión contendrá todos estos elementos, así como el vídeo del invitado.
El desarrollador de software, como invitado, es un consumidor del flujo del anfitrión que incluye el calendario, la tabla de datos y el vídeo del anfitrión con la sobreimpresión de la marca.
Requisitos previos
Una cuenta de Video API de Vonage. Si no tienes una Account, puedes registrarte y crear una.
Versión de Node.js >= 14.17.5
API de Experience Composer habilitada para su Account. Puede hacerlo en el portal de cuentas.
Utilizaremos Bootstrap de la CDN y CSS grid para acelerar el tiempo de desarrollo. No voy a entrar en los detalles de CSS, pero puedes echar un vistazo a los archivos CSS junto con el código completo en el GitHub repo.
Diagrama de arquitectura
El siguiente diagrama muestra la arquitectura de lo que vamos a construir. Todo permanecerá en una única sesión de video de Vonage, Video Session A. Para comenzar, el anfitrión, Stream A, se publicará en la sesión junto con el invitado, Stream B. Sin embargo, el invitado aún no se suscribirá al anfitrión. Experience Composer se suscribirá a la secuencia A y publicará una nueva secuencia, la secuencia A (compuesta), que contendrá el vídeo del anfitrión con la marca superpuesta junto con Google Calendar y la tabla de datos. El invitado consumirá este flujo compuesto. Ambos usuarios podrán comunicarse entre sí.
Architecture Diagram
El servidor
El servidor crea salas, crea sesiones, genera tokens y envía solicitudes a la API de Experience Composer para iniciar y detener secuencias.
Nota: actualmente, la API de Experience Composer no es compatible con el SDK del servidor de Vonage. El inicio y la detención de los flujos de Experience Composer se realizarán a través de llamadas REST.
El endpoint /render endpoint en nuestro servidor tomará el sessionId y el roomName de la petición POST de nuestro cliente. La dirección sessionId se pasa a createRender que iniciará Experience Composer y devolverá algunos datos sobre el Render. El id se extrae y se guarda en el objeto sessions en el objeto roomName como 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 });
}
});
Del mismo modo, para detener el flujo publicado por Experience Composer, nuestro endpoint /render/stop/:id tomará el Render id necesario para detener la instancia de 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 });
}
});
Nota: El código de los botones
createRenderydeleteRenderse encuentra en el archivo archivo index.js.
Para autenticar las peticiones con la API, necesitamos crear un Token Web JSON (JWT) como se explica en la documentación para desarrolladores. He utilizado el paquete jsonwebtoken de npmpero siéntete libre de usar cualquier otro paquete.
Para crear el render, tenemos que pasar unos cuantos parámetros en el cuerpo JSON según la la documentación. Algunos de los parámetros son obligatorios como url, sessionId, tokeny projectId. Preste especial atención al parámetro url . Piense que es la URL que visitará el "usuario invisible", Experience Composer. A continuación, código JavaScript se cargará para que Experience Composer sólo se suscriba al host y se publique un nuevo flujo en el archivo sessionId.
Habrá notado que en la función createRender función que hay un objeto adicional properties que contiene un parámetro name parámetro. Este nombre será útil cuando escuchemos streamCreated eventos en el lado del cliente. Vamos a volver a eso en un poco, pero todo lo que necesita saber por ahora es que este es el nombre de la corriente que vamos a publicar en la sesión.
Nuestro servidor también será responsable de servir el contenido HTML estático al cliente. Configuraremos unas cuantas rutas para las diferentes vistas de nuestra aplicación. Una ruta para el anfitrión (el presentador que publicará el calendario, la tabla, etc), otra para el invitado o consumidor del flujo del anfitrión, y una más para el Experience Composer (ese es el url que enviamos en el cuerpo JSON mencionado anteriormente).
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');
});
Del lado del cliente
Vamos a crear una aplicación de ejemplo Vanilla JS, pero puedes utilizar Experience Composer con cualquier framework de tu elección. El código del lado del cliente se encuentra en la carpeta carpeta src.
Vista de invitados
Piense en el invitado como un espectador del flujo compuesto del anfitrión, al tiempo que envía su vídeo y audio para comunicarse con el anfitrión.
El código de la vista de invitado se encuentra en el archivo HTML user.html con JavaScript y CSS incluidos. El invitado publicará su flujo de vídeo y sólo se suscribirá al flujo publicado por Experience Composer. Podemos suscribirnos selectivamente a la secuencia publicada por Experience Composer porque establecemos un nombre para la secuencia.
Cuando configuremos el streamCreated sólo nos suscribiremos al flujo si el nombre del flujo es EC. Esto es para evitar que el invitado se suscriba al flujo de vídeo normal del anfitrión (sin tabla, superposición e 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
);
}
});Este es el aspecto de la vista de invitados. Puede ver dos flujos diferentes. A la izquierda, el invitado publica su flujo de vídeo, mientras que a la derecha se suscribe al flujo compuesto publicado por Experience Composer, que contiene el flujo de vídeo del anfitrión, el calendario, la superposición y la tabla de datos.
Guest View Diagram
Vista del anfitrión
El anfitrión, en este caso, es la persona que publicará el feed de vídeo junto con algunos elementos personalizados específicos de la aplicación. En esta vista, el anfitrión tiene su fuente de vídeo y se suscribirá a la fuente de vídeo del invitado. El diseño de la vista del anfitrión también tendrá los elementos personalizados (calendario de Google, una tabla de datos y una superposición de marca) que el Experience Composer publicará en la sesión.
La vista host se cargará en la /host ruta de nuestra aplicación. También decidí añadir un parámetro de consulta para identificar el host y el Experience Composer. Así que la ruta completa de nuestro host será ${applicationUrl}/host?role=host.
De nuevo, este es el aspecto que tendrá la vista del host.
Host View Diagram
El host y Experience Composer compartirán el mismo archivo archivo JavaScript pero tendrán archivos HTML independientes. El archivo de marcado para el host puede encontrarse aquí. Para determinar si host o EC, he creado dos funciones, isHost y isExperienceComposer.
function isHost() {
return queryString === '?role=host' && window.location.pathname === '/host';
}
function isExperienceComposer() {
return (
queryString === '?role=experience_composer' &&
window.location.pathname === '/ec'
);
}
Esto nos permitirá suscribirnos selectivamente a los flujos que necesitemos. El host no necesita suscribirse al stream creado por el Experience Composer porque entonces se estaría suscribiendo a su propio stream. Por lo tanto podemos suscribirnos selectivamente al stream cuyo nombre es diferente de EC.
session.on('streamCreated', function (event) {
if (isHost() && event.stream.name !== 'EC') {
subscribe(event.stream);
}
});
La función subscribe decidirá dónde añadir el editor en función de si es el anfitrión o el Experience Composer quien se suscribe a la secuencia. Si es el anfitrión el que intenta suscribirse, querremos anexar el vídeo del otro usuario (invitado) al elemento DOM cuyo id es subscriberen la parte inferior derecha de la vista Host.
function subscribe(stream) {
session.subscribe(
stream,
isExperienceComposer() ? 'publisher' : 'subscriber',
{
width: '100%',
height: '100%',
},
handleError
);
}Dado que se trata de una aplicación de ejemplo, también he añadido por comodidad dos botones para iniciar y detener la secuencia de Experience Composer. Estos botones sólo serán visibles para el anfitrión, pero puede publicar la secuencia de Experience Composer mediante programación una vez que se active el evento para el anfitrión. streamCreated para el anfitrión.
Las llamadas de obtención para iniciar y detener el flujo de Experience Composer se implementan en el archivo src/index.js y las funciones se ejecutan haciendo clic en los botones del archivo archivo host.html.
Otra diferencia importante entre el host y el Experience Composer es que necesitamos decirle explícitamente al host que publique. Así, una vez conectados a la sesión, solo publicaremos si se trata del host.
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);
}
}
});Experience Composer publicará automáticamente en la sesión, por lo que no es necesario que nuestro código JavaScript indique a Experience Composer que publique.
Vista Experience Composer
Experience Composer cargará la URL que pasamos al servidor al realizar la llamada a la API. Cargará el código JavaScript y lo publicará en la sesión (que también se pasa como parámetro). Piense en Experience Composer como un usuario invisible que se une a la URL, captura la pantalla y publica el resultado como un nuevo flujo en la sesión.
Dado que hemos creado algunas funciones de ayuda para saber si es el Experience Composer o el host el que se une, podemos evitar que el Experience Composer publique a través de nuestro código JavaScript una vez que se conecte a la sesión. Véase la sección anterior.
También es importante tener en cuenta que Experience Composer sólo necesita suscribirse a la secuencia del anfitrión porque queremos que la secuencia publicada sólo contenga la fuente de vídeo compuesto del anfitrión.
session.on('streamCreated', function (event) {
if (isExperienceComposer() && event.stream.name === 'host') {
subscribe(event.stream);
}
});
Si echas un vistazo al diseño deseado desde la vista de Experience Composer, tenemos que añadir el suscriptor a la esquina superior derecha de la página, que corresponde al elemento publisher elemento DOM
function subscribe(stream) {
session.subscribe(
stream,
isExperienceComposer() ? 'publisher' : 'subscriber',
{
width: '100%',
height: '100%',
},
handleError
);
}Esta es la vista de Experience Composer con el flujo suscrito desde el host en la parte superior derecha.
Experience Composer View Diagram
##Video Demo
El siguiente Video le muestra la vista host y la vista guest.
Grabación y radiodifusión
Esta aplicación no implementa el archivado/grabación. Sin embargo, puede hacerlo configurando el streamMode en modo "manual" cuando iniciar el archivado y luego añadiendo los flujos que desea incluir en la grabación.
En este caso, sólo queremos tener archivados el stream de Experience Composer y el stream del invitado. De lo contrario, si añadimos los tres flujos o establecemos streamMode a auto, tendríamos 3 streams en la grabación, 2 de los cuales serían del huésped.
El flujo publicado por Experience composer también puede difundirse a través de HLS o RTMP a un público más amplio.
Conclusión
Experience Composer es una oferta muy potente que te permite ofrecer una experiencia más rica a tus videollamadas publicando secuencias con prácticamente cualquier cosa que se te ocurra, siempre que se renderice en una página web.
¿Vas a probar el nuevo Experience Composer? Agradecemos tus comentarios en Slack de la comunidad de Vonage.