ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

海康威视WEB无插件开发包V3.2:WebSocket+WASM实现浏览器直出实时流

海康威视WEB无插件开发包V3.2:WebSocket+WASM实现浏览器直出实时流 简介海康威视 WEB 无插件开发包 V3.2 面向需要在网页端集成视频监控能力的开发者尤其适合安防平台、行业应用的前后端工程师。它解决的是高版本谷歌、火狐浏览器不再支持传统插件取流的问题通过 Websocket 取流配合 nginx 代理服务器实现无插件预览对设备端也有相应支持要求。压缩包共 75 个文件约 9.42MB以 24 个 js 脚本、4 个 html 页面、4 个 xml 配置为主另含 nginx 相关 conf、bat 启停脚本、exe 可执行程序、pdf 开发文档与 license 授权文件构成可直接运行的 demo 环境。资源内附控件开发包编程指南与 Demo 测试文档并整理了已知问题列表和依赖库说明便于快速理解目录结构、排查代理与取流环节的常见故障。目前已有 6728 人学习下载适合希望低成本完成浏览器端视频接入的开发者参考。1. 海康威视 WEB 无插件开发包 V3.2从「装完插件也看不到画面」到浏览器直出实时流如果你做过海康威视摄像头的 Web 集成大概率经历过这个场景客户在 Chrome 里点开预览页面一片空白控制台报WebSocket connection failed或者干脆提示「请下载插件」。你让客户装WebComponents.exe装完重启浏览器还是不行——因为 Chrome 从 45 版本之后就彻底移除了 NPAPI而海康老版本的 Web 开发包恰恰依赖它。海康威视 WEB 无插件开发包 V3.2 就是用来终结这个死循环的它把原来靠 ActiveX/NPAPI 插件才能跑的预览、回放、云台控制改成了基于 WebSocket WebAssembly 的纯浏览器方案Chrome、Edge、Firefox 都能直接出画面不需要用户装任何东西。这套包适合两类人一是做安防管理平台前端集成的工程师二是被「客户电脑装不了插件」反复折磨的交付人员。下面我按实际拆包和集成的顺序把这份资源怎么落地讲清楚。2. 拆开 V3.2 的包目录结构、核心 JS 与依赖关系拿到压缩包先别急着往项目里塞花十分钟把目录结构摸清楚后面能省掉大量「文件 404」的排查时间。V3.2 的包体结构和早期版本差别不小最明显的变化是去掉了webComponents.exe这类本地插件安装程序转而用一套 JS WASM 的组合来解码和渲染。2.1 目录里到底有什么解压后典型的结构是这样的不同小版本可能略有出入以实际包为准webSdk/ ├── js/ │ ├── jquery-1.7.1.min.js │ ├── jsPlugin-1.0.0.js # 核心入口负责加载 WASM 和建立连接 │ ├── jsPlugin-1.0.0.min.js │ ├── jsVideoPlugin-1.0.0.js # 视频预览/回放相关 API │ ├── jsVideoPlugin-1.0.0.min.js │ ├── transform.js # 坐标转换、云台方向映射 │ └── webSocketUtil.js # WebSocket 封装含重连逻辑 ├── wasm/ │ ├── decoder.wasm # 视频解码核心 │ └── decoder.js # WASM 胶水层 ├── css/ │ └── webPlugin.css ├── demo/ │ ├── preview.html # 实时预览示例 │ ├── playback.html # 录像回放示例 │ └── ptz.html # 云台控制示例 └── doc/ └── 开发指南.pdf这里有几个点值得注意。jsPlugin-1.0.0.js是整个 SDK 的入口它内部会去wasm/目录加载decoder.wasm所以这两个目录的相对位置不能改否则 WASM 加载失败页面会卡在「正在初始化」不动。webSocketUtil.js里封装了心跳和断线重连如果你自己的项目已经有 WebSocket 管理可以不用它但要注意海康的心跳间隔默认是 30 秒太短会被设备拒绝。2.2 核心依赖与浏览器要求V3.2 对浏览器的要求比老版本宽松很多但也不是没有底线依赖项最低要求说明Chrome57需要支持 WebAssemblyEdge16Chromium 内核版本即可Firefox52需开启 WASM 支持默认已开网络设备与浏览器可达WebSocket 直连设备或通过平台转发端口设备 WebSocket 端口通常是 7681 或平台自定义注意如果你的页面是 HTTPS 的那 WebSocket 也必须是 WSS否则浏览器会以「混合内容」为由直接拦截。这是集成时最常见的翻车点之一后面避坑章节会细说。2.3 引入顺序不能乱在 HTML 里引入这些 JS 时顺序是有讲究的。jquery必须在最前面因为jsPlugin内部用了 jQuery 的$.ajax去拉取 WASM 胶水层。正确的引入方式!-- 先引入 jQuerySDK 内部依赖它做异步加载 -- script src./webSdk/js/jquery-1.7.1.min.js/script !-- 再引入 WebSocket 工具jsPlugin 会调用它 -- script src./webSdk/js/webSocketUtil.js/script !-- 最后引入核心插件它会自动去加载 wasm/decoder.js -- script src./webSdk/js/jsPlugin-1.0.0.js/script script src./webSdk/js/jsVideoPlugin-1.0.0.js/script逻辑说明jsPlugin-1.0.0.js在$(document).ready之后才会去初始化 WASM所以如果你把脚本放在head里且没有用defer要确保 DOM 加载完成后再调用初始化方法。参数方面jsPlugin暴露了一个全局对象WebVideoPlugin不同版本名字可能不同以demo里的调用为准初始化时传入wasmPath指定 WASM 目录的绝对或相对路径。3. 从零跑通实时预览初始化、登录、取流三步走目录摸清之后真正的集成工作就是三件事初始化 SDK、登录设备、把视频流渲染到div里。V3.2 把这套流程封装得比老版本简洁但每一步都有容易写错的地方。3.1 初始化 SDK 与 WASM 路径配置初始化是整个流程的地基。很多「画面出不来」的问题根源就在这一步 WASM 没加载成功。// 初始化插件指定 wasm 目录路径 // 注意wasmPath 必须是相对于当前页面的路径或者完整的 http(s) 地址 var initResult WebVideoPlugin.init({ wasmPath: ./webSdk/wasm/, // 指向 decoder.wasm 所在目录 debug: false, // 生产环境关掉否则控制台刷屏 onInitDone: function (code) { if (code 0) { console.log(SDK 初始化成功可以开始登录); } else { console.error(SDK 初始化失败错误码, code); } } });逻辑说明init方法内部会先请求wasmPath decoder.js拿到胶水层后再实例化decoder.wasm。如果wasmPath写错onInitDone会返回非 0 的错误码常见的是-1网络错误或-2WASM 编译失败。参数debug建议在联调阶段设为true它会打印出 WebSocket 的握手过程和每一帧的解析状态对排查「连上了但没画面」特别有用。3.2 登录设备IP、端口、用户名密码怎么填登录接口的参数看着简单但端口和协议类型是最容易填错的。海康设备的 WebSocket 端口不一定是 80也不一定是 7681取决于设备型号和固件版本。// 登录设备 // ip设备或平台的地址不要带 http:// 前缀 // portWebSocket 服务端口常见为 7681、80 或平台自定义 // username/password设备或平台的登录凭据 var loginParam { ip: 192.168.1.64, port: 7681, username: admin, password: your_password, protocol: ws // 如果是 https 页面这里必须改成 wss }; WebVideoPlugin.login(loginParam, function (result) { if (result.code 0) { // 登录成功result.sessionID 后续取流要用 window.sessionID result.sessionID; console.log(登录成功sessionID, result.sessionID); } else { console.error(登录失败错误码, result.code, result.msg); } });逻辑说明protocol这个参数在文档里可能写的是ws或wss但实际行为是——如果当前页面是 HTTPSSDK 内部会强制走 WSS此时如果设备不支持 WSS就会握手失败。参数port如果填错表现是 WebSocket 连接超时控制台会看到WebSocket connection to ws://... failed。一个实用的排查技巧先用浏览器直接访问http://设备IP/看能不能打开设备的 Web 登录页能打开说明网络通再确认 WebSocket 端口。3.3 取流与渲染把画面塞进 div登录拿到sessionID之后就可以取流了。V3.2 的取流 API 支持实时预览和录像回放两种模式这里先说实时预览。// 开始实时预览 // divId页面上用于承载视频的容器 id // sessionID登录成功后返回的会话 ID // channel通道号IPC 通常是 1NVR 按实际通道填 var previewParam { divId: videoContainer, sessionID: window.sessionID, channel: 1, streamType: 0, // 0-主码流1-子码流 onRealPlayStart: function () { console.log(预览已开始); }, onPlayException: function (errCode) { console.error(预览异常错误码, errCode); } }; WebVideoPlugin.startRealPlay(previewParam);逻辑说明streamType选主码流还是子码流直接影响首屏速度和带宽占用。主码流清晰但码率高适合大屏子码流适合多路同时预览。onPlayException回调里的错误码是排查的关键常见的有0x0正常、0x1连接断开、0x2解码失败。如果画面黑屏但回调没报错大概率是 WASM 解码器没拿到关键帧可以尝试先停止再重新取流。提示divId对应的容器必须有明确的宽高如果容器高度为 0视频虽然取到了流但渲染不出来表现就是「有声音没画面」或者完全空白。4. 录像回放与云台控制时间轴、倍速与方向指令实时预览跑通之后回放和云台是第二个必须啃下来的模块。这两块在 V3.2 里的 API 设计和预览不太一样回放多了时间参数云台多了指令队列的概念。4.1 录像回放按时间取流与倍速控制回放的核心是告诉设备「我要哪段时间的录像」。海康的录像文件是按时间段存储的取流时需要传入起止时间。// 开始录像回放 // startTime/endTime 格式YYYY-MM-DD HH:mm:ss var playbackParam { divId: playbackContainer, sessionID: window.sessionID, channel: 1, startTime: 2024-01-15 09:00:00, endTime: 2024-01-15 09:30:00, onPlaybackStart: function () { console.log(回放已开始); }, onPlaybackEnd: function () { console.log(回放结束); } }; WebVideoPlugin.startPlayback(playbackParam); // 倍速控制speed 支持 0.5 / 1 / 2 / 4 / 8 WebVideoPlugin.setPlaybackSpeed(2);逻辑说明startTime和endTime的格式必须严格匹配少一个前导零都可能导致设备返回「无录像」。如果该时间段没有录像文件onPlaybackStart不会触发取而代之的是onPlayException返回一个「无录像」的错误码。倍速控制是在客户端做的不是设备端所以 8 倍速下如果浏览器解码跟不上画面会卡顿这是正常现象。4.2 云台控制方向、变焦与预置位云台控制本质上就是往设备发指令。V3.2 把指令封装成了几个方法但要注意指令是异步的连续发太快会被设备丢弃。// 云台方向控制 // commandup / down / left / right / zoomIn / zoomOut // speed1-7数值越大转动越快 // stoptrue 表示停止当前动作 WebVideoPlugin.ptzControl({ sessionID: window.sessionID, channel: 1, command: left, speed: 4, stop: false }); // 停止云台动作必须调用否则会一直转 WebVideoPlugin.ptzControl({ sessionID: window.sessionID, channel: 1, command: left, speed: 4, stop: true }); // 调用预置位 WebVideoPlugin.ptzGotoPreset({ sessionID: window.sessionID, channel: 1, presetIndex: 3 // 预置位编号设备上提前设好的 });逻辑说明ptzControl的stop参数是关键。很多新手写完方向控制发现摄像头一直转不停就是因为没有在mouseup或touchend事件里发停止指令。常见做法是按下时发stop: false松开时发stop: true。speed参数不是所有设备都支持 1-7 全档位部分球机只认 1-4填 7 可能没反应这个要对照设备手册。4.3 多路预览时的资源管理一个页面上同时预览 4 路、8 路甚至 16 路时WASM 解码器的实例数是有限的。V3.2 默认会复用解码器但如果每路都开主码流浏览器内存会飙升。路数建议码流单路内存占用备注1-4 路主码流约 80-120MB画质优先5-9 路子码流约 40-60MB平衡10 路以上子码流 抽帧约 30MB需关闭部分路音频注意停止预览时一定要调用WebVideoPlugin.stopRealPlay(divId)只把 div 隐藏或清空 HTML 不会释放 WASM 解码器时间长了浏览器会崩。5. 避坑与排查那些文档里不会写的翻车现场这一章是我在实际交付里踩过的坑每一条都对应一个具体的现象和解决路径。如果你正在集成 V3.2建议逐条对照排查。5.1 现象页面一直显示「正在初始化」控制台无报错原因wasmPath配置的路径不对或者 WASM 文件被服务器以错误的 MIME 类型返回。有些 Nginx 默认不认.wasm后缀返回application/octet-stream浏览器拒绝编译。解决打开浏览器开发者工具的 Network 面板看decoder.wasm的请求状态。如果是 404检查路径如果是 200 但初始化失败在 Nginx 配置里加一行application/wasm wasm;到types块里然后重载。5.2 现象登录返回错误码提示「用户名密码错误」原因海康设备在多次登录失败后会锁定账户一段时间或者密码里含有特殊字符如、#在传输时被截断。解决先用设备自带的 Web 页面确认密码能登录排除密码本身的问题。如果密码含特殊字符尝试在 SDK 登录前做一次encodeURIComponent或者临时改成纯字母数字密码测试。账户锁定的话等 30 分钟或重启设备。5.3 现象预览有声音没画面或者画面卡在第一帧原因WASM 解码器没有拿到关键帧I 帧或者divId容器的高度为 0。解决先检查容器 CSS确保height不是0或auto。如果容器正常尝试先stopRealPlay再startRealPlay强制重新取流。如果还是不行把streamType从主码流切到子码流试试子码流的 GOP 通常更短更容易拿到关键帧。5.4 现象HTTPS 页面下 WebSocket 连接被浏览器拦截原因页面是 HTTPS但 SDK 配置的protocol是ws浏览器以「混合内容」为由阻止连接。解决把protocol改成wss同时确认设备或平台支持 WSS。如果设备不支持常见做法是在平台侧做一层 WSS 代理把wss://平台地址转发到ws://设备地址。这个代理用 Nginx 的stream模块就能做不需要改设备固件。5.5 现象多路预览时浏览器越来越卡最后崩溃原因每路预览都创建了独立的 WASM 解码器实例没有复用内存持续增长。解决确认 SDK 版本是否支持解码器池化V3.2 默认支持但需要调用WebVideoPlugin.setDecoderPoolSize(n)显式设置。另外停止预览时务必调用stopRealPlay不要只移除 DOM。如果路数超过 9 路建议默认走子码流并在 UI 上提供「单击放大看主码流」的交互。6. 进阶技巧用 Nginx 反代统一入口把 WSS 和跨域一次解决集成到后期你大概率会遇到两个绕不开的问题一是页面和视频流不同源导致的跨域二是 HTTPS 页面连不上只支持 WS 的设备。我最后落地的方案是用 Nginx 做一层反向代理把页面、SDK 静态资源和 WebSocket 全部收敛到同一个域名下跨域和 WSS 一次性解决。具体配置不复杂核心是location的匹配和Upgrade头的透传server { listen 443 ssl; server_name your-platform.com; # 静态资源包括 SDK 的 js 和 wasm location /webSdk/ { root /var/www/html; # 确保 wasm 以正确 MIME 类型返回 types { application/wasm wasm; } } # WebSocket 代理转发到设备或流媒体网关 location /ws/ { proxy_pass http://192.168.1.64:7681/; proxy_http_version 1.1; # 这两个头是 WebSocket 升级的关键缺一不可 proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_read_timeout 3600s; # 长连接超时设大一点 } }逻辑说明proxy_set_header Upgrade和Connection是 WebSocket 握手的必要条件漏掉任何一个Nginx 会把请求当普通 HTTP 处理SDK 侧看到的就是连接被重置。proxy_read_timeout默认 60 秒视频流如果 60 秒内没有数据会被断开设成 3600 秒比较稳妥。前端调用时把ip改成your-platform.comport改成443protocol改成wss路径前缀由 Nginx 的location匹配。这套方案跑通之后我习惯在交付前强制走一遍检查清单WASM 的 MIME 类型对不对、WSS 握手成不成功、多路预览内存涨不涨、停止预览后解码器有没有释放。这四个点过了基本就不会在客户现场翻车。希望帮到你。本文还有配套的精品资源点击获取
返回列表