注释Comments: 在您的 VideoJS 播放器中合作

升级 v1 - > v2
请注意基于事件的API已经改变. 在版本1中,您可以订阅插件事件
pluginInstance.on()。在第二版中,同样的功能可用pluginInstance.registerListener()。以下文件为最新版本.
关于
背景情况
视频制图师与客户端的合作可能很乏味,电子邮件和电话会浪费时间试图引用屏幕的特定框架和区域. 此插件可以让浏览器进行更有效的协作.
这个插件是作为Hack Week项目设想和开发的 内容 以 埃文·卡多尔 财务报告和审定财务报表 杰克・波普. 在Contently继续关注并致力于多媒体支持,整个团队制作并防弹插件作为灵活解决方案,用于我们的产品和其他开源使用案例.
目标
- 对录像机和客户都有效率 - 提供有用的协作特性,包括说明、评论/复制、时间标记等,以及更多的具有直觉控制.
- 模拟和照明 - 所有东西都包含在插件和玩家元素中。 没有必要建造额外的UI组件. 只要安装 VideoJS,注册插件,设置任何您想要的后端存储,并开始合作.
- 强烈的 - 插件可以与现有的注释系统相融合(就像我们在Contently中所做的那样),并且对如何存储注释的假设很少. 自定义事件可用于与外部API通信,为页面互动和数据持久性提供支持. 简单的 CSS 超接也可以允许最小努力的品牌定制,或者完全定制UI/UX.
视频JS插件
视频JS 是400k+站点使用的受欢迎的开源HTML5视频播放器库. 截至 v6 有可扩展的插件架构用于创建此插件 。 此插件是构建和测试的 视频JS v7
用起来!
安装
yarn add @contently/videojs-annotation-comments
或
npm install @contently/videojs-annotation-comments
添加到您的 VideoJS 播放器
作为构建中的脚本
// ...videojs & videojs-annotation-comments have been loaded in script tags...
var player = videojs('video-id');
var plugin = player.annotationComments(pluginOptions)
作为模块
import videojs from 'video.js'
import AnnotationComments from '@contently/videojs-annotation-comments'
videojs.registerPlugin('annotationComments', AnnotationComments(videojs))
var player = videojs('video-id')
var plugin = player.annotationComments(pluginOptions)
插件选项/ 配置
初始化插件时,您可以在选项阵列中通过来覆盖默认选项. 任何被排除的选项都设定为默认值,如下所示:
const pluginOptions = {
// Collection of annotation data to initialize
annotationsObjects: [],
// Flexible meta data object (currently used for user data, but addl data can be provided to wrap each comment with metadata - provide the id of the current user and fullname of the current user at minimum, which are required for the UI)
meta: { user_id: null, user_name: null },
// Use arrow keys to move through annotations when Annotation mode is active
bindArrowKeys: true,
// Show or hide the control panel and annotation toggle button (NOTE - if controls are hidden you must provide custom UI and events to drive the annotations - more on that in "Programmatic Control" below)
showControls: true,
// Show or hide the comment list when an annotation is active. If false, the text 'Click and drag to select', will follow the cursor during annotation mode
showCommentList: true,
// If false, annotations mode will be disabled in fullscreen
showFullScreen: true,
// Show or hide the tooltips with comment preview, and annotation shape, on marker hover or timeline activate
showMarkerShapeAndTooltips: true,
// If false, step two of adding annotations (writing and saving the comment) will be disabled
internalCommenting: true,
// If true, toggle the player to annotation mode immediately after init. (NOTE - "annotationModeEnabled" event is not fired for this initial state)
startInAnnotationMode: false
};
注释数据结构
将插件初始化 annotationsObjects ,使用以下结构:
const annotationsObjects = [{
id: 1,
range: {
start: 10,
end: 15
},
shape: {
x1: 23.47,
y1: 9.88,
x2: 60.83,
y2: 44.2
},
comments: [{
id: 1,
meta: {
datetime: '2017-03-28T19:17:32.238Z',
user_id: 1,
user_name: 'Jack Pope'
},
body: 'The first comment!'
}]
}];
程序控制
如果您想通过外部的UI元素来驱动插件或渲染插件数据,可以配置插件来隐藏内部组件,并通过自定义事件传递数据. 有两种注释Comments API事件, 外部开火 财务报告和审定财务报表 内部开火。 。 。 .
等待插件准备
在启动插件上的任何事件之前, 您必须等待它准备好 。 你可以用这个 onReady 函数在插件上 :
plugin.onReady(() => {
// do stuff with the plugin, such as fire events or setup listeners
});
支持的外部点火事件 :
这些事件是可以从您的脚本中调用以触发插件内的事件的外部动作 :
// openAnnotation : Opens an annotation within the player given an ID
plugin.fire('openAnnotation', { id: myAnnotationId });
// closeActiveAnnotation : Closes any active annotation
plugin.fire('closeActiveAnnotation');
// newAnnotation : Adds a new annotation within the player and opens it given comment data
plugin.fire('newAnnotation', {
id: 1,
range: { start: 20, end: null },
shape: { // NOTE - x/y vals are % based (Floats) in video, not pixel values
x1: null,
x2: null,
y1: null,
y2: null
},
commentStr: "This is my comment."
});
// destroyAnnotation : Removes an annotation and it's marker within the player given comment data
plugin.fire('destroyAnnotation', { id: 1 });
// newComment : Adds a new comment to an Annotation given an Annotation ID and a body
plugin.fire('newComment', { annotationId: 1, body: "My comment string" });
// destroyComment : Removes a comment from an Annotation given a Comment ID
plugin.fire('destroyComment', { id: 1 });
// addingAnnotation : Plugin enters the adding annotation state (adding an annotation at the current player timestamp)
plugin.fire('addingAnnotation');
// cancelAddingAnnotation : Plugin exits the adding annotation state
plugin.fire('cancelAddingAnnotation');
// toggleAnnotationMode : toggle annotation mode to alternative on/off value
plugin.fire('toggleAnnotationMode');
支持的内部火灾事件 :
这些事件是从运行的插件内部触发的,可以通过绑定到 plugin.registerListener 脚本中:
// annotationOpened : Fired whenever an annotation is opened
plugin.registerListener('annotationOpened', (event) => {
// event.detail =
// {
// annotation: (object) annotation data in format {id:.., comments:..., range:..., shape:...},
// triggered_by_timeline: (boolean) TRUE = the event was triggered via a timeline action (like scrubbing or playing), FALSE = the annotation was opened via marker click, UI button interactions, or API/event input
// }
});
// annotationClosed : Fired whenever an annotation is closed
plugin.registerListener('annotationClosed', (event) => {
// event.detail = annotation (object) in format {id:.., comments:..., range:..., shape:...}
});
// addingAnnotationDataChanged : Fired from adding annotation state if:
// 1. the marker is dragged
// 2. the start of the marker is moved via control buttons
// 3. the shape is dragged
plugin.registerListener('addingAnnotationDataChanged', (event) => {
var newRange = event.detail.range; // returns range data if range was changed
var newShape = event.detail.shape; // returns shape data if shape was changed
// do something with the data
});
// annotationDeleted : Fired when an annotation has been deleted via the UI
plugin.registerListener('annotationDeleted', (event) => {
// annotationId = event.detail
});
// enteredAnnotationMode : Fired when the plugin enters adding annotation mode
// includes initial range data
plugin.registerListener('enteredAddingAnnotation', (event) => {
var startTime = event.detail.range.start;
// do something when adding annotation state begins
});
// onStateChanged: Fired when plugin state has changed (annotation added, removed, etc)
// This is a way to watch global plugin state, as an alternative to watching various annotation events
plugin.registerListener('onStateChanged', (event) => {
// event.detail = annotation state data
});
// playerBoundsChanged : Fired when the player boundaries change due to window resize or fullscreen mode
plugin.registerListener('playerBoundsChanged', (event) => {
var bounds = event.detail;
// do something with the new boundaries
});
// Entering annotation mode (annotation icon was clicked when previously 'off')
plugin.registerListener('annotationModeEnabled', (event) => {
// do something
});
// Exiting annotation mode (annotation icon was clicked when previously 'on')
plugin.registerListener('annotationModeDisabled', (event) => {
// do something
});
开发和建设
我们用 线条 用于软件包管理以及 ulp 作为我们的建设系统.
最快的开始方式是:
- 清除还原
- 运行
yarn install - 运行
yarn build - 运行
yarn watch - 访问
http://localhost:3004/test.html看着魔法的到来.
模板
我们正在使用 处理栏 调试库以在插件中渲染各种组件 。 对于性能,模板在开发环境中被预编为JS文件. 这样,我们只需要要求Handlebars运行时间,从精密建筑中节省了近100克b
这个 gulp templates 任务用于预编译每个模板到 /src/js/compiled/templates.js。该文件应当 没有 直接修改,但模板本身在 /src/templates 如果需要修改,应当修改。 模板任务将在内部自动运行 gulp watch。 。 。 .
UI / CSS 自定义
插件使用 SASS , 所有样式均定义在 anotaitons.scs (英语)。文件中有关于类和样式的延伸性评论。 插件使用深层的特异性来防止样式在页面上污染元素,所有类都使用前缀 vac- 用于防止全球命名空间中的类名相撞.
您可以非常容易地通过写入一个覆盖样式表来扩展/修改颜色和元素,以解决您想要修改的特定元素。 也可以改变样式表中的可变颜色,并编译自己,以便更定制.
页:1 - 我们的gulp构建任务使用自动前置器使样式可以工作交叉浏览器,所以如果使用修改来编译 SAS 文件,请自己运行.
测试
特征测试
特性测试目前以浏览器为基础并由访问运行 http://localhost:3004/mocha/features/index.html。特性测试可以作为文件添加到 /test/mocha/features/ 目录,然后包含在 index.html 文件作为外部脚本.
单位测试
单位测试通过 gulp test 任务。 如果 tdd 任务包含在 gulp watch,测试将随测试文件的每次更改而运行。 每个模块应在 /test/mocha/modules 目录.
Gulp 命令
gulp watch: 点燃网络服务器@ http://localhost:3004/test.html,监视任何文件更改 /src,包括js, cs (scs),和模板 (.hbs),再包装,以及转接到一个未忽略的文件 /build 改变.
gulp transpile: 将文件构建到 /build 附有联署材料地图
gulp build: 运行转接、浏览器、 sass , 然后修改为分发文件名 /build 有归属
gulp templates: 使用 Handlebars 将模板预编为javascript文件. 见上文模板部分.
gulp test: 进行摩卡单元测试 /test/mocha/modules/ 目录.
gulp lint: 在 Javascript 文件上运行 jshint linter /src
许可证
此插件为 许可证 根据Apache许可证,版本2.0,这是Video.js使用的同一张许可证