海康 Web 插件版接入指南:用法与注意事项

面向需要在网页里接入海康设备实时预览 / 回放的前端同学。本文只讲 插件版(OCX / WebComponents) 的接入方式与注意事项,不绑定具体业务页面。

常见配套包名:HCWebSDKPluginsUserSetup.exe(Windows)。前端通过全局对象 WebVideoCtrl 调用 I_* 系列 API。


一、插件版是什么

插件版本质是:浏览器装一个本地播放组件,页面用 ActiveX(旧 IE)或 WebComponents/NPAPI 式桥接,把解码、渲染交给本地进程。

说明
核心对象 window.WebVideoCtrl
安装包 常见为 HCWebSDKPluginsUserSetup.exe
检测 API I_CheckPluginInstall(),返回 -1 表示未安装
销毁 API I_DestroyPlugin()
典型环境 Windows + 特定浏览器(历史方案多依赖 IE / 企业定制 Chromium)

和后文将写的「无插件版」对比:

插件版 无插件版
客户端 必须安装本地插件 不用装插件,靠 WASM/JS
检测 I_CheckPluginInstall I_SupportNoPlugin
销毁 I_DestroyPlugin I_DestroyWorker
浏览器 对内核、位数敏感 通常要求较新的 Chromium

二、脚本与静态资源

页面通常需要提前注入(顺序因官方 demo 而异,常见组合):

  1. jQuery(部分接口仍用 $ 解析 XML)
  2. 加密相关脚本(登录 / 会话)
  3. webVideoCtrl.js(暴露 WebVideoCtrl

示例(示意):

xml 复制代码
<script src="/static/hcWebSdk/encryption/aes.js"></script>
<script src="/static/hcWebSdk/webVideoCtrl.js"></script>

业务代码启动前先轮询确认全局对象:

javascript 复制代码
function waitForWebVideoCtrl(timeoutMs = 10000): Promise<boolean> {
  const start = Date.now()
  return new Promise((resolve) => {
    const tick = () => {
      if (window.WebVideoCtrl) return resolve(true)
      if (Date.now() - start > timeoutMs) return resolve(false)
      setTimeout(tick, 500)
    }
    tick()
  })
}

三、标准流程:检测 → 初始化 → 插入 → 登录 → 预览

scss 复制代码
脚本加载成功
    ↓
I_CheckPluginInstall()  !== -1
    ↓
I_InitPlugin({ ... cbInitPluginComplete })
    ↓
I_InsertOBJECTPlugin(容器 DOM id)
    ↓
I_Login(ip, protocol, port, user, pass, { success, error })
    ↓
I_GetDevicePort / 通道信息(可选)
    ↓
I_StartRealPlay / I_StartPlayback
    ↓
离开页面:I_Stop → I_Logout → I_DestroyPlugin

1. 检测是否安装

javascript 复制代码
const status = WebVideoCtrl.I_CheckPluginInstall()
if (status === -1) {
  // 引导用户下载 HCWebSDKPluginsUserSetup.exe,安装后刷新页面
  throw new Error('海康插件未安装')
}

可按系统提供安装包:

  • Windows:/plugin/HCWebSDKPluginsUserSetup.exe
  • Mac:官方若提供对应包,再单独配置(很多项目从未落地 Mac 包)

2. 初始化并插入容器

插件版初始化常见是 对象参数(不传宽高字符串):

typescript 复制代码
await new Promise((resolve, reject) => {
  const timer = setTimeout(() => reject(new Error('插件初始化超时')), 15000)

  WebVideoCtrl.I_InitPlugin({
    bWndFull: true,
    iWndowType: 1, // 1=1×1,2=2×2,3=3×3 ...
    cbSelWnd() {},
    cbDoubleClickWnd() {},
    cbEvent() {},
    cbInitPluginComplete() {
      clearTimeout(timer)
      // 往指定空容器插入插件对象
      WebVideoCtrl.I_InsertOBJECTPlugin('hikPluginBox')
        .then(() => resolve(true))
        .catch(reject)
    },
  })
})

容器要求:

  • 页面里有一个 空的 <div id="hikPluginBox"></div>
  • 不要在里面再塞 Vue/React 子节点;插入时会改写 DOM
  • 容器需要有明确宽高,否则容易黑屏

3. 登录设备

javascript 复制代码
const protocol = location.protocol === 'https:' ? 2 : 1 // 1=http,2=https

const ret = WebVideoCtrl.I_Login(ip, protocol, port, username, password, {
  timeout: 3000,
  success() {
    // deviceIdentify 常用约定:`${ip}_${port}`
  },
  error(err) {
    // errorCode === 2001:设备已在插件会话中登录,可按成功处理
  },
})

// 同步返回 -1:表示已登录
if (ret === -1) {
  // 视为已登录
}

4. 实时预览

javascript 复制代码
const deviceIdentify = `${ip}_${port}`

const wnd = WebVideoCtrl.I_GetWindowStatus(0)
if (wnd) {
  WebVideoCtrl.I_Stop({ iWndIndex: 0 })
}

WebVideoCtrl.I_StartRealPlay(deviceIdentify, {
  iWndIndex: 0,
  iStreamType: 1,   // 主码流
  iChannelID: 1,
  bZeroChannel: false,
  success() {},
  error(status) {},
})

5. 回放

javascript 复制代码
WebVideoCtrl.I_RecordSearch(deviceIdentify, channelId, startTime, endTime, {
  iStreamType: 1,
  iSearchPos: 0,
  success(xmlDoc) {
    // 响应里常见:OK / MORE / NO MATCHES
    // MORE 时递增 iSearchPos 继续查
  },
})

WebVideoCtrl.I_StartPlayback(deviceIdentify, {
  iStreamType: 1,
  iChannelID: channelId,
  szStartTime: '2026-07-15 10:00:00',
  szEndTime: '2026-07-15 11:00:00',
  success() {},
  error() {},
})

6. 云台

php 复制代码
// cmd:1上 2下 3左 4右;10/11 变倍;12/13 聚焦;14/15 光圈
WebVideoCtrl.I_PTZControl(cmd, false, { iWndIndex: 0, iPTZSpeed: 4 })
// 动作后延时发送 stop
setTimeout(() => {
  WebVideoCtrl.I_PTZControl(cmd, true, { iWndIndex: 0, iPTZSpeed: 4 })
}, 300)

7. 销毁

scss 复制代码
WebVideoCtrl.I_Stop() // 或按窗口停
WebVideoCtrl.I_Logout(deviceIdentify)
WebVideoCtrl.I_DestroyPlugin()

切记: 插件版用 I_DestroyPlugin,不要和无插件的 I_DestroyWorker 混用。


四、注意事项(踩坑清单)

1. 必须先装插件,且安装后刷新

未安装时 I_CheckPluginInstall() === -1。用户装完若页面不刷新,WebVideoCtrl / 检测结果可能仍是旧状态。产品文案建议明确:安装完成后请刷新页面

2. 浏览器与系统限制很硬

  • 多数插件包面向 Windows
  • Mac / Linux 往往无包或不可用,别在 UI 上假装「全平台可装」
  • 现代 Chrome 已弱化/移除传统插件能力,插件版越来越难在默认浏览器跑通
    → 长期更宜迁到无插件版

3. 容器 DOM 只能是「空壳」

I_InsertOBJECTPlugin 会接管节点。若用前端框架在同一个节点下 v-if 子组件、或反复销毁重建父节点,容易出现:

  • parentNode 为空
  • 插入返回 -1
  • 黑屏、焦点异常

实践:视频容器单独一个永远存在的空 div,上层 UI 不要嵌进它内部。

4. 视频画面上叠不了普通网页布局

插件版画面不是普通的 <video> / Canvas,而是由本地插件以原生窗口层绘制。它往往压在 HTML 之上,不参与常规文档流的层叠:

  • 在播放区域上用 CSS/z-index 盖遮罩、水印、Loading、Tooltip、弹层,均无效
  • 整页 Modal、抽屉若盖住视频区,会出现「对话框在下面、画面仍戳在最前」的穿帮
  • opacity、圆角裁剪、滤镜、混合模式对插件窗口也不生效

交互与信息建议放到播放区外侧(侧栏、底栏、工具条)。若必须暂时压住画面(切页、弹确认框),优先:

  1. 先停播 / 隐藏或销毁插件窗口,再弹页面层
  2. 或把确认类 UI 设计到不与视频矩形相交的区域

产品评审时尽早约定:画面内不做复杂 HTML 叠加;有强叠加诉求时,优先评估无插件版(Canvas 渲染,才能正常叠 DOM)。

5. 登录态别重复造混乱

I_Login 同步 -1 或回调 errorCode === 2001,通常表示 已经登录过 。切页若不 I_Logout,再进页面很容易撞上 2001。建议:

  • 页面离开:停播 → 登出 → I_DestroyPlugin
  • 2001 可按成功容错,但要自己维护「本地是否已记录该设备」

6. 窗口占用要先停再播

同一窗口再次 I_StartRealPlay / I_StartPlayback 前,先 I_GetWindowStatus + I_Stop,否则容易失败或卡死上一路画面。

7. 协议要跟页面一致

I_LoginiProtocol1 = http2 = https。页面是 HTTPS、却按 HTTP 登录设备,常见证书/混合内容问题。

8. 分屏与尺寸

  • iWndowType:1/2/3/4 对应 1×1 / 2×2 / 3×3 / 4×4
  • 布局变化后如有 I_Resize,等容器真正有宽高再调(侧栏动画结束后再调更稳)

9. 安装包分发与安全策略

企业内网常要把安装包挂在静态资源目录(如 /plugin/)。注意:

  • HTTPS 站点下载 exe 可能被浏览器拦截
  • 权限策略、杀毒软件误报
  • 版本升级后旧插件与新 webVideoCtrl.js 不匹配

10. 全局单例思维

插件往往在浏览器进程里是单实例倾向:多个页面/多个容器同时 I_InitPlugin 很容易打架。常见做法:

  • 全局只保留一个插件宿主
  • 或切页前完整 destroy,再在新容器 init

五、推荐目录结构(示意)

csharp 复制代码
public/
  plugin/
    HCWebSDKPluginsUserSetup.exe   # Windows 安装包
  static/
    hcWebSdk/
      webVideoCtrl.js
      encryption/

六、何时还该用插件版

适合这些情况:

  • 客户机可控、允许统一装包(如机房专用电脑)
  • 设备固件/取流方式不支持无插件 WebSocket
  • 已有成熟插件运维链路,短期无法迁 WASM

否则,更建议直接做无插件版(Chromium + WASM),减少安装、兼容与客服成本。下一篇会专门写 无插件版 的用法与注意事项。


小结

插件版接入骨架很固定:检测安装 → Init/Insert → Login → RealPlay/Playback → DestroyPlugin 。真正拖垮交付的通常是环境与交互边界:浏览器砍插件、容器 DOM 被框架改坏、画面是原生窗口叠不上网页样式、登录态/窗口态未清理、安装包分发不完整。

把它当成「本地播放器 + JS 桥」来管生命周期,会比当成普通 <video> 稳得多。


相关推荐
虚焦像素_1 小时前
海康 Web 无插件版接入指南:用法与注意事项
前端
aaron2 小时前
前端演进史:当你没留意时,前端发生了什么
前端
不好听6132 小时前
前端路由完全指南(上篇):从原理到 6 种路由模式
前端·react.js
像我这样帅的人丶你还2 小时前
🚀大文件上传的那些事
前端·javascript·架构
不好听6132 小时前
前端路由完全指南(中篇):React Router Hooks 完全指南
前端·react.js
hunterandroid2 小时前
[鸿蒙从零到一] ArkUI 声明式 UI 基础实战
前端
七牛开发者2 小时前
RAG 工程里的上下文剪枝:如何减少 68% 的上下文
前端·css·github
橘子星3 小时前
从零理解流式输出 —— 一个 Vue + DeepSeek 的前端实战
前端·javascript·人工智能
智驭未来掌门人3 小时前
如何让你的前端服务在服务器上nohub运行
前端