El middleware es una de las novedades más interesantes de la versión 6.0 de Video.js.
Con el middleware, ahora puedes interactuar y cambiar la forma en que el reproductor y la tecnología se comunican entre sí. La tecnología es la abstracción de Video.js del reproductor, separando la API del reproductor de la tecnología de reproducción. Con las tecnologías, podemos añadir cosas como un Flash fallback o una incrustación de Youtube en Video.js sin cambiar la API externa o la apariencia del reproductor.
Los middleware Video.js son como los middleware Express, pero las rutas se basan en los tipos MIME de vídeo.
Muchos usuarios de Video.js pueden estar familiarizados con middleware de proyectos como Express. Video.js middleware no es tan diferente de aquellos. En ambos casos se registra el middleware contra una ruta en particular para llamar a la cadena cuando la ruta se activa. En Express, las rutas se basan en las rutas url. En Video.js, estas rutas se basan en el tipo MIME del vídeo. Y, como en Express, hay rutas "estrella" (*
) que coinciden con todas las rutas.
Hay que tener en cuenta dos aspectos importantes del middleware:
- Gestión dinámica de fuentes
- Interceptar las interacciones entre el jugador y la tecnología
Catálogo de vídeos
Con el manejo de fuentes dinámicas, podrías cargar vídeo con un tipo y fuente personalizados y resolverlo de forma asíncrona. Un buen ejemplo de esto es un sistema de catálogo de vídeo. La página puede ser renderizada con un ID de catálogo específico y un tipo MIME especial, así:
<video controls class="video-js">
<source src="123" type="video/my-catalog">
</video>
Entonces, podría registrar un middleware para esa ruta - el tipo video/my-catalog
.
// middleware methods get the player instance as an argument
videojs.use('video/my-catalog', function(player) {
// middleware are expected to return an object with the methods on it.
// It can be a plain object or an instance of something.
return {
// setSource allows you to tell Video.js whether you're going to be handling the source or not
setSource(srcObj, next) {
const id = srcObj.src;
videojs.xhr({
uri: '/getVideo?id=' + id
}, function(err, res, body) {
// pass null as the first argument to say everything is going fine and we can handle it.
next(null, {
src: body.sourceUrl,
type: body.sourceType
})
});
}
};
});
Entonces, cuando Video.js se inicialice, llamará a los middleware que están configurados para video/my-catalog
.
Inserción de anuncios en el servidor
La inserción de anuncios en el lado del servidor (SSAI) encaja a la perfección en el middleware. Muestra la capacidad de interceptar las interacciones de reproducción y tecnología. Por ejemplo, tiene un anuncio de 30 segundos seguido de un vídeo de cinco minutos en su manifiesto HLS. Quieres que la línea de tiempo muestre el tiempo del anuncio y el tiempo del contenido apropiado cuando cada uno se está reproduciendo. Ahora mismo, la duración mostrada será la duración combinada de cinco minutos y 30 segundos (5:30
). La solución es añadir un middleware que sepa cuándo se está reproduciendo el anuncio y le diga al reproductor que la duración es de 30 segundos y cuando se esté reproduciendo el contenido que la duración es de cinco minutos.
// register a star-middleware because HLS has two mimetypes
videojs.use('*', function(player) {
return {
setSource(srcObj, next) {
const type = srcObj.type;
if (type !== 'application/x-mpegurl' && type !== 'application/vnd.apple.mpegurl') {
// call next with an error to signal you cannot handle the source
next(new Error('Source is not an HLS source'));
} else {
// in here we know we're playing back an HLS source.
// We don't want to do anything special for it, so, pass along the source along with a null.
next(null, srcObj);
}
},
// this method gets called on the tech and then up the middleware chain providing the values as you go along
duration(durationFromTech) {
if (areWeCurrentlyPlayingAnAd(durationFromTech)) {
// since we're now in an ad, return the ad duration
// in a real example you'd calculate this based on your playlist
// rather than hardcode a value in here
return 30;
} else {
// we're playing back content, so, return that duration
return 5 * 60;
}
}
}
});
Ajuste de la tasa de reproducción: estudio de un caso
Un middleware sencillo pero interesante es el ajustador de velocidad de reproducción. Este middleware cambiará los tiempos de los controles dependiendo de la tasa actual. Por ejemplo, si estás reproduciendo un vídeo de 20 minutos y cambias la velocidad a 2x, los controles se ajustarán para mostrar 10 minutos. Echemos un vistazo al código.
videojs.use('*', function(player) {
/* ... */
return {
setSource(srcObj, next) {
next(null, srcObj);
},
duration(dur) {
return dur / player.playbackRate();
},
/* ... */
};
});
Así que, aquí, adjuntamos un star-middleware porque queremos que se aplique a cualquier vídeo, independientemente del tipo MIME. En setSource
también llamamos next
directamente con null
y el srcObj
porque queremos utilizar este middleware con todas y cada una de las fuentes. También configuramos nuestro duration
para tomar la duración del middleware anterior y dividirla por la tasa de reproducción que obtenemos del reproductor.
Si nos fijamos en el código puedes ver algunos otros métodos junto a la duración. Están ahí para asegurarse de que otros métodos que dependen de la duración se actualizan. Los dos métodos a notar son currentTime
y setCurrentTime
. currentTime
se llama cuando queremos saber cuál es la hora actual. setCurrentTime
se llama cuando estamos buscando. Debido a que el usuario está buscando en el tiempo desplazado, queremos aplicar nuestra operación de cambio a la inversa. En lugar de dividirlo, queremos multiplicarlo.
currentTime(ct) {
return ct / player.playbackRate();
},
setCurrentTime(ct) {
return ct * player.playbackRate();
},
Si aplicaras lo que hemos hecho hasta ahora, notarás que nada cambia, la barra de control sigue mostrando una duración de 20 minutos. Esto es porque hasta donde Video.js sabe, nada ha cambiado. Por lo tanto, tenemos que decirle a Video.js que la duración ha cambiado. Podemos hacer eso almacenando la tecnología que Video.js nos da después de la selección de la fuente se ha completado.
videojs.use('*', function(player) {
let tech;
return {
setTech(newTech) {
tech = newTech;
}
/* ... */
};
});
Y luego, cuando el ratechange
le decimos a Video.js que la duración ha cambiado y Video.js actualizará los controles en consecuencia:
videojs.use('*', function(player) {
let tech;
player.on('ratechange', function() {
tech.trigger('durationchange');
tech.trigger('timeupdate');
});
return {
/* ... */
}
});
Vea un ejemplo en vivo y el código completo.
Este artículo se publicó originalmente en el blog Video.js.