# 插件化
thumbplayer-h5对外提供了插件化的能力,通过插件基类对插件安装、卸载等进行管理。播放器的插件体系部分参考了videojs播放库,在实现上更加灵活。
下面是一个简单的函数插件声明,只会绑定this到播放器实例
import { H5Player, PluginMsg, H5_PLAY_EVENT } from '@tencent/thumbplayer-h5';
// config为自定义配置参数,extra中的msg用于监听二级ext事件
H5Player.registerPlugin('functionPlugin', function(this: H5Player, config: unknown, extra: { msg: PluginMsg }) {
this.on(H5_PLAY_EVENT.VIDEO_PLAYING, console.log);
});
# 注册插件
插件总体分为2类,函数插件 和 继承自Plugin基类的子类插件。
Plugin基类提供了一系列的生命周期钩子(hookPlaySessionStart等)方便切入部分流程,同时会在销毁时移除自身事件,销毁挂载在播放器上的插件实例;函数插件则只会绑定this到player。
子类插件(可以使用脚手架 @tencent/create-thumbplayer-plugin (opens new window) 快速创建)
# 注册子类插件
import { H5Player, Plugin, H5_PLAY_EVENT } from '@tencent/thumbplayer-h5';
export class TestPlugin extends Plugin {
// 插件名,供外部引用
public static readonly pluginName = 'my-test-plugin';
public constructor(player: H5Player, public config: { test: number }, extra) {
super(player, config, extra);
// player.config是播放器初始化配置(new H5Player时传入),config是插件初始化配置(通过plugins传入)
const config = { ...player.config.testPluginConfig, ...config };
// 拿到播放器之后,可以做一些自己的事情: 插入dom、事件监听等。事件监听推荐使用hookXX方法实现
player.container.insertAdjacentHTML('beforeend', '<div>test</div>');
player.on(H5_PLAY_EVENT.VIDEO_PLAYING, console.log);
}
// 生命周期钩子在对应的流程节点自动执行,插件销毁时也会自动解除事件监听
protected hookVideoPlaying({ isFirst }) {
if (isFirst) {
console.log('视频首次开播');
}
}
}
// 注册插件,注册后可以在plugins配置传入插件名来实例化
H5Player.registerPlugin(TestPlugin.pluginName, TestPlugin);
declare module '@tencent/thumbplayer-h5' {
// 类型扩展,使player.plugins['my-test-plugin']类型为TestPlugin
export interface IPluginInstances {
[TestPlugin.pluginName]?: TestPlugin;
}
// 类型扩展(可选),使播放器初始化config的类型包含testPluginConfig?: { testConfig: number }
export interface IH5PlayerConfig {
testPluginConfig?: { testConfig: number }
}
}
# 注册函数插件
import { H5Player, H5_PLAY_EVENT } from '@tencent/thumbplayer-h5';
H5Player.registerPlugin('functionPlugin', function(this: H5Player) {
this.on(H5_PLAY_EVENT.VIDEO_PLAYING, console.log);
});
# 注销/获取插件
H5Player上提供了一组注册/注销/检测插件的静态方法
class H5Player {
/** 注册插件 */
static registerPlugin = registerPlugin;
/** 注销插件 */
static deregisterPlugin = deregisterPlugin;
/** 获取插件 */
static getPlugins = getPlugins;
/** 获取部分插件map */
static getPlugin = getPlugin;
/** 判断是否函数插件 */
static isFunctionPlugin = isFunctionPlugin;
/** 判断某个插件是否存在 */
static pluginExists = pluginExists;
}
# 使用插件
插件可以通过plugins
初始化配置创建 或者 通过createPlugin/createPlugins
方法动态创建,创建的实例可以通过player.plugins[实例名]
获取。
# 通过plugins
初始化配置
配置方式类似于babel plugin (opens new window)
const { player } = new H5Player({
container: '#h5-player',
plugins: [
// 完整参数: [实例变量名, { pluginName: 注册的插件名, ...其他配置 }]
[TestPlugin.pluginName, { pluginName: TestPlugin.pluginName, hello: 1 }],
// 如果插件名和实例变量名相同,并且不需要传入自定义配置,可以省略插件名
[TestPlugin2.pluginName],
// 也可以直接用字符串
TestPlugin3.pluginName,
// 支持插件多实例,使用场景较少
['another_test', { pluginName: TestPlugin.pluginName }],
],
});
如果需要校验插件参数类型,可以使用definePlugins
搭配as const
使用,这个工具函数会提示数组第二个元素类型为第一个元素构造函数的第二个参数:
const player = new H5Player({
container: '#h5-player',
plugins: definePlugins([
[TestPlugin, { hello: 1 }],
[TestPlugin2, { world: 2 }],
] as const),
});
# 通过createPlugin
或者createPlugins
动态创建
参数与plugins初始化配置配置一致
player.createPlugin(CtrlBarPlugin.pluginName)
player.createPlugins([
[CtrlBarPlugin.pluginName, { pluginName: CtrlBarPlugin.pluginName }],
[SubTitlePlugin.pluginName],
SubtitleControl.pluginName,
])