资讯动态

海康ISAPI开发实战:球机对接的协议原理与避坑指南

发布时间:2026/10/14 16:05:51 来源:尧图企业网站定制
简介本资源是面向安防系统集成开发者、嵌入式工程师及智能视频平台研发人员的《ISAPI开发手册海康球形摄像机》官方技术文档聚焦基于HTTP/REST架构的智能安全API对接实践解决海康威视PTZ球机设备与上位平台间的认证登录、实时预览、录像回放、事件上报及智能功能调用等核心通信问题。手册覆盖DS-2DE、DS-2PT、iDS系列等数十款主流球型网络摄像机详述ISAPI框架、快速入门流程、11000接口分类指引并关联SADP设备发现、RTSP流媒体、OTAP/ISUP升级等协同协议兼顾公安、交通、教育等多行业落地场景。资源为单文件PDF共1个7.94MB高清技术文档内容结构完整含概览、框架、快速入门、接口指引、术语定义及适用产品清单等核心章节。已有2061人学习下载可直接用于开发环境搭建、接口调试参考与协议规范查证是开展海康设备二次开发不可或缺的权威指南。1. ISAPI 开发手册海康球形摄像机不是协议文档是能跑通的「设备对接黑匣子」拆解实录你手头有一台 DS-2PT3A40BX(T5) 球机IP 已配好但 curl 一发/ISAPI/System/deviceInfo就返回401 Unauthorized你照着示例写了 Python digest 认证结果设备日志里全是auth failed: nonce reused你把人脸图片和 XML 打包成 multipart/form-data 发过去设备却回400 Bad Request连错在哪都不知道——这不是你代码写得差而是 ISAPI 这个「安防领域最常用、文档最厚、踩坑最密」的协议根本没打算让你轻松上手。这份由苏州中皓智能科技有限公司发布的《ISAPI 开发手册海康球形摄像机》表面是 PDF 文档实则是海康系 PTZ 设备DS-2DE/DS-2PT/iDS-2PT 等全系列的完整通信契约白皮书它不讲 HTTP 基础不教 REST 是什么而是直接告诉你——设备在什么条件下接受什么格式的请求、返回什么结构的响应、哪些字段必须填、哪些边界值会触发静默失败。它面向的是正在集成球机到自研平台的嵌入式工程师、安防系统集成商的二次开发人员、以及需要绕过 Web UI 直接控制云台/调焦/事件订阅的现场实施工程师。如果你要做的不是“调通一个接口”而是“让 200 台球机在弱网环境下稳定上报人脸事件、支持断线重连、兼容固件升级后的新字段”那这份手册就是你唯一能信任的源码级依据。它不承诺完美但每一页都标着有效期 2025-07-12意味着所有接口定义、错误码、字段约束都是当前主流固件版本S5/S6/T5/T7的真实快照。2. ISAPI 协议本质HTTP REST 的安防特化实现不是通用 API 而是设备状态机映射ISAPI 不是凭空造出来的协议它是 HTTP/1.1 在安防设备上的深度定制。理解这一点是避免后续所有玄学问题的前提。很多开发者卡在第一步就是因为把 ISAPI 当成了普通 Web API —— 用 Postman 发 GET 请求填对了 URL 和 Basic Auth却忘了设备根本不认 Basic只认RFC 7616 摘要认证Digest Authentication或者以为/ISAPI/Intelligent/FDLib返回 JSON 就万事大吉结果发现设备默认只返回 XMLJSON 需要显式加?formatjson参数且部分老固件压根不支持该参数。ISAPI 的核心逻辑是把设备内部的状态、配置、事件流通过 RESTful 资源路径暴露出来每个 URL 对应一个可读写的设备实体如/System/deviceInfo是只读设备信息/System/time是可读写的时间配置而 HTTP 方法GET/PUT/POST/DELETE则对应设备对该实体的操作语义查询/修改/创建/删除。这种映射不是抽象的而是和设备固件的内存结构强绑定的。比如/Intelligent/FDLib/pictureUpload这个 POST 接口背后实际触发的是设备端人脸库管理模块的addFacePicture()函数调用并同步写入 Flash 存储区。因此ISAPI 的“REST”是表象“设备状态机驱动”才是内核。2.1 为什么必须用摘要认证Basic Auth 在球机上为何必然失败海康球机出厂默认关闭 Basic Auth这是硬性安全策略。设备固件在 HTTP Server 层做了拦截当收到Authorization: Basic xxx头时直接返回401并在响应头中带上WWW-Authenticate: Digest realm..., qopauth, nonce...强制要求客户端切换为 Digest 流程。Basic Auth 的明文密码传输风险在安防场景下是不可接受的。而 Digest 认证通过 nonce一次性随机数、cnonce客户端随机数、nc计数器和 HA1/HA2 哈希值的组合确保即使抓包也无法还原原始密码。手册第 4.1 节给出的 C/C libcurl 示例关键就在这一行curl_easy_setopt(pCurlHandle, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);这行代码告诉 libcurl别用默认的 Basic按 RFC 7616 规范走 Digest 流程。libcurl 会自动完成以下步骤发送无认证的 GET 请求解析设备返回的WWW-Authenticate头提取realm、nonce、qop用username:realm:password计算 HA1MD5 哈希用method:uri计算 HA2用HA1:nonce:nc:cnonce:qop:HA2计算最终响应值response将所有参数组装成Authorization: Digest ...头重发请求。提示如果手动拼装 Digest 头请务必注意ncnonce 计数器必须是 8 位十六进制字符串如00000001且每次新请求必须递增cnonce必须是客户端生成的 16 字节随机字符串推荐用 UUIDv4 的前 16 字节。任何格式错误都会导致401。2.2 XML 与 JSON 报文格式的隐性规则命名空间、版本号与 format 参数的生死线ISAPI 的报文格式绝非“能解析就行”。手册第 4.2.1.1 节明确指出所有 XML 报文必须声明默认命名空间xmlnshttp://www.isapi.org/ver20/XMLSchema且version2.0。这意味着即使你的 XML 结构完全正确只要漏了这个 namespace设备就会返回400 Bad Request且日志里可能只显示“XML parse error”不告诉你错在哪。看这个合法示例?xml version1.0 encodingUTF-8? NodeList xmlnshttp://www.isapi.org/ver20/XMLSchema version2.0 Node id1/id enabledtrue/enabled /Node /NodeList而这个非法设备拒绝?xml version1.0 encodingUTF-8? NodeList Node id1/id enabledtrue/enabled /Node /NodeListJSON 格式则依赖?formatjson参数。例如获取设备信息的标准 XML URL 是http://192.168.1.100/ISAPI/System/deviceInfo而 JSON 版本必须是http://192.168.1.100/ISAPI/System/deviceInfo?formatjson。手册强调“没有formatjson参数的 URL 对应的报文格式通常都是 XML但也存在个别例外”。这个“个别例外”就是坑点——比如/ISAPI/Event/triggers接口在某些 S6 固件中即使不加?formatjson设备也可能返回 JSON因历史兼容性但在 T5 固件中则严格返回 XML。因此最佳实践是所有你期望 JSON 的请求必须显式携带?formatjson并在 Accept 头中声明application/json。2.3 表单multipart/form-data的三重校验boundary、name、Content-ID 的协同陷阱当需要上传人脸图片、固件包或配置文件时ISAPI 强制使用 multipart/form-data。这不是为了“标准”而是因为设备端解析器是按此格式硬编码的。手册第 4.2.1.4 节给出了关键细节一个合法的 multipart 请求必须满足三个条件boundary 唯一性boundary 字符串如e5c2f8c5461142aea117791dade6414d不能出现在任何 part 的 body 中否则解析器会提前截断。实践中用uuid.uuid4().hex生成 32 位字符串是最稳妥的。name 字段的语义绑定每个 part 的Content-Disposition: form-data; namexxx中的xxx必须与 XML/JSON 请求体中对应的字段名严格一致。例如上传人脸时XML 中pId19d48a26f7b8b4f2390c16808f93f3534/pId1那么图片 part 的 name 就必须是9d48a26f7b8b4f2390c16808f93f3534而不是face_picture或image。Content-ID 的跨 part 关联在事件上报等复杂场景如 4.2.1.4 节的mixedTargetDetection示例XML/JSON 中的contentID1字段值如humanImage必须与对应图片 part 的Content-ID: humanImage完全匹配。设备端解析器会先读取 XML提取所有contentID再遍历所有 parts用Content-ID去查找对应二进制数据。ID 不匹配数据就丢失。下面是一个 Python requests 库构造合法 multipart 的核心代码基于手册示例import requests import uuid # 1. 生成唯一 boundary boundary uuid.uuid4().hex # 2. 构造 XML 数据注意必须包含命名空间 xml_data ?xml version1.0 encodingUTF-8? PictureUploadData xmlnshttp://www.isapi.org/ver20/XMLSchema version2.0 faceInfo pId1{p_id}/pId1 nametest_person/name /faceInfo /PictureUploadData.format(p_id9d48a26f7b8b4f2390c16808f93f3534) # 3. 读取图片二进制 with open(face.jpg, rb) as f: image_data f.read() # 4. 手动构造 multipart bodyrequests 会自动处理 boundary但需确保 name 匹配 files { PictureUploadData: (None, xml_data, application/xml), 9d48a26f7b8b4f2390c16808f93f3534: (face.jpg, image_data, image/jpeg) } # 5. 发送请求注意auth 必须是 digest response requests.post( http://192.168.1.100/ISAPI/Intelligent/FDLib/pictureUpload, filesfiles, authrequests.auth.HTTPDigestAuth(admin, admin12345) ) print(response.status_code, response.text)注意files字典的 key如9d48a26f7b8b4f2390c16808f93f3534就是Content-Disposition的name值它必须与 XML 中的pId1值完全一致。requests 库会自动添加Content-Type和Content-Length但name的语义绑定必须由开发者保证。3. 球机专属开发要点PTZ 控制、实时预览、事件订阅的协议级实现海康球形摄像机PTZ的核心价值在于其物理可动性——平移Pan、倾斜Tilt、变焦Zoom以及预置点、巡航、守望等高级功能。ISAPI 将这些硬件能力全部映射为标准的 HTTP 资源。但与普通网络摄像头不同球机的这些操作具有强状态性和时序敏感性。例如发送一个PUT /ISAPI/PTZCtrl/channels/1/continuous请求去启动连续转动设备不会立即执行而是进入“运动中”状态此时若立刻发另一个PUT去停止必须确保speed字段为0否则可能触发固件内部状态机冲突导致云台失控或返回503 Service Unavailable。手册第 3.4 节“视频取流”和第 4.3 节“实时预览”虽篇幅不长却隐藏着大量球机特有的协议细节。3.1 PTZ 连续控制/continuous接口的 speed 字段与方向编码球机的连续转动Continuous Move通过PUT /ISAPI/PTZCtrl/channels/{channelNo}/continuous实现。请求体是 XML核心字段是speed其值不是简单的 0-100 数字而是一个16 进制编码的 4 字节整数高 8 位表示水平Pan速度低 8 位表示垂直Tilt速度且速度值本身是带符号的正为右/下负为左/上。手册未明说但实测固件S6/T5的编码规则如下方向Pan 速度高8位Tilt 速度低8位16进制 speed 值向右0x32 (50)0x000x3200向左0xCE (-50)0x000xCE00向上0x000xCE (-50)0x00CE向下0x000x32 (50)0x0032右上0x320xCE0x32CE发送speed0x3200启动向右转动要停止必须发送speed0x0000。任何非零值都会被解释为新的运动指令。Python 实现示例import requests from lxml import etree def ptz_move(channel1, pan_speed0, tilt_speed0): # 构造 speed 值pan_speed 和 tilt_speed 为 -100 到 100 的整数 def to_signed_byte(v): if v 127: v 127 if v -128: v -128 return v 0xFF # 转为无符号字节 speed_hex (to_signed_byte(pan_speed) 8) | to_signed_byte(tilt_speed) xml_body f?xml version1.0 encodingUTF-8? PTZContinuousMove xmlnshttp://www.isapi.org/ver20/XMLSchema version2.0 speed{hex(speed_hex)}/speed /PTZContinuousMove response requests.put( fhttp://192.168.1.100/ISAPI/PTZCtrl/channels/{channel}/continuous, dataxml_body, headers{Content-Type: application/xml; charsetUTF-8}, authrequests.auth.HTTPDigestAuth(admin, admin12345) ) return response # 向右转动速度50 ptz_move(pan_speed50) # 停止 ptz_move(pan_speed0, tilt_speed0)3.2 RTSP 实时预览ISAPI 与 RTSP 的双协议协同ISAPI 本身不传输音视频流它只负责信令Signaling。真正的视频流必须通过 RTSP 协议拉取。手册第 3.4.1 节明确指出“视频设备支持标准的 RTSPReal Time Streaming Protocol, 详见 RFC 7826”。但球机的 RTSP URL 并非固定它由 ISAPI 接口动态生成。流程如下先用 ISAPI 查询设备支持的视频通道和码流类型GET /ISAPI/Streaming/channels返回 XML列出所有channelID和video子节点再查指定通道的主码流MainStreamURL 模板GET /ISAPI/Streaming/channels/1/video返回 XML其中streamingUrl字段即为 RTSP 地址如rtsp://192.168.1.100:554/Streaming/Channels/101最后用 VLC 或 ffmpeg 直接播放该 URL。关键点在于RTSP URL 中的端口如554和路径如/Streaming/Channels/101是设备固件预设的不能随意修改但 ISAPI 接口是获取它的唯一可靠途径。硬编码rtsp://ip:554/...在设备重启或固件升级后极易失效。此外手册提到 Metadata智能结构化信息会随 RTSP 流同步下发但这需要先通过 ISAPI 开启PUT /ISAPI/Intelligent/VideoAnalytics/metadata并将enabledtrue/enabled。开启后RTSP 的 SDP 描述中会包含acontrol:metadata字段客户端才能解析出人脸框、车牌等数据。3.3 事件订阅与上报/Event/notification的长连接保活与心跳机制球机的报警事件如移动侦测、人脸抓拍、越界入侵通过/ISAPI/Event/notification接口以 HTTP 长连接方式推送。这不是简单的 webhook而是一个需要客户端主动维护的 TCP 连接。手册第 2.3.8 节定义“事件”为“设备主动上报的信息”并强调“如果设备网络中断可以缓存下来待恢复后再上报”。这意味着客户端必须实现连接建立发送GET /ISAPI/Event/notification设备返回200 OK并保持连接打开心跳保活设备会在连接空闲约 30 秒后主动断开。客户端必须定期建议 25 秒发送一个空的OPTIONS请求到同一 URL以重置设备端超时计时器事件解析设备推送的数据是 multipart/form-data 格式如 4.2.1.4 节示例包含一个 JSON 描述事件元数据以及多个Content-ID关联的图片 part。客户端需按Content-ID将 JSON 与图片一一匹配。一个健壮的事件监听 Python 脚本框架如下import requests import time from urllib3.util.retry import Retry def start_event_listener(): session requests.Session() # 配置重试策略应对网络抖动 retry_strategy Retry( total3, backoff_factor1, status_forcelist[429, 500, 502, 503, 504], ) adapter requests.adapters.HTTPAdapter(max_retriesretry_strategy) session.mount(http://, adapter) session.mount(https://, adapter) # 1. 建立长连接 event_url http://192.168.1.100/ISAPI/Event/notification try: # 使用 streamTrue 保持连接 with session.get(event_url, auth(admin, admin12345), streamTrue, timeout(30, 300)) as r: if r.status_code ! 200: print(fFailed to start event listener: {r.status_code}) return # 2. 启动心跳线程在另一个线程中定期发 OPTIONS import threading def heartbeat(): while True: try: session.options(event_url, auth(admin, admin12345), timeout5) except Exception as e: print(fHeartbeat failed: {e}) time.sleep(25) # 25秒心跳间隔 hb_thread threading.Thread(targetheartbeat, daemonTrue) hb_thread.start() # 3. 解析流式响应 for line in r.iter_lines(): if line: # line 是 multipart 的 boundary 分隔符或数据块 # 实际解析需按 RFC 1341 处理 multipart此处简化为打印 print(fRaw event line: {line}) except requests.exceptions.RequestException as e: print(fEvent listener connection error: {e}) start_event_listener()注意iter_lines()只能读取文本行而事件流中的图片是二进制。真实项目中必须用r.raw获取原始 socket 流并用email.parser.BytesParser或专用 multipart 解析器如requests-toolbelt的MultipartDecoder来分离 JSON 和图片 parts。4. 避坑指南ISAPI 开发中 5 个血泪经验换来的高频翻车点ISAPI 手册里那些轻描淡写的“注意事项”、“说明”、“一般来讲”往往是开发者调试三天三夜后才悟出的真相。以下 5 条全部来自某公司某跨平台安防系统集成项目的真实排错记录每一条都对应一个让开发团队集体沉默的凌晨三点。4.1 现象PUT /ISAPI/System/time返回400 Bad Request但 XML 结构与手册示例完全一致原因设备时间格式校验极严。手册示例中time节点的dateTime字段值为2009-11-14T15:2708:00但实际固件尤其是 S6 早期版本要求08:00必须是0800无冒号。更隐蔽的是T字母必须是大写2009-11-14t15:270800会被拒绝。解决严格按YYYY-MM-DDTHH:MM:SSHHMM格式生成时间字符串用 Python 的datetime.now().strftime(%Y-%m-%dT%H:%M:%S%z)会生成0800但需手动插入冒号更稳妥是用isoformat()后替换dt.isoformat().replace(, )实际是dt.isoformat().replace(:, , 2)去掉时分秒间的冒号再补。4.2 现象POST /ISAPI/Intelligent/FDLib/pictureUpload成功返回200但/ISAPI/Intelligent/FDLib/pictures查询不到该人脸原因pictureUpload接口的 XML 请求体中pId1字段的值如9d48a26f7b8b4f2390c16808f93f3534被设备当作“临时 ID”仅用于本次上传关联并非人脸在库中的永久 ID。设备入库后会生成一个新的、内部管理的FDID人脸库 ID该 ID 无法通过 upload 接口指定。解决上传成功后必须立即调用GET /ISAPI/Intelligent/FDLib/pictures?formatjson在返回的 JSON 数组中根据name字段即上传时 XML 中的name值找到对应的人脸条目从中提取真实的FDID字段名通常是id或fdId后续所有对该人脸的操作如删除、比对都必须用这个FDID而非上传时的pId1。4.3 现象GET /ISAPI/Streaming/channels/101返回404 Not Found但/ISAPI/Streaming/channels显示 channelID 为1原因ISAPI 的 channelID 是逻辑通道号而 RTSP URL 中的101是物理流编号。手册第 2.3.18 节“通道管理模式”指出球机支持“通道模式”Channel Mode和“任务管理模式”Task Mode。在 Channel Mode 下主码流 channelID1 对应 RTSP URL/Streaming/Channels/1011001子码流 channelID1 对应/Streaming/Channels/102但在 Task Mode 下编号规则完全不同。设备默认是 Channel Mode但某些固件升级后可能被重置为 Task Mode。解决先查设备当前模式GET /ISAPI/Intelligent/VideoAnalytics/taskMode。若返回taskModetask则必须用GET /ISAPI/Intelligent/VideoAnalytics/tasks获取任务列表再从任务中提取streamingUrl字段而非硬套/Streaming/Channels/{id}01。4.4 现象POST /ISAPI/Event/triggers创建移动侦测布防成功但设备无任何事件上报原因移动侦测Motion Detection的布防开关有两个层级。第一层是全局使能PUT /ISAPI/Event/inputs/1中enabledtrue/enabled第二层是具体通道的灵敏度设置PUT /ISAPI/Event/inputs/1/motionDetection中sensitivityLevel5/sensitivityLevel。手册未强调但实测发现若sensitivityLevel为0最低即使enabled为true设备也认为“未布防”。解决创建触发器后必须紧接着发送一个PUT请求到/ISAPI/Event/inputs/1/motionDetection将sensitivityLevel设为1到10之间的有效值推荐5否则布防无效。4.5 现象GET /ISAPI/System/deviceInfo在浏览器中能正常返回 XML但用 Python requests 发送相同请求却返回401原因requests 库的auth参数在 Digest 认证中会自动添加Accept头为*/*。而某些海康球机固件特别是 iDS 系列 T5对Accept头有严格校验要求必须是application/xml或application/json否则拒绝认证。解决显式设置headers覆盖 requests 的默认Acceptheaders { Accept: application/xml, Content-Type: application/xml; charsetUTF-8 } response requests.get( http://192.168.1.100/ISAPI/System/deviceInfo, authrequests.auth.HTTPDigestAuth(admin, admin12345), headersheaders )5. 进阶验证用 curl jq xmllint 构建本地化接口沙箱告别盲目调试在真实项目中你不可能每次改一行代码就部署到球机上测试。最高效的开发节奏是在 PC 上构建一个能 100% 模拟球机响应行为的本地沙箱。这不需要模拟整个固件只需用标准 Unix 工具链把手册里的每一个接口定义、每一个 XML/JSON 示例、每一个错误码变成可执行、可验证的命令行脚本。这样当你写出一个pictureUpload的 multipart 请求时能在 3 秒内看到它是否符合 boundary 规则、name 是否匹配、XML 命名空间是否正确——而不是等球机返回400再猜。5.1 用 xmllint 验证 XML 命名空间与结构合法性xmllint 是 libxml2 的命令行工具能严格校验 XML 是否符合 DTD 或 Schema。虽然 ISAPI 没有公开 XSD但我们可以用其内置的命名空间检查功能。手册要求所有 XML 必须有xmlnshttp://www.isapi.org/ver20/XMLSchema我们用 xmllint 提取并验证# 将手册示例 XML 保存为 device_info.xml cat device_info.xml EOF ?xml version1.0 encodingUTF-8? NodeList xmlnshttp://www.isapi.org/ver20/XMLSchema version2.0 Node id1/id enabledtrue/enabled /Node /NodeList EOF # 验证命名空间是否存在且正确 xmllint --xpath /*[namespace-uri()http://www.isapi.org/ver20/XMLSchema] device_info.xml # 如果输出非空则命名空间正确否则报错 # 验证 version 属性值 xmllint --xpath /*/version device_info.xml | grep -q 2.0 echo version OK || echo version ERROR5.2 用 curl 模拟 Digest 认证全流程抓包分析 nonce 复用问题Digest 认证失败最常见的原因是nonce reused。用 curl 的-v参数可以完整看到请求-响应循环# 第一次请求无认证 curl -v -X GET http://192.168.1.100/ISAPI/System/deviceInfo 21 | grep WWW-Authenticate # 输出类似WWW-Authenticate: Digest realmHIKVISION, qopauth, nonceabc123, opaquedef456 # 手动构造第二次请求带 Digest 头 # 注意nc 必须是 8 位cnonce 是随机字符串 curl -v -X GET http://192.168.1.100/ISAPI/System/deviceInfo \ -H Authorization: Digest usernameadmin, realmHIKVISION, nonceabc123, uri/ISAPI/System/deviceInfo, cnoncexyz789, nc00000001, qopauth, responsea1b2c3d4e5f67890 \ -H Accept: application/xml # 如果返回 401 且 WWW-Authenticate 中的 nonce 与上次相同说明设备端 nonce 未刷新需检查固件版本5.3 用 jq 解析 JSON 响应快速定位字段缺失当?formatjson接口返回数据时用 jq 可以秒级验证关键字段# 获取设备信息 JSON curl -s http://192.168.1.100/ISAPI/System/deviceInfo?formatjson \ -u admin:admin12345 | jq . # 检查是否有 model 字段且不为空 curl -s http://192.168.1.100/ISAPI/System/deviceInfo?formatjson \ -u admin:admin12345 | jq -e .model | select(length 0) /dev/null echo model OK || echo model MISSING # 检查所有通道的 streamingUrl 是否都以 rtsp:// 开头 curl -s http://192.168.1.100/ISAPI/Streaming/channels?formatjson \ -u admin:admin12345 | jq -r .StreamingChannelList.StreamingChannel[].streamingUrl | grep ^rtsp:// /dev/null echo RTSP URLs OK || echo RTSP URLs INVALID5.4 构建自动化测试脚本验证 10 个核心接口的连通性与基础字段最后把以上技巧封装成一个isapi_health_check.sh脚本作为每日构建CI的一部分#!/bin/bash DEVICE_IP192.168.1.100 USERadmin PASSadmin12345 echo ISAPI Health Check for $DEVICE_IP # 1. 设备信息 echo -n 1. Device Info... if curl -s -o /dev/null -w %{http_code} http://$DEVICE_IP/ISAPI/System/deviceInfo?formatjson -u $USER:$PASS | grep -q 200; then echo OK else echo FAIL exit 1 fi # 2. 时间同步 echo -n 2. Time Sync... TIME_NOW$(date -u %Y-%m-%dT%H:%M:%S%z | sed s/\(..$\)/\1/) TIME_XML?xml version\1.0\ encoding\UTF-8\?Time xmlns\http://www.isapi.org/ver20/XMLSchema\ version\2.0\timedateTime$TIME_NOW/dateTime/time/Time if curl -s -o /dev/null -w %{http_code} -X PUT http://$DEVICE_IP/ISAPI/System/time -u $USER:$PASS -H Content-Type: application/xml -d $TIME_XML | grep -q 200; then echo OK else echo FAIL exit 1 fi # 3. PTZ 控制只发停止指令不真转动 echo -n 3. PTZ Stop... PTZ_STOP_XML?xml version1.0 encodingUTF-8?PTZContinuousMove xmlnshttp://www.isapi.org/ver20/XMLSchema version2.0speed0x0000/speed/PTZContinuousMove if curl -s -o /dev/null -w %{http_code} -X PUT http://$DEVICE_IP/ISAPI/PTZCtrl/channels/1/ p a hrefhttps://download.csdn.net/download/qq_37059136/88547425 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑