ARTICLE DETAIL

资讯详情

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

大华WebAPI接入指南:签名算法、WebSDK与RTSP流播放详解

大华WebAPI接入指南:签名算法、WebSDK与RTSP流播放详解 简介大华Web SDK开发包是一份面向Web开发者的安防设备集成工具通过浏览器JavaScript接口即可完成视频流播放、云台控制、录像回放、报警管理等功能免去安装独立客户端适合企业监控平台和家庭安防应用的二次开发。压缩包共111个文件以76个C/C头文件和28个动态链接库为主并含3个lib导入库、3个pdb调试符号及1个manifest配置整体约11.17MB。头文件用于接口声明dll提供OpenAPI客户端通信、音视频解码与编码等底层能力方便开发者按需调用。已有603人学习下载。借助该资源可获得核心库、接口头文件与调试符号避免从零封装协议快速搭建带实时预览和事件订阅的监控Web应用。1. 大华webapi不是海康那套先弄清楚sdk.rar里装的到底是哪一层拿到sdk.rar_大华 webapi_大华 浏览器API这份资源的第一天我就踩了个认知坑以为解压出来就能像海康SDK那样直接 new 一个客户端对象。实际上大华给的这套东西核心是 webapi 接口文档、鉴权示例和 websdk 封装走的是 HTTP JSON 的 RESTful 路子。webapi 解决的是「服务端怎么调设备」websdk 解决的是「浏览器怎么调设备」两者是配合关系不是替代关系。这套资源最适合两类人一类是正在做第三方平台对接的集成工程师需要把大华摄像头网页插件能力接入自己的系统另一类是前端开发想在网页里完成预览、回放、云台控制但不想自己去啃私有协议。下面按我实际拆包的顺序把这套东西的调用链路、签名算法、流地址获取和踩坑点一次讲透。2. 大华webapi调用链路appKey、appSecret与signature签名算法2.1 两种调用通道IP直连与开放平台大华webapi分两个场景这个必须先分清因为后续所有参数配置都不一样。第一种是 IP 直连也就是内网环境下直接通过设备的 IP 地址访问 webapi 服务适用于项目私有化部署设备在局域网里平台服务器和设备之间没有公网隔离。第二种是开放平台通道走openapi.dahuatech.com这个公网入口适用于把设备接入大华云平台、或者需要通过公网对设备做管理的场景。两者的核心区别在于 appKey 的归属IP直连时appKey 是在设备上配置的每个设备一个开放平台时appKey 是在大华开放平台申请的绑定的是你的开发者账号可以管理多个设备。很多人在内网项目里拿开放平台的 appKey 去直连设备结果一直 401就是这个原因。鉴权方式两者一致都是请求头带三个字段请求头字段说明X-Dahua-AppKey你的应用标识X-Dahua-Signature签名结果X-Dahua-Time当前时间戳毫秒级2.2 签名算法一步步算出一个合法请求大华webapi的签名算法不复杂但细节极容易翻车。我之前按文档写了一遍第一次请求就返回签名错误查了半天发现是时间戳格式的问题。完整签名过程如下取当前时间的毫秒时间戳比如1719400000000把appSecret和time字符串拼接成一个待签名串对待签名串做SHA1哈希然后做Base64编码签名格式为appKey:Base64串请求头带上X-Dahua-Time和X-Dahua-Signature下面这段 Python 代码是完整的签名与登录流程可以直接跑。我在项目里先用它验证接口连通性确认没有问题再继续写业务代码。import time import hashlib import base64 import requests app_id your_app_key # 设备上配置的appKey app_secret your_app_secret # 设备上配置的appSecret device_ip 192.168.1.64 device_port 8090 # webapi服务端口 def build_signature(): # 毫秒时间戳注意不是秒级 now_ms str(int(time.time() * 1000)) # 待签名串appSecret time source app_secret now_ms # SHA1哈希后取字节 sha1_digest hashlib.sha1(source.encode(utf-8)).digest() # Base64编码签名内容 encode_str base64.b64encode(sha1_digest).decode(utf-8) # 最终签名字符串 return now_ms, app_id : encode_str def get_access_token(): now_ms, signature build_signature() url fhttp://{device_ip}:{device_port}/openapi/accessToken # 按key1value1key2value2格式传参 payload fipAddress{device_ip}portNo{device_port}userNameadmin headers { X-Dahua-AppKey: app_id, X-Dahua-Signature: signature, X-Dahua-Time: now_ms, Content-Type: application/x-www-form-urlencoded; charsetUTF-8 } resp requests.post(url, headersheaders, datapayload, timeout10) return resp.json()逻辑说明build_signature函数把时间戳转成毫秒级字符串后与appSecret拼接先做SHA1再做Base64这是大华webapi文档里约定的两层编码顺序顺序不能颠倒先 Base64 再 SHA1 的结果完全不同。get_access_token请求里注意payload的传参格式userName是设备的管理员账号ipAddress和portNo是设备自身的地址信息这两个值必须手动填对。参数说明里有个隐藏点accessToken接口的返回里包含accessToken字段和一个过期时间expireTime默认有效期是10分钟。业务接口调用时必须把这个 token 放到请求头X-Dahua-Time和X-Dahua-Signature之外再加一个X-Dahua-Token字段。token 过期后接口返回错误码通常是10001或者401需要重新调用get_access_token刷新。我一般把 token 缓存起来过期前一分钟主动刷新。2.3 与海康SDK的差异这里多说一句和搜索词里高频出现的海康SDK的区别。海康的传统SDK是 C 动态库提供设备列表、预览、回放等整套能力Java 里通过 JNA 调C# 里通过 P/Invoke 调依赖原生环境部署麻烦。大华webapi走的是纯 HTTP 接口服务端只要发请求就行不依赖原生库跨平台友好。但webapi的能力覆盖不如传统SDK全某些底层能力比如设备私有协议报警订阅在webapi里只能用长连接方式实现这部分没有完整封装需要自己用 Socket 补。如果项目需要深度定制设备行为传统SDK仍是首选webapi适合快速集成和浏览器端展示。3. 在浏览器里跑起来websdk封装与页面集成实战3.1 websdk和webapi怎么分工webapi是HTTP接口理论上前端自己发请求也能调通但实际操作时会碰到跨域、token管理、签名维护等一堆重复劳动。大华提供的 websdk在sdk.rar里通常叫webapibind或websdk的jar包/js文件把这一层封装好了它内部维护了 token 刷新机制封装了签名生成暴露给前端的方法就是login、logout、startPreview、stopPreview这种业务方法。我用下来觉得websdk的价值主要在两点一是把「先取token再带token调业务接口」这个两步流程封装成了一次方法调用二是预览能力它内部处理了插件或WebRTC的拉起逻辑不用自己在底层折腾流协议。但要注意websdk不同版本封装的深度不一样有的版本只是简单包装HTTP请求有的版本才真正集成了流播放能力具体看jar包体积和文档里的方法清单。3.2 前端集成登录、预览一段可直接运行的代码在拿到sdk.rar后解压出来通常有一个src目录放着JavaScript示例一个doc目录放着webapi接口文档。我把自己在Vue项目里封装的最小可运行代码贴在下面这个思路在纯HTML里也能用。// 引入大华websdk通常是解压包里的js文件 import DhWebApi from ./dhWebApi // 初始化配置 const dhWeb new DhWebApi({ ip: 192.168.1.64, // 设备IP port: 8090, // webapi端口 appKey: your_app_key, appSecret: your_app_secret }) // 登录设备 const loginRes await dhWeb.login({ userName: admin, password: your_password }) if (loginRes.code 0) { // 登录成功获取通道列表 const channelRes await dhWeb.getChannels() // 通常返回channels数组每个元素有channelId和channelName console.log(通道列表:, channelRes.channels) }参数说明DhWebApi的构造函数里必须传ip和port这两个值是设备webapi服务的监听地址默认端口是8090但有些定制设备会改成其他端口在设备网络设置页面能查到。login里的userName是设备管理员账号password默认是明文传输如果项目要求安全性需要在webapi文档里看是否有encryptType参数把密码做AES加密后再传。getChannels返回的channelId是后续预览、回放接口的唯一通道标识不是通道名称这个ID是设备内部索引比如0、1这样的数字。3.3 预览与播放websdk拉起播放窗口// 预览第一个通道主码流 const previewRes await dhWeb.startPreview({ channelId: 0, // 通道索引 streamType: 0, // 0主码流 1子码流 container: playerDiv, // 页面上存放播放器的div id protocol: WSS // 浏览器播放协议 }) // 切换子码流 const previewSubRes await dhWeb.startPreview({ channelId: 0, streamType: 1, container: playerDiv })streamType这个参数在项目里经常被忽略主码流分辨率高、码率大适合全屏回放子码流分辨率低、码率小适合多画面预览。如果在多画面墙里全用主码流很快设备端CPU就飙高预览卡顿页面黑屏。protocol参数可选WSS或HLS取决于大华webapi版本和设备固件能力我一般优先试WSS延迟低部分老设备不支持就降级到HLS。启动预览后WebSDK底层会做三件事拿channelId生成流地址、向设备请求拉起码流、把码流交给播放器渲染。如果页面黑屏先看浏览器控制台有没有跨域错误再看网络请求有没有返回401前者是平台配置问题后者是token过期。3.4 与阿里云认证SDK的关系搜索引擎里经常把大华SDK和阿里云认证SDK一起问这俩其实是不同的东西。阿里云认证SDK是阿里云 IoT 平台提供的设备接入认证组件用于设备连接阿里云物联网平台大华webapi是设备侧的能力开放接口。两者要是同时出现通常是这类架构大华摄像头通过RTSP流或者webapi把视频流推到流媒体服务器流媒体服务器再以标准协议对接阿里云。在这类项目里大华的webapi用来获取设备信息和流地址阿里云SDK用来做平台侧接入各管一段。别指望用阿里云认证SDK去直接调大华摄像头协议不对谁也通不了。4. 从设备拿到能播的流RTSP地址格式与播放方案4.1 主码流与子码流的RTSP地址规则webapi能拿到设备能力和通道信息但真正要把视频播出来核心还是得拿到流地址。大华设备的RTSP地址格式有固定规则在浏览器里和VLC里都能验证。下面是常见的大华设备RTSP地址格式rtsp://user:passwordip:554/cam/realmonitor?channel1subtype0上面地址的参数含义拆开看554是RTSP默认端口channel1是通道编号从1开始webapi里的channelId从0开始两者差1这是最容易搞混的坑subtype0表示主码流subtype1表示子码流。用户名密码就是设备的管理员账号密码。4.2 浏览器播放方案选型问题来了浏览器原生不能播放RTSP除了极老的IE时代装插件。现在主流的网页播放方案有下面几种方案延迟量级适用场景注意事项websdk内置WSS播放200-500ms局域网实时预览设备固件需支持无法跨公网ffmpeg转HLS3-10秒公网直播、回放延迟偏高需要切片存储流媒体网关ZLMediaKit/MediaMTX1-3秒多路聚合、集中管理部署成本适中适合中大型项目WebRTC网关300-800ms对延迟敏感的对讲、控制实现成本较高需要单独搭建信令服务我一般优先选择websdk内置的WSS播放因为它集成最简单不需要额外部署服务局域网内的画面延迟在可接受范围。但项目如果涉及公网访问、或者需要把多个品牌摄像头比如海康、大华在同一平台统一接入我就倾向用流媒体网关方案。这时候大华webapi的角色变成了「拿流地址」的工具获取到RTSP地址后交给网关去拉流网关再输出给前端。4.3 用ffmpeg验证流地址是否可用在集成播放器之前我会先用ffmpeg验证流地址是否有效避免排查问题时不知道是流地址问题还是播放器问题。这个习惯帮我省了很多时间。ffmpeg -rtsp_transport tcp \ -i rtsp://admin:password192.168.1.64:554/cam/realmonitor?channel1subtype0 \ -c copy -f flv rtmp://your_media_server/live/camera01命令解释-rtsp_transport tcp指定用TCP方式拉RTSP流UDP方式在某些网络环境下会丢包导致画面花屏TCP更稳定-i后面是刚才说的RTSP地址-c copy表示不重新编码直接复制流数据降低CPU消耗-f flv封装成FLV输出给流媒体服务器。如果这条命令能一直跑不报错说明流地址可用问题不在设备端如果卡在Opening阶段优先检查端口和账号密码如果运行后花屏考虑切换-rtsp_transport udp再对比。4.4 大华流地址参数调试记录调试过程中最常改的三个地方subtype、通道号、端口。先说通道号webapi接口返回的channelId是0基索引RTSP地址里是1基索引平台代码里如果直接用webapi通道号拼RTSP地址出来的流是错的或者黑屏。端口这块部分大华设备RTSP端口不是554需要在设备页面看有些定制固件改成什么端口的都有。还有subtype预览多画面的时候务必用1子码流回放单路高清的时候用0主码流这个策略能显著降服务器CPU占用。5. 避坑大华webapi集成最常见的六个翻车现场5.1 签名一直报错时间戳粒度不对现象按照文档写完签名算法请求返回signature error。原因大华webapi要求X-Dahua-Time是毫秒级时间戳我在第一次实现时用了int(time.time())秒级时间戳签名串里用的也是秒级设备端校验时取当前时间毫秒做比对时间窗口直接超出允许范围。解决统一改成str(int(time.time() * 1000))签名串、X-Dahua-Time、X-Dahua-Signature 三处用同一个时间戳变量不要把签名和请求头里的时间戳分开取两次。从那以后我写这类 signed 请求都强制用一个常量。5.2 开放平台appKey直连设备401不断现象内网环境里用开放平台申请好的 appKey 与 appSecret 去直连设备结果所有的请求全部返回 401登录也登不上。原因开放平台的 appKey 绑定的是大华开放平台账号体系授权关系在云端验证设备本地的 webapi 服务只认在设备上创建的本地 appKey。两边体系隔离不能混用。解决登录设备web页面在系统设置里找「平台对接」或「webapi配置」看到 appKey 和 appSecret 生成本地凭证用这组凭证做签名。我踩过的二次坑是设备本地生成的 appSecret 只显示一次刷新页面后就不再完整显示所以刚生成第一件事就是复制保存。忘了就只能重置影响在线业务。5.3 页面预览黑屏跨域和OPTIONS预检现象前端调用websdk登录成功startPreview返回成功但播放器区域一片黑控制台有跨域报错网络面板里能看到 CORS 的preflight请求失败。原因大华webapi服务对跨域支持有限浏览器发送带自定义头的请求时先发OPTIONS预检设备端webapi服务对OPTIONS方法处理不完整返回的不是允许的跨域响应浏览器直接拦截。解决在设备前面加一层 nginx 做反向代理把跨域请求转成同源请求。核心配置是把设备IP端口映射成前端同源的路径同时配置add_header允许跨域。这段配置我放到支持跨域的网关层而不是一台台设备上去改。5.4 子码流参数改了不生效现象在设备web页把子码流分辨率改成704x576但webapi调用子码流预览时分辨率还是原来的CIF怎么推流都不对。原因大华部分设备型号上子码流参数有「实时子码流」和「存储子码流」两个独立配置预览走的是实时通道存储走的是计划通道改错页面当然不生效。解决在设备配置页面找到「摄像机」-「编码」-「子码流」改完先重启设备再调用webapigetChannelInfo拉取实际的编码参数确认。我一般改完参数后先 curl 拿一帧流数据验证分辨率而不是直接在播放器里肉眼看画质。5.5 websdk在部分机器预览正常部分机器黑屏现象同一个项目领导电脑上预览没问题同事电脑上一片黑播放器区域无任何报错也不自动重新加载。原因大华websdk的播放器组件尤其插件型播放器在国产浏览器和部分系统上权限策略不同插件安装或者ActiveX启用的流程被拦截了。解决先看websdk文档里对浏览器内核的兼容说明主流推兼容 Chromium 88 内核优先让同事换新版Edge或者Chrome还不行就检查浏览器是否拦了插件加载项。这个问题的排查成本比较高我现在习惯在集成时就把播放器的错误回调详细打出来黑屏能定位到具体错误码。5.6 平台服务里面调用webapi超时与大华对接的并发量现象平台里同时开启几十路预览时部分webapi请求返回超时错误集中在Device busy。原因设备的webapi服务并发能力有限尤其低端型号同时处理几十个取流请求时CPU打满接口响应超时。解决把平台侧的取流逻辑改成「串行化」「限流器」轮询取流时限制最大并发数为设备型号允许的上限。同时把每次取流后拿到真正的流地址交给流媒体网关前端所有播放统一走后端拉流不再让播放器和设备直连。上千路的规模靠webapi直连设备根本扛不住网关是必须的一层。6. 上线前的验证技巧把一整套黑匣子拆开看最后分享一个我在上线前固定执行的做法用抓包和 curl 模拟把整套webapi链路的每个环节单独验证一遍而不是直接开着播放器点页面。第一步是验证签名。在集成环境上用 Python 脚本单独跑签名逻辑输出签出的X-Dahua-Signature拿同一条请求去 curl 设备直接看HTTP状态码和响应体。这一步能排除90%的鉴权问题。# 在终端手动模拟webapi请求避免前端页面的干扰 # 参数按签名结果填入 curl -X POST http://192.168.1.64:8090/openapi/accessToken \ -H X-Dahua-AppKey: your_app_key \ -H X-Dahua-Signature: appKey:base64sha1串 \ -H X-Dahua-Time: 1719400000000 \ -d ipAddress192.168.1.64portNo8090userNameadmin第二步是核对设备时间。签名校验强依赖时间窗口设备时间如果和服务器偏差超过几十秒签名就无效。我见过一个项目反复出现偶发401查到最后是设备NTP没配置时间慢了两分钟。上线前一定要确认设备端开启了NTP同步或者在设备页面手动校准。第三步是按下面的清单逐项检查检查项判断标准命令/位置签名是否正确返回code0或正常响应体上述curltoken是否过期响应码10001/401业务接口响应头RTSP地址是否有效ffmpeg能持续拉流ffmpeg命令设备时间同步与服务器相差60秒设备NTP设置页子码流分辨率实际值与预期一致webapi getChannelInfo浏览器控制台无CORS报错无红色报错F12 Console多路并发限制无Device busy压测脚本从那以后我每次拿到大华这类sdk资源包都强制先做一件事把官方文档里的接口列表和参数表全部过一遍抽出一个最小调用链路跑通再开始写业务别信什么「照着示例改就行」。webapi设备的坑基本都是参数和时序问题跑通最小链路之后后面的工作就会顺畅很多。希望帮到你。本文还有配套的精品资源点击获取
返回列表