尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ONVIF与RTSP对接实战:从设备发现到OnvifDeviceManager拉流排坑指南

ONVIF与RTSP对接实战:从设备发现到OnvifDeviceManager拉流排坑指南 简介这是一份面向ONVIF协议开发者的RAR压缩包聚焦RTSP视频流与OnvifDeviceManager的成功对接。资源围绕NVT端视频流接入OnvifDeviceManager这一场景给出可直接参考的C代码核心实现适合正在调试ONVIF视频通路、需要理解设备端与Manager握手细节的开发者。包内仅1个c源码文件即作者手写的核心实现总大小仅13KB其余辅助代码可按博文方法自动生成因此压缩包极为精简便于聚焦关键逻辑。该资源已被2658人学习/下载说明其在同类问题上有一定代表性。与直接拿来即用的完整工程不同这份资源更强调“过一遍”的参考价值读者可结合源码梳理ONVIF协议对接流程对比自身实现中的差异点从而定位RTSP流无法显示或设备注册失败等问题的原因。整体上资源虽小却为ONVIF-RTSP对接提供了一条经过验证的实战路径。 这段时间一直在调摄像头的ONVIF协议对接目标很明确让自研设备的RTSP视频流能被OnvifDeviceManager正常发现、配网、拉流播放。折腾了几天总算把这链路完整跑通从设备发现、能力协商到最终在OnvifDeviceManager里看到实时画面每一步背后的坑和原理也基本摸清楚了。这篇文章把整个对接过程、关键设计思路、实操步骤和排查经验都整理出来给同样在做ONVIF设备端开发、或者需要验证自家摄像头兼容性的朋友一份参考。先说结论ONVIF和RTSP对接本身不复杂真正磨人的是协议细节。很多设备能出画面却在OnvifDeviceManager里时好时坏问题多半出在鉴权、地址拼接、端口绑定这些容易被忽略的地方。下面我会按整体设计→设备端链路分析→实测步骤→问题排查的顺序来写尽量让刚接触这个领域的人也能少走弯路。1. 项目整体思路与方案选型1.1 ONVIF和RTSP各管哪一段很多人把ONVIF和RTSP混在一起说其实这俩解决的是不同层面的问题。ONVIF是设备端的标准接口协议负责设备发现、能力协商、参数配置这类管理面的事RTSP是媒体会话控制协议负责协商视频流的传输方式、地址属于媒体面。在实际对接里ONVIF负责帮你找到设备、问清设备支持什么、拿到媒体地址拿到地址之后才轮到RTSP上场由播放器或取流模块去建立会话、拉流。用生活化的例子说ONVIF就像酒店前台你入住时前台告诉你房间号、WiFi密码、餐厅开放时间RTSP则是客房服务通道你通过它把餐点视频流送到房间。没有前台你找不到房间没有客房服务你知道了房间号也没用。对接ONVIF的主要目的就是顺利从前台手里拿到那张写有RTSP地址的纸条并能凭有效凭证用户名密码通过客房通道。所以我做这个项目时第一件事就是把这两条线拆开先保证ONVIF管理链路通再验证RTSP媒体链路。两条线都稳了OnvifDeviceManager才能丝滑播放。1.2 为什么选OnvifDeviceManager做验证工具OnvifDeviceManager是Windows平台上一款免费的ONVIF调试工具界面简洁不需要配置环境装完打开就能用。它能自动发WS-Discovery广播、发现局域网内的ONVIF设备还能浏览设备能力、查看Profile、触发取流、测试PTZ控制等基础操作。我选择它作为首选验证工具原因有几个。第一它对协议完整性要求高如果设备端哪个接口实现不对它往往会直接报错或卡在某一步问题暴露得很清晰。第二它自带的媒体信息查看功能可以直接拿到GetStreamUri返回的RTSP地址省得自己用代码去解析SOAP报文。第三在开发阶段用它验证通过基本意味着其他ONVIF客户端比如各家NVR、平台软件大概率也能兼容。相比之下ONVIF Device Test Tool那种按规范逐项测试的重型工具更适合做认证前的完整回归日常对接调试用OnvifDeviceManager效率更高。当然工具终归只是辅助重点还是把设备端服务实现正确。下面我来拆解设备端从开机到被成功取流到底要过哪几关。2. 设备端服务梳理从发现到取流的关键链路2.1 设备发现与鉴权机制ONVIF设备发现走的是WS-Discovery协议本质是一种基于UDP多播的机制。设备上电后加入组播组客户端OnvifDeviceManager发送一个探测消息Probe设备收到后回复ProbeMatch这样客户端就能拿到设备的元数据地址XAddr。这个过程是ONVIF一切交互的第一步。这里有个容易踩的坑设备必须在UDP 3702端口上正确监听多播地址而且回复报文中的地址要能被客户端访问。如果设备有多个网卡回复的XAddr写死了内网IP而客户端在另一个网段那就会发生能发现但打不开的情况。正确的做法是通过探测请求的来源IP动态决定XAddr的IP部分或者至少在设备端做多网卡地址策略。鉴权方面ONVIF默认使用WS-UsernameToken。简单说就是在SOAP头部附带用户名、密码摘要PasswordDigest和一个随机数Nonce以及时间戳Created。服务端收到后会用同样的算法重新计算摘要比对一致才算通过。这里时间戳特别重要设备通常只容忍5分钟以内的时钟偏差。如果设备没有校时而客户端电脑时间不同步就会出现添加设备时提示密码错误的怪现象。鉴权要素用途常见坑Username标识用户大小写敏感PasswordDigest密码摘要Base64编码格式错误Nonce防重放重复使用会被某些客户端拒绝Created时间戳设备与客户端时钟偏差超过5分钟会失败2.2 拿到RTSP地址的关键流程当客户端成功发现并鉴权后会按顺序调用这几个接口GetCapabilities拿能力GetProfiles拿媒体配置最后GetStreamUri拿具体的RTSP URL。这个过程看起来简单但每一步都可能出问题。GetCapabilities返回的是各类服务的地址比如MediaService的XAddr。注意有些设备把Media服务地址写死在固定路径有些则是动态生成的如果地址写错后面所有请求都会404。GetProfiles返回设备预置的媒体Profile包含视频编码、分辨率、帧率等参数。OnvifDeviceManager一般会列出所有Profile用户选一个去拉流。如果设备没正确返回Profile客户端会看不到任何可播放的流。最关键的是GetStreamUri。这个请求需要传入ProfileToken和StreamType通常为RTP-Unicast或RTP-Multicast。设备返回的RtspUrl一般是类似rtsp://192.168.1.100:554/stream1这样的地址。这里的坑是很多设备在响应里填的是localhost或设备自身的主机名客户端拿到这个地址根本连不上。解决方法是设备端在生成RtspUrl时要根据请求的来源IP动态拼接或者统一填成rtsp://设备IP:554/...并确保554端口对外开放。按照我们项目实测使用GetStreamUri返回地址后OnvifDeviceManager会自动调用RTSP DESCRIBE和SETUP收到200 OK后就能出画面。整个过程大概1-2秒如果超过5秒没画面基本可以判断RTSP交互某个环节卡住了。3. 实测接入过程与关键步骤3.1 环境准备与工具部署为了方便复现我列一下本次对接使用的环境操作系统Windows 10 专业版OnvifDeviceManager运行端设备端自研IPC开发板支持H.264/H.265编码Linux系统ONVIF工具OnvifDeviceManager 3.1.1抓包工具Wireshark 4.0播放验证VLC media player 3.0备用OnvifDeviceManager不需要安装解压双击exe就能运行。首次启动时它会自动发送WS-Discovery探测局域网内的ONVIF设备一般会在几秒内出现在左侧列表里。如果没有自动发现可以手动点添加设备输入设备的IP和ONVIF端口通常是80或8080。Wireshark建议安装后先配置好抓包过滤条件只抓设备IP和UDP 3702端口以及TCP 554端口避免抓包文件过大影响分析。VLC准备好用于验证GetStreamUri返回的RTSP地址是否能独立播放这能快速把问题定位到ONVIF侧还是RTSP侧。3.2 RTSP地址拼接与播放验证在项目里我们约定设备端的RTSP取流URL遵循通用的规则rtsp://用户名:密码设备IP:端口/路径。路径部分由设备决定比如/stream1、/ch01等。但要注意ONVIF的GetStreamUri返回的URL往往不带用户名密码而是靠RTSP的401挑战机制进行鉴权。也就是说播放器先发DESCRIBE设备回401并带WWW-Authenticate头播放器再带Authorization头重发。这个机制在OnvifDeviceManager和VLC里都支持得很好。实测时我建议分两步验证先用VLC直接打开OnvifDeviceManager里显示出来的RTSP地址输入用户名密码看能不能出画面。如果VLC能出画面而OnvifDeviceManager不行那问题大概率在ONVIF的Profile配置或GetStreamUri返回参数上。再回到OnvifDeviceManager选择对应Profile点播放按钮观察是否正常出流。我在项目中还测试了不同厂家设备的RTSP地址格式方便大家参考设备类型RTSP地址常见格式说明海康威视rtsp://user:passip:554/Streaming/Channels/101101表示通道1主码流小米摄像头rtsp://user:passip:8554/xxx端口和路径因固件版本而异自研设备rtsp://user:passip:554/stream1自定义路径需在GetStreamUri中返回从实测结果看用OnvifDeviceManager播放的关键不在于RTSP路径长什么样而在于设备返回的RtspUrl是否准确、RTSP端口是否监听、以及鉴权是否兼容。只要这三条满足VLC和OnvifDeviceManager都能正常出图。3.3 从抓包视角验证对接是否成功如果OnvifDeviceManager和VLC都能出画面说明对接基本成功。但作为开发人员我习惯再用Wireshark确认一下关键报文。抓包时长建议控制在10秒左右抓完后重点看这几个环节UDP 3702端口是否有Probe和ProbeMatch报文确认设备发现成功TCP 80或ONVIF端口的HTTP / SOAP报文里是否出现200 OK确认GetCapabilities、GetProfiles、GetStreamUri依次成功TCP 554端口是否有RTSP请求依次是OPTIONS、DESCRIBE、SETUP、PLAYRTP报文是否在PLAY之后持续到达确认视频流真实传输这里有个细节很多自研设备在ONVIF端口上同时集成了HTTP和RTSP服务但是Wireshark默认可能无法正确解析RTSP报文因为它识别不了自定义端口。这个问题我放在后面的排查部分详细说明。4. 排查实录对接过程中最容易踩的5个坑4.1 OnvifDeviceManager看不到设备这是最经典的问题。设备明明在线OnvifDeviceManager却搜不到。排查思路第一步确认设备侧WS-Discovery是否正常。在设备端抓UDP 3702报文看有没有收到Probe。如果没收到检查防火墙是否屏蔽了UDP 3702端口的入站多播报文同时确认设备是否加入了正确的多播组239.255.255.250。第二步如果收到了Probe但没有回复或者回复报文客户端收不到重点检查XAddr的地址拼接。我之前遇到过一个设备多播探测回复里写的是127.0.0.1客户端当然访问不到。第三步如果设备在某个网段正常、另一个网段搜不到大概率是多播路由问题或设备端回复地址写死。稳妥方案是把回复地址动态生成为请求来源IP对应的本机地址。4.2 能发现但拉流失败设备能发现说明ONVIF的发现和鉴权链路基本通了但拉流失败通常发生在GetStreamUri、RTSP鉴权或编码协商环节。一种常见情况是GetStreamUri返回了rtsp://localhost:554/stream1OnvifDeviceManager直接拿这个地址去连必然失败。解决思路设备端生成RtspUrl时用请求的来源IP替换hostname确保返回的地址对客户端可见。另一种情况是RTSP端口没有监听。有些设备把ONVIF和RTSP都放到8080端口但RTSP服务实际绑定在127.0.0.1上外部无法访问。排查方法是设备上执行netstat -an | grep 554确认端口监听在0.0.0.0或可访问的IP上。还有一种情况是编码格式不兼容。比如设备只输出H.265而OnvifDeviceManager运行的平台解码能力有限可能黑屏或卡顿。这个不算协议错误但会让人误以为对接失败。4.3 Wireshark识别不了RTSP包在抓包分析时Wireshark默认只解析标准554端口上的RTSP。如果你的设备RTSP端口是8554或自定义的其它端口Wireshark会把这些报文的协议识别为TCP或HTTP导致看不到RTSP方法名和状态码。解决办法很简单在Wireshark中右键点击任意一条相关TCP报文选择解码为Decode As把目标端口如8554手动指定为RTSP协议重新抓包或应用解码规则后RTSP报文就会正确显示。这个操作在热词里也看到了wireshark decode as 当前没有rtsp协议的提问说明是大家常遇到的共性问题。但通常只有在自己实现RTSP服务、或者在自定义端口上做调试时才需要这样处理。顺带提一句RTSP报文的顺序也很重要。规范的流程是OPTIONS→DESCRIBE→SETUP→PLAY如果设备在DESCRIBE阶段直接返回200而没经过401鉴权可能会导致某些播放器不兼容。4.4 IPv6下的ONVIF测试经验有些项目要求设备支持IPv6ONVIF本身是支持IPv6的但实测中有几个点需要特别留意。WS-Discovery在IPv6下使用不同的多播地址通常是ff02::c而且有些老的OnvifDeviceManager版本只支持IPv4导致设备和工具不在同一协议栈上时永远发现不了。另外在IPv6环境下获取RtspUrl时URL的格式必须是rtsp://[2001:db8::1]:554/stream1这种带方括号的写法否则解析会有歧义。设备端代码里如果直接把IPv6地址通过%s拼进URL很容易遗漏方括号导致RTSP连接失败。测试IPv6时建议先确认客户端工具支持IPv6再确认设备返回的URL地址格式正确最后使用Wireshark的抓包分析功能来确认RTSP请求和响应。4.5 公网RTSP地址无法播放热词里提到了网络rtsp视频流 公网测试地址公开rtsp直播流公网开放的rtsp地址很多人想用公网RTSP源来测试播放器或取流模块但经常遇到打不开的情况。首先要明确一个事实绝大多数家用摄像头和自研设备默认不支持公网直连取流因为RTSP使用TCP或UDP传输需要做端口映射。如果你的设备在NAT后面公网客户端是无法直接访问内网IP的。实测方法上有两种思路。一种是端口映射在路由器上把RTSP端口映射到公网客户端用公网IP加映射端口访问。但ONVIF的发现报文走多播公网环境下基本不能穿透所以公网场景更多是直接访问RTSP地址而不是通过ONVIF发现。另一种思路是搭建一台有公网IP的代理服务器把内网RTSP流转发出去。这个方案适合长期稳定使用但需要额外一台云主机。我在项目里测过用公网RTSP源调试播放器时重点要检查端口是否被封、是否开启了鉴权、编码格式是否被播放器支持。如果这几个都正常VLC一般都能直接打开。简单来说公网取流能用但限制较多还是优先在局域网内做完整验证更靠谱。5. 一些体会和补充建议整个项目做下来我的感受是ONVIF协议框架本身很成熟难点不在规范上而在实现细节的严谨程度。设备端服务哪怕一个小问题上处理不到位比如SOAP报文缺少某个必填字段、鉴权时间戳计算错误、RtspUrl没有动态生成都能让客户端表现得很玄学。在调试过程中建议始终遵从一个原则先用工具验证再写代码。工具本身能节省很多时间——用OnvifDeviceManager验证设备发现用VLC验证RTSP地址用Wireshark定位协议层问题。这三个工具配合好基本能覆盖90%的对接问题。我也建议开发者在做完基础对接后主动多测几种客户端。有的播放器对鉴权方式的要求更严格有的NVR对Profile字段的要求更苛刻。用真实的第三方客户端去做兼容验证会比只用测试工具更早暴露问题。最后再分享一个我在项目里验证过的实用小技巧OnvifDeviceManager连不上时可以先在设备端打开Wireshark抓包然后点击OnvifDeviceManager里的刷新看设备端是否收到探测报文。如果抓不到任何报文问题根本不在协议而在网络连通性上如果收到报文但没有回复再深入分析协议逻辑——这样能快速缩小排查范围省下大量没必要的分析时间。本文还有配套的精品资源点击获取
返回列表