Video.js のユーザであれば、プラグイン(作成したプレーヤーのメソッドとなる関数)の概念についてご存じでしょう。Video.js プラグインについてよくご存じない場合は、包括的なプラグイン ガイドをご覧ください。
これらのプラグイン(ここでは基本プラグインと呼ぶ)は軽量で、プレーヤーを完全にコントロールできる。これは本当に便利で、今も変わっていない。
しかし、もっと豊富な機能が欲しい場合はどうしたらいいでしょうか?あるいは、プラグインをどのように構成するかについて、より多くのガイダンスが必要ですか?あるいは、複雑なプラグインリッチプレーヤーを管理するのに役立つ、より多くのツールが必要ですか?
まあ、Video.js 6.0までは、自分で解決するしかなかった。
高度なプラグインの紹介
Video.jsの強みの1つは、豊富なプラグインのエコシステムです。そのため、ここ数ヶ月は、プラグイン作成者のエクスペリエンスを向上させることに力を注ぎたいと考えていました。
Video.jsチームは、プラグイン・ジェネレータのようなプロジェクトによって、プラグインの作者になることがこれまで以上に簡単になる一方で、Video.jsプラグインの未来を築くための基盤となるAPIと規約のセットを提供することが重要だと考えました。
私たちのソリューションは、高度なプラグインです。
高度なプラグインはコンポーネントライク
高度なプラグインの設計目標のひとつは、既存のコンポーネント・システムを彷彿とさせるAPIを提供することだった。私たちは多くの方法でこれを達成した。
最も低いレベルでは、プラグイン登録関数の名前を videojs.plugin
に videojs.registerPlugin
(ネーミングは videojs.registerComponent
& videojs.registerTech
).
単純な登録メソッド名の変更を超えて、高度なプラグインはクラスベースです。高度なプラグインの些細な例は次のようなものです:
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);
ES6トランスパイラを使用している場合は、同様の方法でES6クラスを使用できます。
このプラグインは、基本的なプラグインと同じように、プラグインの登録名と同じ名前のプレーヤー・メソッドで初期化できます。
高度なプラグインの場合、このメソッドはファクトリー関数で、プラグインクラスをインスタンス化してインスタンスを返します。
作成されるプレーヤー・メソッドは常に関数であることを知っておくと便利です。プレーヤーがすでに高度なプラグインのインスタンスを持っている場合、関連するメソッドは、それを再初期化するのではなく、既存のインスタンスを返すだけです:
var player = videojs('my-player');
var instance = player.helloWorld();
// Logs: 'true'
videojs.log(instance === player.helloWorld());
について helloWorld
メソッドは、破棄されるまでこのプラグインオブジェクトを返します - その後、新しいプラグインインスタンスを再び作成します。
イベント
コンポーネントと同様に、高度なプラグインは on
, one
, off
+ trigger
のメソッドがあります。
これは、プラグインや他のオブジェクト(コンポーネント、プレーヤーなど)が自身の状態を管理し、互いの状態の変化に応答するための疎結合の通信チャネルを提供する。
追加イベントデータ
Video.jsのイベントシステムでは、イベントをトリガーする際の第2引数として、リスナーに追加データを渡すことができます(第1引数はイベントオブジェクトそのものです)。
プラグインイベントは、このオブジェクト内の一貫したプロパティセットを渡します。 trigger
)
instance
:イベントをトリガーしたプラグインインスタンス。name
:文字列としてのプラグインの名前(例えば'helloWorld'
).plugin
:プラグインクラス/コンストラクタ関数(たとえばHelloWorld
).
例えば、プラグインのイベントのリスナーは次のようなことを期待できる:
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'});
ライフサイクル
プラグインとコンポーネントのもう一つの類似点は、ライフサイクルの概念、より具体的にはセットアップとティアダウンのプロセスである。
JavaScriptでは、通常のオブジェクト生成の副作用としてセットアップ機能を得ることができるが、オブジェクトの破棄や、メモリリークを避けるためにオブジェクト間の参照を確実にクリーンアップすることに関しては、私たちは自分たちのデバイスに任されている。
Video.jsコンポーネントには dispose
メソッドとイベントは、DOMとメモリからコンポーネントを削除する処理を行います。高度なプラグインにも同じ機能があります:
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);
について pluginsetup
イベント
プラグインには、コンポーネントにはないライフサイクル機能があります。 pluginsetup
イベント。
このイベントは、プレーヤー上でプラグインが初期化されたときにトリガーされます:
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();
リアクトに触発されたステートフルネス
先進的なプラグインとコンポーネントの両方にとって、Video.jsで追加されたエキサイティングな機能の1つは、Reactにインスパイアされたステートフルネスである。基本的に、これはすべてのプラグインオブジェクトとコンポーネントオブジェクトが state
プロパティがあり、これはプレーン・オブジェクトで、そのオブジェクトの変数の状態を保存するのに使うことができる。次に setState
このオブジェクトを更新し statechanged
イベント。
このシステムにより、プラグインとコンポーネントは、一貫性のあるAPIを通じて、イベント化された性質を利用して、メモリ内の状態変更を伝達することができる:
// 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'});
プレーヤープラグインの認識
最後に、プラグインの複雑な組み合わせを管理する上で、より悪質な問題の1つに取り組むことなく、新しいプラグイン・インフラストラクチャを追加することはできませんでした。この目的のために、プレーヤーには2つの新しいメソッドがあります: hasPlugin
& usingPlugin
.これらの方法は 両方 プラグインの種類
について hasPlugin
方法
このメソッドは、指定された名前に一致するプラグインがプレーヤーで利用可能かどうかを報告します:
var player = videojs('my-player');
// Logs: 'true'
videojs.log(player.hasPlugin('helloWorld'));
// Logs: 'false'
videojs.log(player.hasPlugin('fooBar'));
このメソッドは、プラグインが初期化されているかどうかを無視し、単に登録されているかどうかを報告する。
について usingPlugin
方法
このメソッドは、プラグインがプレーヤーで利用可能かどうかだけでなく、プレーヤーで現在有効かどうかも報告します:
var player = videojs('my-player');
// Logs: 'false'
videojs.log(player.usingPlugin('helloWorld'));
player.helloWorld();
// Logs: 'true'
videojs.log(player.usingPlugin('helloWorld'));
注意点:これはどちらのタイプのプラグインにも使えますが、この値を複数回変更できるのは上級プラグインだけです。基本的なプラグインにはライフサイクルもイベントも組み込まれていないので、"破棄 "されたかどうかを判断することはできません。
コードを書く
私たちは、プラグインアーキテクチャへのこれらの追加と改善により、Video.jsプラグインをより楽しく書けるようになり、プラグインがメモリリークやその他の問題を発生させないようにするための低レベルの足かせが取り除かれることを願っています。
先進的なプラグインの設計は、6.0が成熟し、コミュニティからのフィードバックが増えるにつれて、機能を追加できるようになっています。これまでと同様、Video.js プロジェクトには、ユーザーの皆様がどのような形であれ還元されることを強くお勧めします。
これはもともとVideo.jsブログに投稿されたものです。