REPRODUCTOR DE VÍDEO BRIGHTCOVE: PLUGINS AVANZADOS

Foto de JESS R
JESS R
blog-placeholder image

Si eres usuario de Video.js desde hace tiempo, probablemente estés familiarizado con el concepto de plugins: funciones que se convierten en métodos de cualquier reproductor que crees. Si no estás familiarizado con los plugins de Video.js, disponemos de una completa guía sobre plugins.

Estos plugins -que llamaremos plugins básicos- sonligeros y ofrecen un control total del reproductor. Eso es muy útil y no está cambiando.

Pero, ¿y si desea un conjunto más amplio de funciones? ¿O más orientación sobre cómo estructurar tu plugin? ¿O más herramientas listas para usar que le ayuden a gestionar los complejos reproductores ricos en plugins?

Bueno, hasta Video.js 6.0, tenías que arreglártelas por tu cuenta.

Plugins avanzados

Uno de los puntos fuertes de Video.js es su rico ecosistema de plugins. Por eso, en los últimos meses hemos querido centrar nuestros esfuerzos en mejorar la experiencia del autor de plugins.

Aunque proyectos como el generador de plugins hacen que convertirse en autor de plugins sea más fácil que nunca, el equipo de Video.js pensó que era importante proporcionar una API básica y un conjunto de convenciones sobre las que se pudiera construir el futuro de los plugins de Video.js.

Nuestra solución son los plugins avanzados.

Los plugins avanzados son similares a los componentes

Uno de los objetivos de diseño de los plugins avanzados era ofrecer una API que recordara al sistema de componentes existente. Lo hemos conseguido de varias maneras.

En el nivel más bajo, esto incluía un cambio de nombre para la función de registro de plugins de videojs.plugin a videojs.registerPlugin (siguiendo el ejemplo de videojs.registerComponent y videojs.registerTech).

Más allá de un simple cambio de nombre del método de registro, los plugins avanzados se basan en clases. Un ejemplo trivial de un plugin avanzado podría ser algo como esto:

var Plugin = videojs.getPlugin('plugin');

var HelloWorld = videojs.extend(Plugin, {
  constructor(player) {
    Plugin.call(this, player);
    this.player.addClass('hello-world');
  }
});

videojs.registerPlugin('helloWorld', HelloWorld);

 

Si utiliza un transpilador ES6, puede utilizar clases ES6 de forma similar.

Este plugin se puede inicializar de la misma forma que un plugin básico: mediante un método player cuyo nombre coincida con el nombre registrado del plugin.

En el caso de los plugins avanzados, este método es una función de fábrica, que instancia la clase del plugin y devuelve una instancia.

Es útil saber que el método del reproductor que se cree será siempre una función. Si un reproductor ya tiene una instancia de un plugin avanzado, su método asociado simplemente devolverá la instancia preexistente en lugar de reiniciarla:

var player = videojs('my-player');
var instance = player.helloWorld();

// Logs: 'true'
videojs.log(instance === player.helloWorld());

 

En helloWorld devolverá este objeto plugin hasta que sea desechado - después de lo cual creará una nueva instancia plugin de nuevo.

Eventos

Al igual que los componentes, los plugins avanzados pueden escuchar y activar eventos a través de la función ononeofftrigger métodos.

Esto proporciona un canal de comunicación poco acoplado para que los plugins y otros objetos (componentes, reproductores, etc.) gestionen su propio estado y respondan a los cambios de estado de los demás.

Datos adicionales del evento

El sistema de eventos de Video.js permite pasar datos adicionales a los oyentes como segundo argumento al activar eventos (el primer argumento es el propio objeto del evento).

Los eventos de plugin pasan un conjunto coherente de propiedades en este objeto (incluyendo cualquier propiedad personalizada pasada a trigger):

  • instance: La instancia del plugin que desencadenó el evento.
  • name: El nombre del plugin en forma de cadena (por ejemplo. 'helloWorld').
  • plugin: La clase/función constructora del plugin (por ejemplo HelloWorld).

Por ejemplo, un listener para un evento en un plugin puede esperar algo como esto:

var player = videojs('my-player');
var instance = player.helloWorld();

instance.on('some-custom-event', function(e, data) {
  videojs.log(data.instance === instance); // true
  videojs.log(data.name === 'helloWorld'); // true
  videojs.log(data.plugin === videojs.getPlugin('helloWorld')); // true
  videojs.log(data.foo); // "bar"
});

instance.trigger('some-custom-event', {foo: 'bar'});

 

Ciclo de vida

Otra similitud entre los plugins y los componentes es el concepto de ciclo de vida, más concretamente, los procesos de instalación y desinstalación.

Obtenemos la función de configuración como un efecto secundario de la creación normal de objetos en JavaScript, pero se nos deja a nuestros propios dispositivos cuando se trata de la destrucción de objetos y asegurar que las referencias entre objetos se limpian para evitar fugas de memoria.

Hace tiempo que los componentes de Video.js dispose que se encargan de eliminar un componente del DOM y de la memoria. Los plugins avanzados tienen la misma función:

var player = videojs('my-player');

var firstInstance = player.helloWorld();

// Logs: 'true'
videojs.log(firstInstance === player.helloWorld());

firstInstance.on('dispose', function() {
  videojs.log('disposing a helloWorld instance');
});

// Logs: 'disposing a helloWorld instance'
firstInstance.dispose();

var secondInstance = player.helloWorld(); 

// Logs: 'false'
videojs.log(firstInstance === secondInstance);

 

En pluginsetup Evento

Los plugins tienen una característica del ciclo de vida que no tienen los componentes: la función pluginsetup evento.

Este evento se activa en un reproductor cuando se inicializa en él un plugin:

var player = videojs('my-player');

player.on('pluginsetup', function(e, hash) {
  if (hash.name === 'helloWorld') {
    videojs.log('A helloWorld instance was created!');
  }
});

// Logs: 'A helloWorld instance was created!'
player.helloWorld();

 

Statefulness inspirado en React

Una de las novedades más interesantes de Video.js, tanto para plugins avanzados como para componentes, es la statefulness inspirada en React. Básicamente, esto significa que todos los objetos del plugin y los objetos del componente tienen una función state que es un objeto plano que se puede utilizar para almacenar el estado variable de ese objeto. Además, existe una propiedad setState que actualiza este objeto y activa un método statechanged evento.

Este sistema permite a los plugins y componentes utilizar su naturaleza de eventos para comunicar cambios de estado en memoria a través de una API coherente:

// A static property of the constructor can be used to pre-populate state 
// for all instances.
HelloWorld.defaultState = {color: 'red'};

var player = videojs('my-player');
var instance = player.helloWorld();

instance.on('statechanged', function(e) {
  var color = e.changes.color;

  if (color) {
    videojs.log('The helloWorld color changed from "' + color.from + '" to "' + color.from + '"!');
  }
});

// Logs: 'The helloWorld color changed from "red" to "blue"!'
instance.setState({color: 'blue'});

 

Conocimiento de los plugins del reproductor

Por último, no podíamos añadir una nueva infraestructura de plugins sin trabajar en uno de los problemas más perniciosos de la gestión de combinaciones complejas de plugins: el reproductor no puede informar de qué plugins ha inicializado, o no. Para ello, el reproductor dispone de dos nuevos métodos: hasPlugin y usingPlugin. Estos métodos funcionan para ambos tipos de plugins.

En hasPlugin Método

Este método informa de si un complemento que coincide con un nombre dado está disponible en el reproductor:

var player = videojs('my-player');

// Logs: 'true'
videojs.log(player.hasPlugin('helloWorld'));

// Logs: 'false'
videojs.log(player.hasPlugin('fooBar'));

 

Este método ignora si el plugin se ha inicializado o no y se limita a informar de si se ha registrado o no.

En usingPlugin Método

Este método informa no sólo de si un complemento está disponible en un reproductor, sino también de si está actualmente activo en el reproductor:

var player = videojs('my-player');

// Logs: 'false'
videojs.log(player.usingPlugin('helloWorld'));

player.helloWorld();

// Logs: 'true'
videojs.log(player.usingPlugin('helloWorld'));

 

Una advertencia a tener en cuenta: aunque esto funciona para ambos tipos de plugins, sólo los plugins avanzados pueden cambiar este valor más de una vez. Un plugin básico no tiene incorporado un ciclo de vida o eventos, por lo que no es posible determinar si uno ha sido "desechado".

Avanza y codifica

Esperamos que estas adiciones y mejoras a la arquitectura de plugins hagan que escribir plugins Video.js sea más placentero y eliminen parte del trabajo de bajo nivel involucrado en asegurar que los plugins no estén creando fugas de memoria y otros problemas.

El diseño de los plugins avanzados es tal que podemos añadir funciones a medida que la versión 6.0 madura y recibimos más comentarios de la comunidad. Como siempre, animamos encarecidamente a nuestros usuarios a devolver al proyecto Video.js lo que puedan.

Este artículo se publicó originalmente en el blog Video.js.

Brightcove ayudó a un fabricante de equipos de diagnóstico a reducir el tiempo de clase y los gastos, a la vez que mejoraba el éxito ...
Brightcove ayudó al mercado automovilístico más reconocido a gestionar su enorme videoteca heredada y a monetizarla...
Para mantener la integridad de la marca, las marcas minoristas necesitan reproductores de vídeo personalizables que les permitan ajustar los colores, la fuente...

¿PREPARADO PARA EMPEZAR?

Póngase en contacto con nosotros para saber cómo podemos mejorar sus esfuerzos de marketing por vídeo y ayudarle a generar los resultados y el ROI que necesita.