videojs文档翻译Guides-Plugins
Video.js Plugins
Video.js的一大优势在于其插件生态系统,允许来自世界各地的作者分享他们的视频播放器定制。这包括从最简单的UI调整到新的播放技术和资源处理程序的一切!
因为我们将插件视为Video.js的重要组成部分,所以该组织致力于维护一套强大的插件作者工具:
generator-videojs-plugin
一个Video.js插件项目的Yeoman脚手架生成器。此外,它提供了一组插件作者的约定,如果遵循,使作者,贡献和使用一致和可预测。简而言之,生成器使插件作者专注于编写他们的插件 - 不会弄乱工具。
videojs-spellbook
从版本3开始,插件生成器包括一个新的依赖关系:videojs-spellbook。 Spellbook是一个插件开发工具:它构建插件,创建标签,运行开发服务器等。
Spellbook的好处是,您可以运行生成器一次,并在Spellbook中接收更新和错误修复,而无需再次运行生成器并处理Yeoman冲突和其他头痛。
只要您的插件项目遵循约定,Spellbook应该可以工作!
Writing a Basic Plugin
如果以前写过一个Video.js插件,基本的插件概念应该是熟悉的。 它类似于jQuery插件,其核心思想是您正在向播放器添加一种方法。
写一个JavaScript函数
一个基本的插件是一个纯粹的JavaScript函数:
function examplePlugin(options) {
if (options.customClass) {
this.addClass(options.customClass);
}
this.on('playing', function() {
videojs.log('playback began!');
});
}
按照惯例,插件会传递一个选项对象; 然而,事实上你可以接受任何你想要的参数。 此示例插件将添加一个自定义类(无论以options.customClass的形式传入),并且在播放开始时,它会将消息记录到浏览器控制台。
注意:插件函数中的this值是播放器实例; 因此,您可以访问其完整的API。
注册一个基本插件
现在我们有一个与播放器有关的函数,剩下的就是用Video.js注册插件:
videojs.registerPlugin('examplePlugin', examplePlugin);
之后,任何player将自动在其原型上拥有一个examplePlugin方法!
注意:插件名称的唯一规定是它不能与任何现有的插件或播放器方法冲突。
编写高级插件
Video.js 6引入了高级插件:这些插件与基本插件共享类似的API,但是基于类,并提供一系列额外的功能开箱即用。
在阅读以下部分时,您可能需要参考Plugin API文档以获取更多详细信息。
编写一个JavaScript类/构造函数
如果您熟悉创建组件,则此过程是类似的。 一个高级插件从一个JavaScript类(a.k.a.一个构造函数)开始。
如果您已经使用ES6,您可以使用你选择的解析器/语言的语法(Babel,TypeScript等):
const Plugin = videojs.getPlugin('plugin');
class ExamplePlugin extends Plugin {
constructor(player, options) {
super(player, options);
if (options.customClass) {
player.addClass(options.customClass);
}
player.on('playing', function() {
videojs.log('playback began!');
});
}
}
Or
with ES5:
var Plugin = videojs.getPlugin('plugin');
var ExamplePlugin = videojs.extend(Plugin, {
constructor: function(player, options) {
Plugin.call(this, player, options);
if (options.customClass) {
player.addClass(options.customClass);
}
player.on('playing', function() {
videojs.log('playback began!');
});
}
});
现在,这个例子的高级插件与上述基本插件完全相同 - 不用担心,随着我们的继续,我们会使它更有趣!
注册一个高级插件
高级插件的注册过程与基本插件的过程相同。
videojs.registerPlugin('examplePlugin', ExamplePlugin);
注意:由于ES6类是JavaScript中现有构造函数和原型体系结构之上的语法糖,在所有情况下,registerPlugin的第二个参数是一个函数。
与基本插件的主要区别
高级插件与基本插件有两个主要区别,在描述其高级功能之前,这些插件很重要。
The Value of this
使用基本的插件,这个插件函数的值将是播放器。
使用高级插件,this的值是插件类的实例。 播放器作为其第一个参数传递给插件构造函数(并自动作为播放器属性应用于插件实例),并且之后传递任何其他参数。
The Player Plugin Name Property
通过调用播放器一个与插件匹配的名字的方法来设置基本插件和高级插件。(例如,player.examplePlugin())
However, with advanced plugins, this method acts like a factory function and it is replaced for the current player by a new function which returns the plugin instance:
然而,使用高级插件,此方法的作用就像工厂函数,并且通过返回插件实例的新函数替换当前播放器:
// `examplePlugin` has not been called, so it is a factory function.
player.examplePlugin(); // `examplePlugin` is now a function that returns the same instance of
// `ExamplePlugin` that was generated by the previous call.
player.examplePlugin().someMethodName();
使用基本插件,该方法不会改变 - 它始终是相同的功能。 基本插件的作者可以处理对其插件功能的多次调用。
高级插件的特点
到目前为止,我们的示例高级插件在功能上与我们的示例基本插件相同。 然而,高级插件带来了很多不是内置基本插件的好处。
Events
与组件一样,高级插件提供事件的实现。 这包括:
能够使用on或one来监听插件实例上的事件:
player.examplePlugin().on('example-event', function() {
videojs.log('example plugin received an example-event');
});能够在插件实例上触发自定义事件:
player.examplePlugin().trigger('example-event');能够使用off停止监听插件实例上的自定义事件:player.examplePlugin().off('example-event');
通过提供内置的事件系统,高级插件为大多数Web开发人员熟悉的模式提供了更广泛的代码结构选项。
Statefulness
为高级插件引入的新概念是statefulness。 这类似于React组件的state属性和setState方法。
高级插件实例每个都有一个状态属性,它是一个纯JavaScript对象 - 它可以包含插件作者想要的任何键和值。
可以通过向插件构造函数添加静态属性来提供默认状态:
ExamplePlugin.defaultState = {
customClass: 'default-custom-class'
};
当状态通过setState方法更新时,插件实例会触发一个“statechanged”事件,但只有当事情发生变化时! 此事件可用作更新DOM或执行其他操作的信号。 传递给此事件的侦听器的事件对象包括,一个描述发生在state属性上的更改的对象:
player.examplePlugin().on('statechanged', function(e) {
if (e.changes && e.changes.customClass) {
this.player
.removeClass(e.changes.customClass.from)
.addClass(e.changes.customClass.to);
}
});
player.examplePlugin().setState({customClass: 'another-custom-class'});
Lifecycle
与组件相似,高级插件具有生命周期。 它们可以使用其工函数创建,并且可以使用其dispose法进行销毁:
// set up a example plugin instance
player.examplePlugin(); // dispose of it anytime thereafter
player.examplePlugin().dispose();
dispose方法有几个作用:
- 触发插件实例上的“dispose”事件。
- 清理插件实例上的所有事件侦听器,这有助于避免在清除对象后触发事件引起的错误。
- 删除插件状态和播放器的引用以避免内存泄漏。
- 将播放器的命名属性(例如player.examplePlugin)恢复回原始工厂功能,因此可以重新设置插件。
此外,如果播放器被销毁,所有高级插件实例的销毁也将被触发。
高级示例高级插件
接下来是一个完整的ES6高级插件,当播放器的状态在播放和暂停之间改变时,会记录自定义消息。 它使用所有描述的高级功能:
import videojs from 'video.js';
const Plugin = videojs.getPlugin('plugin');
class Advanced extends Plugin {
constructor(player, options) {
super(player, options);
// Whenever the player emits a playing or paused event, we update the
// state if necessary.
this.on(player, ['playing', 'paused'], this.updateState);
this.on('statechanged', this.logState);
}
dispose() {
super.dispose();
videojs.log('the advanced plugin is being disposed');
}
updateState() {
this.setState({playing: !player.paused()});
}
logState(changed) {
videojs.log(`the player is now ${this.state.playing ? 'playing' : 'paused'}`);
}
}
videojs.registerPlugin('advanced', Advanced);
const player = videojs('example-player');
player.advanced();
// This will begin playback, which will trigger a "playing" event, which will
// update the state of the plugin, which will cause a message to be logged.
player.play();
// This will pause playback, which will trigger a "paused" event, which will
// update the state of the plugin, which will cause a message to be logged.
player.pause();
player.advanced().dispose();
// This will begin playback, but the plugin has been disposed, so it will not
// log any messages.
player.play();
这个例子在现实中可能有点毫无意义,但它表明了高级插件在基本插件上提供的灵活性。
设置一个插件
在播放器上设置(或初始化)插件有两种方法。 这两种方式对于基本和高级插件都是相同的。
第一种方式是创建播放器期间。 使用插件选项,可以在播放器上自动设置插件:
videojs('example-player', {
plugins: {
examplePlugin: {
customClass: 'example-class'
}
}
});
另外,可以手动设置插件:
var player = videojs('example-player');
player.examplePlugin({customClass: 'example-class'});
这两种方法在功能上是相同的 - 使用你喜欢的任何一种!
videojs文档翻译Guides-Plugins的更多相关文章
- videojs文档翻译-api
直播流地址 rtmp://live.hkstv.hk.lxdns.com/live/hks API 接口 (一) Modules 模块 1) browser :浏览器 2) ...
- videojs文档翻译-Player(v6.0.0-RC.2)
Player 当使用任何Video.js设置方法初始化视频时,将创建Player类的实例. 创建实例后,可以通过两种方式在全局访问: 调用videojs('example_video_1');直接通过 ...
- videojs文档翻译Guides-components
components Components Video.js播放器的架构围绕组件. Player类和所有表示播放器控件和其他UI元素的类都继承自Component类. 这种架构使得可以轻松地以反映DO ...
- videojs文档翻译-EventTarget
EventTarget new EventTarget() EventTarget是一个可以与DOM EventTarget具有相同API的类. 它增加了包含冗长功能的缩写功能. 例如:on函数是 ...
- videojs文档翻译-SeekBar
SeekBar 拖动条和进度条的容器. 使用PlayProgressBar作为其栏. 构造函数 new SeekBar(player, optionsopt) 创造此类的实例 Parameters: ...
- 前端视频直播技术总结及video.js在h5页面中的应用
全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/12557070.html,多谢,=.=~ (如果对你有帮助的话请帮我点个赞啦) 目前有一个需求是在 ...
- 一款开源免费跨浏览器的视频播放器--videojs使用介绍
最近项目中的视频功能,需要做到浏览器全兼容,所以之前用html5实现的视频功能就需要进行改造了.在网上翻了个遍,试来试去,在所有的视频播放器中,就数它最实际了.首先我们来看看它的优点: 1.它是开源免 ...
- 【转】一款开源免费跨浏览器的视频播放器--videojs使用介绍
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)(二)
Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Logging raw data(记录原始数据) Logging the raw ...
随机推荐
- Pytorch CNN网络MNIST数字识别 [超详细记录] 学习笔记(三)
目录 1. 准备数据集 1.1 MNIST数据集获取: 1.2 程序部分 2. 设计网络结构 2.1 网络设计 2.2 程序部分 3. 迭代训练 4. 测试集预测部分 5. 全部代码 1. 准备数据集 ...
- Winform中用户自定义控件中外部设置子控件属性的方法
假设我们新建立一个用户自定义控件,由一个lable1和pictureBox1组成 此时我们在外部调用该控件,然后想动态改变lable1的值,我们该怎么办? 假设实例化的用户控件名为UserContro ...
- Mysql优化(出自官方文档) - 第十篇(优化InnoDB表篇)
Mysql优化(出自官方文档) - 第十篇(优化InnoDB表篇) 目录 Mysql优化(出自官方文档) - 第十篇(优化InnoDB表篇) 1 Optimizing Storage Layout f ...
- 基于ILI9341的TFT液晶显示模组LCM240320详解(1)
Hello,大家好,今天我们来讨论当下非常流行的TFT液晶显示模组,它最大的特点是可以显示出效果非常好的彩色信息,绝大多数手机.液晶显示器,液晶电视.MID.MP4等产品都在使用它,你想抗拒它的魅力还 ...
- 《手把手教你》系列基础篇之(三)-java+ selenium自动化测试- 启动三大浏览器(上)(详细教程)
1.简介 前边宏哥已经将环境搭建好了,今天就在Java项目搭建环境中简单地实践一下: 启动三大浏览器.按市场份额来说,全球前三大浏览器是:IE.Firefox.Chrome.因此宏哥这里主要介绍一下如 ...
- 高性能的Redis之对象底层实现原理详解
对象 在前面的数个章节里, 我们陆续介绍了 Redis 用到的所有主要数据结构, 比如简单动态字符串(SDS).双端链表.字典.压缩列表.整数集合, 等等. Redis 并没有直接使用这些数据结构来实 ...
- Ant Design Blazor 组件库的路由复用多标签页介绍
最近,在 Ant Design Blazor 组件库中实现多标签页组件的呼声日益高涨.于是,我利用周末时间,结合 Blazor 内置路由组件实现了基于 Tabs 组件的 ReuseTabs 组件. 前 ...
- 对象池技术和通用实现GenericObjectPool
对象池技术其实蛮常见的,比如线程池.数据库连接池 他们的特点是:对象创建代价较高.比较消耗资源.比较耗时: 比如 mysql数据库连接建立就要先建立 tcp三次握手.发送用户名/密码.进行身份校验.权 ...
- 『心善渊』Selenium3.0基础 — 29、使用HTMLTestRunner生成unittest的HTML报告
目录 1.HTMLTestRunner介绍 2.HTMLTestRunner的使用 3.测试报告示例 4.封装成模块 1.HTMLTestRunner介绍 HTMLTestRunner是一个基于uni ...
- Django基础-002 Models的属性与字段
1.models字段类型 AutoField():一个IntegerField,根据可用ID自动递增.如果没指定主键,就创建它自动设置为主键. IntegerField():一个整数: FloatFi ...