# @contently/videojs-annotation-comments 中文文档

规范地址：https://npmcn.com/package/%40contently/videojs-annotation-comments/

版本：2\.0\.1
npm 元数据更新时间：2022-04-05T01:06:44.862Z
中文译文更新时间：2026-11-10T16:39:33.356Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40contently/videojs-annotation-comments
原文对照：https://npmcn.com/package/%40contently/videojs-annotation-comments/?lang=original
项目主页：https://github.com/contently/videojs-annotation-comments#readme
源码仓库：https://github.com/contently/videojs-annotation-comments

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：2.4 MB，9 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- 运行依赖：1 个
- peer 依赖：jquery ^3，video\.js ^7
- 首次发布：2019-01-18T22:11:49.705Z
- 最新版本发布：2020-01-30T14:29:35.656Z
- 近 30 天下载量：62307（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：7（近 12 个月 0 个）

## 中文简介

用于 video.js 的插件, 用于添加对时间时刻/ 距离注释和说明的支持

## 安装

```sh
npm install @contently/videojs-annotation-comments
```

也可以使用：`pnpm add @contently/videojs-annotation-comments`、`yarn add @contently/videojs-annotation-comments`、`bun add @contently/videojs-annotation-comments`

## README

[![CircleCI](https://circleci.com/gh/contently/videojs-annotation-comments/tree/master.svg?style=svg)](https://circleci.com/gh/contently/videojs-annotation-comments/tree/master)

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

![AnnotationComments Screenshot1](https://npmcn.com/package/%40contently/videojs-annotation-comments/test/screenshot.png)

> ## 升级 v1 - > v2
> 
> 请注意基于事件的API已经改变. 在版本1中,您可以订阅插件事件 `pluginInstance.on()`。在第二版中,同样的功能可用 `pluginInstance.registerListener()`。以下文件为最新版本.

## 关于

### 背景情况

视频制图师与客户端的合作可能很乏味,电子邮件和电话会浪费时间试图引用屏幕的特定框架和区域. 此插件可以让浏览器进行更有效的协作.

这个插件是作为Hack Week项目设想和开发的 [内容](http://www.contently.com/) 以 [埃文·卡多尔](http://www.github.com/ecaroth) 财务报告和审定财务报表 [杰克・波普](http://www.github.com/jackpope). 在Contently继续关注并致力于多媒体支持,整个团队制作并防弹插件作为灵活解决方案,用于我们的产品和其他开源使用案例.

### 目标

-   **对录像机和客户都有效率** - 提供有用的协作特性,包括说明、评论/复制、时间标记等,以及更多的具有直觉控制.
-   **模拟和照明** - 所有东西都包含在插件和玩家元素中。 没有必要建造额外的UI组件. 只要安装 VideoJS,注册插件,设置任何您想要的后端存储,并开始合作.
-   **强烈的** - 插件可以与现有的注释系统相融合(就像我们在Contently中所做的那样),并且对如何存储注释的假设很少. 自定义事件可用于与外部API通信,为页面互动和数据持久性提供支持. 简单的 CSS 超接也可以允许最小努力的品牌定制,或者完全定制UI/UX.

### 视频JS插件

[视频JS](http://videojs.com/) 是400k+站点使用的受欢迎的开源HTML5视频播放器库. 截至 v6 有可扩展的插件架构用于创建此插件 。 此插件是构建和测试的 [视频JS v7](https://www.npmjs.com/package/video.js/)

## 用起来!

### 安装

```
yarn add @contently/videojs-annotation-comments
```

或

```
npm install @contently/videojs-annotation-comments
```

### 添加到您的 VideoJS 播放器

#### 作为构建中的脚本

```javascript
// ...videojs & videojs-annotation-comments have been loaded in script tags...
var player = videojs('video-id');
var plugin = player.annotationComments(pluginOptions)
```

#### 作为模块

```javascript
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)
```

### 插件选项/ 配置

初始化插件时,您可以在选项阵列中通过来覆盖默认选项. 任何被排除的选项都设定为默认值,如下所示:

```javascript
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` ,使用以下结构:

```javascript
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` 函数在插件上 :

```javascript
plugin.onReady(() => {
    // do stuff with the plugin, such as fire events or setup listeners
});
```

#### 支持的外部点火事件 :

这些事件是可以从您的脚本中调用以触发插件内的事件的外部动作 :

```javascript
// 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` 脚本中:

```javascript
// 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
});
```

## 开发和建设

我们用 [线条](https://yarnpkg.com/en/) 用于软件包管理以及 [ulp](https://github.com/gulpjs/gulp) 作为我们的建设系统.

最快的开始方式是:

-   清除还原
-   运行 `yarn install`
-   运行 `yarn build`
-   运行 `yarn watch`
-   访问 `http://localhost:3004/test.html` 看着魔法的到来.

### 模板

我们正在使用 [处理栏](http://handlebarsjs.com/) 调试库以在插件中渲染各种组件 。 对于性能,模板在开发环境中被预编为JS文件. 这样,我们只需要要求Handlebars运行时间,从精密建筑中节省了近100克b

这个 `gulp templates` 任务用于预编译每个模板到 `/src/js/compiled/templates.js`。该文件应当 _没有_ 直接修改,但模板本身在 `/src/templates` 如果需要修改,应当修改。 模板任务将在内部自动运行 `gulp watch`。 。 。 .

### UI / CSS 自定义

插件使用 SASS , 所有样式均定义在 [anotaitons.scs (英语)](https://npmcn.com/package/%40contently/videojs-annotation-comments/src/css/annotations.scss)。文件中有关于类和样式的延伸性评论。 插件使用深层的特异性来防止样式在页面上污染元素,所有类都使用前缀 `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`

### 许可证

此插件为 [许可证](https://npmcn.com/package/%40contently/videojs-annotation-comments/license.md) 根据Apache许可证,版本2.0,这是Video.js使用的同一张许可证

## 常见问题

### @contently/videojs-annotation-comments 是什么？

用于 video\.js 的插件, 用于添加对时间时刻/ 距离注释和说明的支持

### 如何安装 @contently/videojs-annotation-comments？

在项目目录运行 npm install @contently/videojs-annotation-comments，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：jquery（^3）、video\.js（^7）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @contently/videojs-annotation-comments 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/contently\_\_videojs-annotation-comments 是否存在。

### @contently/videojs-annotation-comments 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @contently/videojs-annotation-comments 可以商用吗？

@contently/videojs-annotation-comments 使用 Apache-2\.0 许可。宽松许可：允许商业使用、修改和再分发，并附带明确的专利授权；分发时需保留许可与 NOTICE 文件，修改过的文件要注明改动。以上为概括，不构成法律意见，请以许可原文为准。

### @contently/videojs-annotation-comments 的下载量有多少？

根据 npm 官方下载统计，@contently/videojs-annotation-comments 在 2026/10/11 – 2026/11/09 这 30 天内被下载 62,307 次，日均约 2,077 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @contently/videojs-annotation-comments 还在维护吗？

最新版本 2\.0\.1 发布于 2020/01/30（6 年前）；至今共发布 7 个版本，其中过去 12 个月发布了 0 个；首次发布于 2019/01/19。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

