ZWPlayer 交互标注功能使用说明

1. 功能概述

ZWPlayer 支持为视频添加交互标注(Annotation)功能,可在视频画面上叠加可交互节点,实现点击跳转、分支选择、测验问答、投票调查、表单收集等丰富的互动体验。广泛应用于互动教学、分支剧情、产品展示、在线培训等场景。

交互标注功能支持 13 种节点类型,分为四大类:

分类 节点类型 说明
基础类 hotspot(热区)、text(文本)、image(图片)、button(按钮) 最常用的交互元素
交互类 choice(选项分支)、quiz(测验)、form(表单)、vote(投票)、card(信息卡片) 数据收集与互动反馈
高级类 webview(网页嵌入)、map(地图) 外部内容集成
系统类 countdown(倒计时)、speed_controller(变速控制) 播放控制

成功加载标注数据后:

  1. 视频覆盖层:在视频画面上显示交互节点,用户可点击、长按触发动作
  2. 进度条标记:播放器进度条上会显示标注节点的时间范围
  3. 标注按钮:如果初始化时设置了 annotations 参数,控制条上会出现标注编辑按钮,点击可打开在线标注编辑器

2. 设置标注信息

2.1 通过构造函数配置

在创建 ZWPlayer 实例时,通过 annotations 参数传入标注数据:

var player = new ZWPlayer({
    url: 'http://example.com/vod/movie.mp4',
    playerElm: '#mse',
    // 传入标注 JSON URL
    annotations: 'http://example.com/annotations/movie_annotation.json'
});

也支持 annotation(单数)属性名,播放器内部会自动归一化。

2.2 通过方法动态加载

使用 loadAnnotations 方法在运行时动态加载标注数据:

// 加载远程 JSON 文件
player.loadAnnotations('http://example.com/annotations/movie_annotation.json');

// 加载 ZWMAP JSON 对象
player.loadAnnotations({
    "zwp_protocol": "ZWMAP/1.0",
    "zwp_type": "annotation",
    "nodes": [ /* ... */ ]
});

// 卸载标注
player.unloadAnnotations();

2.3 通过 URL 对象配置

url 参数的 JS 对象中同时配置视频和标注:

var player = new ZWPlayer({
    playerElm: '#mse',
    url: {
        src: 'http://example.com/vod/movie.mp4',
        annotations: 'http://example.com/annotations/movie_annotation.json',
        chapters: 'http://example.com/chapters/movie_chapter.json',
        subtitles: 'http://example.com/subtitles/movie.vtt'
    }
});

2.4 拖拽文件加载

将标注 JSON 文件直接拖拽到播放器上即可加载。支持以下拖拽方式:

  • 单独拖拽标注 JSON:将 *_annotation.json 文件拖入播放器,为当前播放的视频加载标注
  • 同时拖拽视频和标注:将视频文件与对应的标注 JSON 一起拖入,播放器自动按文件名匹配(如 movie.mp4 匹配 movie_annotation.json
  • 播放列表拖拽:拖入多个视频及对应的标注文件,自动创建带交互标注的播放列表

3. 标注数据格式

3.1 ZWMAP JSON 格式

交互标注采用 ZWMAP(Z&W 媒体标注协议)标准 JSON 格式,导出文件命名为 {视频标题}_annotation.json

{
  "zwp_protocol": "ZWMAP/1.0",
  "zwp_type": "annotation",
  "zwp_version": "1.0",
  "nodes": [
    {
      "id": "btn001",
      "type": "button",
      "name": "了解更多",
      "time_range": { "start": 10, "end": 30 },
      "position": { "x": 60, "y": 70, "w": 25, "h": 8 },
      "style": {
        "border_radius": 4,
        "opacity": 90,
        "background": "#1890ff"
      },
      "events": [
        {
          "trigger": "click",
          "actions": [
            { "type": "SEEK_TIME", "target": 120 }
          ]
        }
      ]
    },
    {
      "id": "quiz001",
      "type": "quiz",
      "name": "知识测验",
      "time_range": { "start": 60, "end": 90 },
      "position": { "x": 20, "y": 20, "w": 60, "h": 60 },
      "content": {
        "question": "以下哪个是正确的?",
        "options": [
          { "text": "选项 A", "correct": true },
          { "text": "选项 B", "correct": false }
        ]
      },
      "events": [
        {
          "trigger": "click",
          "actions": [
            { "type": "PAUSE_MEDIA" }
          ]
        }
      ]
    }
  ]
}

3.2 协议头部字段

字段 类型 必填 说明
zwp_protocol string 协议标识,固定 "ZWMAP/1.0"
zwp_type string 数据类型,固定 "annotation"
zwp_version string 协议版本号,默认 "1.0"
nodes array 标注节点数组

3.3 节点对象字段

字段 类型 必填 说明
id string 节点唯一标识符(UUID)
type string 节点类型,如 hotspottextbuttonquiz
name string 节点显示名称
time_range object 出现时间范围 { "start": 秒, "end": 秒 }
position object 位置与尺寸 { "x": 百分比, "y": 百分比, "w": 百分比, "h": 百分比 }
style object 样式配置(边框、透明度、背景色等)
content object 节点内容,根据 type 不同而异
events array 事件数组,包含触发器和动作链
animation object 动画配置(入场、强调、退场)

3.4 事件与动作链

每个节点可配置一个或多个事件,每个事件包含触发器和动作链:

{
  "trigger": "click",
  "actions": [
    { "type": "PAUSE_MEDIA" },
    { "type": "SEEK_TIME", "target": 120 },
    { "type": "EMIT_MESSAGE", "data": { "key": "value" } }
  ]
}

支持的触发器类型:

触发器 说明
click 用户点击节点
longpress 用户长按节点

支持的动作类型:

动作类型 参数 说明
SEEK_TIME target(秒数) 跳转到指定时间点
PAUSE_MEDIA 暂停视频播放
PLAY_MEDIA 恢复视频播放
LOAD_ITEM target(URL) 切换播放列表项
OPEN_LINK urltarget 打开链接
SHOW_NODE target(节点ID) 显示目标节点
HIDE_NODE target(节点ID) 隐藏目标节点
TOGGLE_NODE target(节点ID) 切换节点可见性
EMIT_MESSAGE data(键值对) 向父页面发送 postMessage
SUBMIT_DATA urldata 向 API 提交数据

3.5 动画系统

每个节点支持三个阶段的动画:

阶段 可用动画 默认时长
入场 fade_inslide_in_leftslide_in_rightslide_in_upslide_in_downzoom_inbounce_in 300ms
强调 pulseglowshakebounceswing 300ms
退场 fade_outslide_out_leftslide_out_rightslide_out_upslide_out_downzoom_out 300ms

所有动画支持自定义时长(100–3000ms)。

4. 自动识别规则

zwplayer 根据参数内容自动识别标注格式:

  • 字符串 URL:作为远程 JSON 文件自动下载并解析
  • 对象且含 zwp_type: "annotation":按 ZWMAP 协议格式解析,提取 nodes 数组
  • 对象含 nodes 数组:直接作为节点数组使用
  • 拖拽文件:文件名匹配 *_annotation.json 模式,自动按 ZWMAP 格式解析

5. 在线标注编辑器

ZWPlayer 提供在线标注编辑器,可通过以下方式使用:

  1. 在播放器控制条上点击标注编辑按钮(需配置 annotations 参数)
  2. 直接访问 annotation/index.html 打开独立编辑器

编辑器功能包括:

  • 可视化画布绘制:直接在视频画面上拖拽绘制节点区域
  • 属性面板:配置节点的位置、时间范围、样式、内容和交互动作
  • 时间线编辑:在时间轴上直观管理节点的时间范围
  • 实时预览:按 P 键进入预览模式,在真实播放器中测试交互效果
  • JSON 导入/导出:支持导入和导出标准 ZWMAP JSON 文件
  • 快捷键操作:按 N 快速创建节点,Delete 删除,Ctrl+Z 撤销

6. 使用示例

示例 1:加载远程标注文件

var player = new ZWPlayer({
    url: 'http://example.com/vod/movie.mp4',
    playerElm: '#mse',
    annotations: 'http://example.com/annotations/movie_annotation.json'
});

示例 2:直接传入 ZWMAP 对象

var player = new ZWPlayer({
    url: 'http://example.com/vod/movie.mp4',
    playerElm: '#mse',
    annotations: {
        "zwp_protocol": "ZWMAP/1.0",
        "zwp_type": "annotation",
        "nodes": [
            {
                "id": "node1",
                "type": "button",
                "name": "Click Me",
                "time_range": { "start": 5, "end": 15 },
                "position": { "x": 40, "y": 40, "w": 20, "h": 10 },
                "events": [
                    {
                        "trigger": "click",
                        "actions": [
                            { "type": "SEEK_TIME", "target": 30 }
                        ]
                    }
                ]
            }
        ]
    }
});

示例 3:运行时动态加载与卸载

// 初始化播放器
var player = new ZWPlayer({
    url: 'http://example.com/vod/movie.mp4',
    playerElm: '#mse'
});

// 视频播放后加载标注
player.onmediaevent = function(event) {
    if (event.type === 'play') {
        player.loadAnnotations('http://example.com/annotations/movie_annotation.json');
    }
};

// 切换视频时卸载旧标注
function switchVideo(newUrl) {
    player.unloadAnnotations();
    player.setVideoUrl(newUrl);
}

示例 4:在播放列表中使用标注

{
  "zwp_protocol": "ZWMAP/1.0",
  "zwp_type": "playlist",
  "groups": [
    {
      "name": "互动课程",
      "items": [
        {
          "name": "第一课",
          "url": "https://cdn.example.com/lesson1.mp4",
          "annotation": "https://cdn.example.com/annotations/lesson1_annotation.json"
        },
        {
          "name": "第二课",
          "url": "https://cdn.example.com/lesson2.mp4",
          "annotation": "https://cdn.example.com/annotations/lesson2_annotation.json"
        }
      ]
    }
  ]
}

7. 注意事项

  1. 协议头必需:标注 JSON 必须包含 zwp_protocol: "ZWMAP/1.0"zwp_type: "annotation",否则将拒绝加载
  2. 时间范围time_range 中的 startend 以秒为单位,end 必须大于 start
  3. 位置坐标position 中的 xywh 均为百分比值(0–100),相对于视频画面
  4. 性能考虑:同一时间段内同时显示的节点数量建议不超过 20 个,以保持流畅的播放体验
  5. 编辑器:可从 annotation/index.html 访问在线标注编辑工具,可视化创建和编辑标注
  6. 单复数兼容:配置参数同时支持 annotationsannotation(单数),播放器内部自动归一化