开源工具:ONVIF协议实现搜索局域网摄像机(IPC)+RTSP地址获取

Onvif协议做安防监控的人应该都很熟悉,它广泛被用在各种安防设备中,比如IPC、DVR、NVR。在局域网中发现IPC设备很多就是基于Onvif协议实现的。本文章给大家介绍QuickGBLink开源的一个工具,该工具能够通过Onvif的设备发现将局域网内的Onvif IPC枚举出来,显示到界面的列表中,并且可以获得每个IPC设备的RTSP流地址。该工具界面截图如下:

开源工具:ONVIF协议实现搜索局域网摄像机(IPC)+RTSP地址获取_第1张图片

1. Onvif搜索设备的原理

Onvif客户端向网段内固定的某个组播地址发送一段广播报文,这个组播地址就是:239.255.255.250,端口:3702。而Onvif服务端(响应消息的设备)在固定端口上监听,接收到广播消息之后向发送者回复消息,回复的消息里返回设备自己的IP、UUID、EP Address、Type等,最重要的会返回设备的Device Service Address,格如:http://192.168.0.64:8099/onvif/device_service ,此地址就是为设备提供Onvif服务的服务地址。

2. 报文发送和接收

Onvif客户端向局域网内固定组播组发送的广播报文:


xmlns="http://www.w3.org/2003/05/soap-envelope">



uuid:25862dc4-4866-42a9-87a7-edcf2918ab10


urn:schemas-xmlsoap-org:ws:2005:04:discovery


http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe



xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns="http://schemas.xmlsoap.org/ws/2005/04/discovery">
dn:NetworkVideoTransmitter




 

Onvif服务端回复的报文,消息格式如下:


xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xs="http://www.w3.org/2000/10/XMLSchema"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
secext-1.0.xsd" 
xmlns:wsa5="http://www.w3.org/2005/08/addressing" 
xmlns:xop="http://www.w3.org/2004/08/xop/include" 
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"  
xmlns:tt="http://www.onvif.org/ver10/schema"  xmlns:ns1="http://www.w3.org/2005/05/xmlmime" 
xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" 
xmlns:ns7="http://docs.oasis-open.org/wsrf/r-2" 
xmlns:ns2="http://docs.oasis-open.org/wsrf/bf-2" 
xmlns:dndl="http://www.onvif.org/ver10/network/wsdl/DiscoveryLookupBinding" 
xmlns:dnrd="http://www.onvif.org/ver10/network/wsdl/RemoteDiscoveryBinding" 
xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" 
xmlns:dn="http://www.onvif.org/ver10/network/wsdl" 
xmlns:ns10="http://www.onvif.org/ver10/replay/wsdl" 
xmlns:ns11="http://www.onvif.org/ver10/search/wsdl"
xmlns:ns13="http://www.onvif.org/ver20/analytics/wsdl/RuleEngineBinding" 
xmlns:ns14="http://www.onvif.org/ver20/analytics/wsdl/AnalyticsEngineBinding" 
xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" 
xmlns:ns15="http://www.onvif.org/ver10/events/wsdl/PullPointSubscriptionBinding" 
xmlns:ns16="http://www.onvif.org/ver10/events/wsdl/EventBinding" 
xmlns:tev="http://www.onvif.org/ver10/events/wsdl" 
xmlns:ns17="http://www.onvif.org/ver10/events/wsdl/SubscriptionManagerBinding" 
xmlns:ns18="http://www.onvif.org/ver10/events/wsdl/NotificationProducerBinding" 
xmlns:ns19="http://www.onvif.org/ver10/events/wsdl/NotificationConsumerBinding" 
xmlns:ns20="http://www.onvif.org/ver10/events/wsdl/PullPointBinding" 
xmlns:ns21="http://www.onvif.org/ver10/events/wsdl/CreatePullPointBinding" 
xmlns:ns22="http://www.onvif.org/ver10/events/wsdl/PausableSubscriptionManagerBind
ing" 
xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" 
xmlns:ns3="http://www.onvif.org/ver10/analyticsdevice/wsdl" 
xmlns:ns4="http://www.onvif.org/ver10/deviceIO/wsdl" 
xmlns:ns5="http://www.onvif.org/ver10/display/wsdl" 
xmlns:ns8="http://www.onvif.org/ver10/receiver/wsdl" 
xmlns:ns9="http://www.onvif.org/ver10/recording/wsdl" 
xmlns:tds="http://www.onvif.org/ver10/device/wsdl" 
xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" 
xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl"
xmlns:trt="http://www.onvif.org/ver10/media/wsdl" 
xmlns:trt2="http://www.onvif.org/ver20/media/wsdl" 
xmlns:ter="http://www.onvif.org/ver10/error"  xmlns:tns1="http://www.onvif.org/ver10/topics" 
xmlns:tnsn="http://www.eventextension.com/2011/event/topics">

urn:uuid:327b23c6-5566-7788-99ac-001217d7bf0f

uuid:25862dc4-4866-42a9-87a7-edcf2918ab10


http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous


http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches






urn:uuid:b12dca78-5566-7788-99aa-001217d7bf0f


dn:NetworkVideoTransmitter

onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/type/audio_encoder 
onvif://www.onvif.org/hardware/IPC-model onvif://www.onvif.org/location/country/china 
onvif://www.onvif.org/name/NVT onvif://www.onvif.org/Profile/Streaming


http://192.168.0.64:8099/onvif/device_service

10




 

Onvif客户端解析上面收到的数据,得到IPC摄像头的「设备服务地址」,即XAddrs字段,
 http://192.168.0.64:8099/onvif/device_service

3. 实现Onvif设备发现类

我们将Onvif设备发现功能的逻辑处理都放到一个类里面实现,这个类的声明如下:

class DEVICE_IPC_INFO
{
public:
	char          hardware_type[128]; //硬件型号
	char          DeviceName[64];
	char          DeviceID[128]; //uuid
	char          IP[32];
	int           Port;

	DEVICE_IPC_INFO()
	{
		memset(DeviceName, 0, sizeof(DeviceName));
		memset(DeviceID, 0, sizeof(DeviceID));
		memset(IP, 0, sizeof(IP));
		memset(hardware_type, 0, sizeof(hardware_type));
		Port = 80;
	}

	DEVICE_IPC_INFO& operator =(const DEVICE_IPC_INFO& t) 
	{
		strcpy(hardware_type, t.hardware_type);
		strcpy(DeviceName, t.DeviceName);
		strcpy(DeviceID, t.DeviceID);
		strcpy(IP, t.IP);
		Port = t.Port;

		return *this;
	}
};


typedef void (CALLBACK* DeviceDiscoverCB)(DEVICE_IPC_INFO * pInfo, LPVOID lpContext);

class COnvifDiscovery
{
public:
	COnvifDiscovery(void);
	~COnvifDiscovery(void);

	void SetDiscoveryInfoCB(DeviceDiscoverCB lpCallback, LPVOID lpContext);
	int  StartFind(void);
	void StopFind();

protected:
	static DWORD WINAPI ReceivingThrd(void * pParam);

	int probeSocketIni(int *fd);
	void probeSocketEnd(int *fd);
	int sendProbe(int fd,const char *uuid,const char *types);
	int recvProbeMatches(int fd,int timeout);

	void ReceivingLoop(void);

	 int     m_fd;
	 BOOL    m_bIsReceiving;
	 HANDLE  m_hRcvThread;

	 DeviceDiscoverCB m_lpCallback;
	 LPVOID           m_lpContext;
};

这个类的头文件和源文件是Discover.h、Discover.cpp。具体实现过程这里略过。

4.常见问题答疑

1. 获取RTSP地址需要填写IPC的登录用户名和密码。但是,连某些摄像机,填写了用户名和密码之后,登录摄像机获取流信息失败,如下图:

开源工具:ONVIF协议实现搜索局域网摄像机(IPC)+RTSP地址获取_第2张图片
错误原因可能是填写的登录IPC的用户名或密码错误,导致用户权鉴失败;也有可能是这个用户是没有Onvif访问权限(需要在IPC上做配置,这个问题多出现在海康的摄像机系列)。

关于这个问题的解决办法,请看这篇文章:

https://blog.csdn.net/QuickGBLink/article/details/103442791

2. 成功获取流信息后,可以选择流索引(流编号)从而显示不同通道的流URL,一般的摄像机有双码流,所以有两个通道的流,但是有些摄像机有三个流的。用户可以切换选择不同的流编号(通道编号),然后拷贝这个流的RTSP地址,放到VLC播放器中或我们的RTSP客户端中播放。

开源工具:ONVIF协议实现搜索局域网摄像机(IPC)+RTSP地址获取_第3张图片

该工具的代码下载地址:

Github:https://github.com/QuickGBLink88/OnvifDiscoveryTool

 

 

 

你可能感兴趣的:(安防,开源,Onvif设备发现)