精华内容
下载资源
问答
  • 《通过onvif协议接入海康、大华NVR步骤》由会员分享,可在线阅读,更多相关《通过onvif协议接入海康、大华NVR步骤(4页珍藏版)》请在人人文库网上搜索。1、通过onvif协议接入海康、大华NVR步骤注意:1. 把摄像机跟...

    《通过onvif协议接入海康、大华NVR步骤》由会员分享,可在线阅读,更多相关《通过onvif协议接入海康、大华NVR步骤(4页珍藏版)》请在人人文库网上搜索。

    1、通过onvif协议接入海康、大华NVR步骤注意:1. 把摄像机跟路由器相连接,使得相机和NVR连接在同一个路由器上;2. 局域网内相机和NVR必须被配置在同一网段上;比如NVR的内网IP为192.168.1.X,则相机的IP则为192.168.1.Y;3. 摄像机固件必须带后缀为: -ONVIF版本。4. 固件升级地址:(一)对接海康NVR一、 NVR开机后进入通道管理界面(如下图所示):1选择通道号以后,在IP通道地址栏输入相机的IP地址,在协议栏下选择ONVIF协议,管理端口栏填写2000。1 / 42点击添加,点击添加后可以在如下图所示的设备列表看到添加设备的信息及连接状态,若状态栏显示。

    2、已连接上,点击预览即可预览播放视频;若未连接点击编辑查看上述参数是否正确;(二)对接大华NVR1、NVR开机后进入远程设备界面,点击搜索(如下图所示):2、点解搜索后即可显示局域网内已连接上的可支持ONVIF协议的网络摄像机,如图注意:如若搜索不到网络摄像机,请检查:1. 网络摄像机是否正确接入局域网;2. 网络摄像机是否已分配正确的内网IP;3. NVR是否正确接入局域网;4. NVR是否已分配正确的内网IP;3在搜索出来的设备中,勾选需要添加的设备,点击添加杰克完成对接。注意:搜索出来的设备端口需要2000,如若不是请修改。-温馨提示:如不慎侵犯了您的权益,可联系文库删除处理,感谢您的关注。

    展开全文
  • 在我们弱电行业网VIP技术2群中也讨论到一个问题,关于大华的录像机添加海康摄像头为什么总是不成功,很多情况下,我们直接的解决方法,是直接使用onvif协议就可以解决,但是并不然,很多朋友在大华的录像机添加海康...

    理大华的录像机添加海康摄像头在监控项目中经常会遇到,有很多的项目我们使用并不是同一个厂家的设备。

    在我们弱电行业网VIP技术2群中也讨论到一个问题,关于大华的录像机添加海康摄像头为什么总是不成功,很多情况下,我们直接的解决方法,是直接使用onvif协议就可以解决,但是并不然,很多朋友在大华的录像机添加海康摄像头,使用了onvif协议也是不能解决的。

    这个问题不断的有朋友遇到,之前我们也曾讨论过,本期我们再来详细了解下。

    c81e986ad60d2cb02157b5752bc701d4.png

    那是什么原因,我们一起来看下。

    一、原因与解决的办法

    大华的录像机添加海康摄像头,设置了onvif协议,也无法解决?

    1、分析

    首先来分析这个问题,海康的摄像头添加到大华的录像机里,使用了onvif协议也不成功,我们一般的设置是这样的。

    d1c32dc82bf121c68c5936cefac4fdf2.png

    设置了onvif协议并没有解决问题,分析这个问题,可能的原因:

    1、摄像机ip地址没有与录像机在同一个网段。

    2、端口没有设置正确,

    3、密码没有设置正确。

    4、摄像头出厂没有开启onvif协议。

    于是就针对这些问题进行逐一排查。

    6240261eeabdfd0ef573819853b64cbd.png

    排查过后,这些可能的原因都排查了一遍,但问题摄像头还是添加不进去。

    69b5cf4524ff1a81b0e0e99de95429cb.png

    2、问题解决

    上面都进行检测了,为什么还没有解决呢?原因是没有给海康的摄像头添加一个用户,给序权限其它设备取流,于是就,海康摄像头添加用户,再确认启用onvif协议。

    网络→高级配置→集成协议

    3266f7c85f9ee5a0728de3bcc64d4d86.png

    添加用户,密码最好与录像机的密码一样,方便直接添加。

    29b5ece341b797e3e8f78b78bef08f76.png

    再确认启用onvif协议。

    95a5edcc8849bc6b85bce22fa4b05414.png

    然后摄像头断电重启。

    08cd9a70ea7fe4039baeb9dd89d9755f.png

    问题解决,在使用海康的摄像头混搭时需要注意下,越是小问题越不容易被发现,我们在排除故障时,经常会用大的方向来首先排障,往往故障就发生在容易忽略的小问题。

    展开全文
  • onvif协议

    千次阅读 2019-04-28 17:46:05
    onvif协议是视频监控领域共同制订的一套标准,以探测同一局域网内摄像头信息。 onvif开源代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h>...

    onvif协议是视频监控领域共同制订的一套标准,以探测同一局域网内摄像头信息。

    onvif开源代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h> 
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <unistd.h> 
    
    /* 发送探测消息(Probe)的目标地址、端口号 */ 
    #define CAST_ADDR  "239.255.255.250"  // 多播地址,固定的239.255.255.250 
    #define CAST_PORT  3702               // 端口号
     
    const char *probe = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:dn=\"http://www.onvif.org/ver10/network/wsdl\" xmlns=\"http://www.w3.org/2003/05/soap-envelope\"><Header><wsa:MessageID xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">uuid:fc0bad56-5f5a-47f3-8ae2-c94a4e907d70</wsa:MessageID><wsa:To xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">urn:schemas-xmlsoap-org:ws:2005:04:discovery</wsa:To><wsa:Action xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</wsa:Action></Header><Body><Probe xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://schemas.xmlsoap.org/ws/2005/04/discovery\"><Types>dn:NetworkVideoTransmitter</Types><Scopes /></Probe></Body></Envelope>"; 
     
    int main(int argc, char **argv) 
    { 
        int ret;
    	int optval; 
    	int s; 
    	int len; 
    	char recv_buff[4096] = {0}; 
    	struct sockaddr_in multi_addr;
    	struct sockaddr_in client_addr;
    	
    	s = socket(AF_INET, SOCK_DGRAM, 0); // 建立数据报套接字
    	if (s < 0) 
    	{ 
    		perror("socket error");
    		return -1; 
    	} 
    		
    	multi_addr.sin_family = AF_INET; // 搜索IPC:使用UDP向指定地址发送探测消息(Probe) 
    	multi_addr.sin_port = htons(CAST_PORT); 
    	multi_addr.sin_addr.s_addr = inet_addr(CAST_ADDR); 
    	ret = sendto(s, probe, strlen(probe), 0, (struct sockaddr*)&multi_addr, sizeof(multi_addr)); 
    	if (ret < 0) 
    	{ 
    		perror("sendto error");
    		return -1; 
    	} 
    	
    	printf("Send Probe message to [%s:%d]\n\n", CAST_ADDR, CAST_PORT); 
    	
    	SLEEP(1);
    
    	for (;;) 
    	{ 
    		// 接收IPC的应答消息(ProbeMatch)
    		len = sizeof(client_addr); 
    		memset(recv_buff, 0, sizeof(recv_buff)); 
    		memset(&client_addr, 0, sizeof(struct sockaddr)); 
    		ret = recvfrom(s, recv_buff, sizeof(recv_buff) - 1, 0, (struct sockaddr*)&client_addr, &len); 
    		printf("===Recv ProbeMatch from [%s:%d]===\n%s\n\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recv_buff); 
    		SLEEP(1); 
    		
    	}
    		
    	return 0;
    }
    

    1、ue设备发送组播、目的端口为3702的udp发现报文,udp报文数据部分为xml格式

    2、支持onvif协议的摄像头收到该报文后,会回复ProbeMatch报文

    onvif测试工具:

    xml格式是通过采用onvif测试工具(ONVIF测试工具(ONVIF Device Test Tool)_146@971597.exx)抓取的,在pc上安装该工具后,pc会自动发送onvif发现报文,和pc在同一局域网内的摄像头均回复该报文,onvif测试工具则可以获取所有摄像头相关信息。

    onvif协议报文:

    发现报文:

    应答报文:

     

    参考文档:

    https://blog.csdn.net/benkaoya/article/details/72476120
    https://www.cnblogs.com/attilax/p/6181545.html

    https://blog.csdn.net/foreverhot1019/article/details/83301513
    ONVIF协议网络摄像机(IPC)客户端程序开发(2):第一次使用IPC摄像头
    https://blog.csdn.net/benkaoya/article/details/72426853

    展开全文
  • onvif 协议

    2017-05-09 01:59:00
    1、ONVIF 协议解读 https://www.onvif.org 一、什么是ONVIF? 1.1形成 2008年5月,由安讯士(AXIS)联合博世(BOSCH)及索尼(SONY)公司三方宣布携手共同成立一个国际开放型网络视频产品标准网络接口开发...

    1、ONVIF 协议解读

     

    https://www.onvif.org

     

     

    一、什么是ONVIF?

    1.1形成

    2008年5月,由安讯士(AXIS)联合博世(BOSCH)及索尼(SONY)公司三方宣布携手共同成立一个国际开放型网络视频产品标准网络接口开发论坛,取名为ONVIF(Open Network Video Interface Forum,开放型网络视频接口论坛),并以公开、开放的原则共同制定开放性行业标准。ONVIF标准将为网络视频设备之间的信息交换定义通用协议,包括装置搜寻、实时视频、音频、元数据和控制信息等。截止到2011年3月,已有279个公司加入ONVIF成为会员。

    2008年11月,论坛正式发布了ONVIF第一版规范。

    2010年11月,论坛发布了ONVIF第二版规范。规范涉及设备发现、实时音视频、摄像头PTZ控制、录像控制、视频分析等方面。

    1.2规范作用

    ONVIF规范描述了网络视频的模型、接口、数据类型以及数据交互的模式。并复用了一些现有的标准,如WS系列标准等。ONVIF规范的目标是实现一个网络视频框架协议,使不同厂商所生产的网络视频产品(包括摄录前端、录像设备等)完全互通。

    ONVIF规范中设备管理和控制部分所定义的接口均以Web Services的形式提供,设备作为服务提供者为服务端。ONVIF规范涵盖了完全的XMLWSDL的定义。每一个支持ONVIF规范的终端设备均须提供与功能相应的Web Service。服务端与客户端的数据交互采用SOAP协议。ONVIF中的其他部分比如音视频流则通过RTP/RTSP进行 。

    1.3规范优势

    协同性:不同厂商所提供的产品,均可以通过一个统一的“语言”来进行交流。方便了系统的集成。

    灵活性:终端用户和集成用户不需要被某些设备的固有解决方案所束缚。大大降低了开发成本。

    质量保证:不断扩展的规范将由市场来导向,遵循规范的同时也满足主流的用户需求。

    由于采用WSDL+XML模式,使ONVIF规范的后续扩展不会遇到太多的麻烦。XML极强的扩展性与SOAP协议开发的便捷性将吸引更多的人来关注和使用ONVIF规范。

    ONVIF组织日益扩大,与同领域的PSIA,HDCCTV相比,占据了绝对的人员优势。会员企业不乏国内外著名的设备制造商与集成商。一套规范、协议的生命周期,与市场占有率是息息相关的。而ONVIF规范的发展则正是由市场来导向,由用户来充实的。每一个成员企业都拥有加强、扩充ONVIF规范的权利。ONVIF规范所涵盖的领域将不断增大。目前门禁系统的相关内容也即将被纳入ONVIF规范之中。在安防、监控系统急速发展的今天,效率和质量的领先所带来的价值不言而喻。ONVIF协议提供了这样的潜质。

    二、ONVIF规范的实现机制

    2.1 Web Service

    Web Service是基于网络的、分布式的模块化组件,执行特定的任务。Web Service 主要利用HTTP 和SOAP 协议使数据在Web 上传输。Web 用户能够使用 SOAP 和 HTTP通过 Web 调用的方法来调用远程对象。 

     

           Web Service是基于XML和HTTPS的一种服务,其通信协议主要基于SOAP。服务端、客户端以传递符合XML的SOAP消息实现服务的请求与回应。

     

    客户端根据 WSDL 描述文档,会生成一个 SOAP 请求消息,该请求会被嵌入在一个HTTP POST请求中,发送到 Web Services 所在的Web 服务器。Web Services 请求处理器解析收到的SOAP 请求,调用相应的 Web Services。然后再生成相应的 SOAP 应答。Web 服务器得到SOAP 应答后,会再通过 HTTP应答的方式把信息送回到客户端。

     

    2.2 WSDL

    WSDL是Web services 描述语言(Web Service Description Language)的缩写。是一个用来描述Web服务和说明如何与Web服务通信的XML语言,为用户提供详细的接口说明书。

    2.3 SOAP

    SOAP是Simple Object Access Protocol的缩写。是基于XML的一种协议。一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:

    必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息

    可选的 Header 元素,包含头部信息

    必需的 Body 元素,包含所有的调用和响应信息

    可选的 Fault 元素,提供有关在处理此消息所发生错误的信息

    在向Web Service发送的SOAP请求中,Body元素中的字段需与WSDL中数据类型的相符合。在构建SOAP的过程中,必须从WSDL文件中获取并映射这一种对应关系。然而这样一个对应过程将是充满了重复性和机械性的,为了避免不必要的人工差错以及节约开发时间,一个名为gSOAP的编译工具应运而生。

    gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。通过将WSDL文件解析序列化为C/C++文件,最小化了Web Service的开发过程。

     

    SOAP协议位置

    2.4 ONVIF规范

    ONVIF规范向视频监控引入了Web Service的概念。设备的实际功能均被抽象为了Web Service的服务,视频监控系统的控制单元以客户端的身份出现,通过Web请求的形式完成控制操作。

     

    2.4.1 Web Service能为视频监控什么?

    a)     设备的无关性,任何一个设备接入系统,不会对其他系统造成影响。

    b)     设备的独立性,每一个设备只负责对接收到的请求做出反馈,甚至不需要知晓控制端的存在。

    c)     管理的集中性,所有的控制由客户端来发起。

     

    2.4.2 ONVIF规范能为视频监控带来什么?

    a)     抽象了功能的接口。统一了对设备的配置以及操作的方式。

    b)     控制端关心的不是设备的型号,而是设备所提供的Web Service。

    c)     规范了视频系统中Web Service范围之外的行为。

    d)     ONVIF提供了各个模块的WSDL,拥有效率非常高的开发方式。

     

    3、ONVIF规范的内容

    a)        设备发现

    b)        设备管理

    c)        设备输入输出服务

    d)        图像配置

    e)        媒体配置

    f)         实时流媒体

    g)        接收端配置

    h)        显示服务

    i)          事件处理

    j)          PTZ控制

    k)        其他

    4、ONVIF的应用

    4.1 名词说明

    CMU(Center Manager Unit),即中心管理单位。

    PU(Prefocus Unit),即监控前端单元,负责在CMU的控制下使用摄像机采集视频流、使用麦克风采集音频流、使用控制口采集报警信息、对摄像机云台镜头进行控制。

    CU(Client Unit),监控系统的监控客户端单元,负责将PU采集到的视频流、音频流、报警信息提交给监控用户,并根据用户要求操作PU设备,如云台、镜头等。

    4.2 传统视频监控系统的一个局域网应用场景

    a)        PU设备上线后,向CMU注册,建立连接。

    b)        CMU与PU进行信令交互,请求能力集,获取配置。

    c)        CU上线,向CMU注册,建立连接。

    d)        CMU与CU进行信令交互,传输设备列表。

    e)        CU向PU请求码流。

     

    4.3 应用ONVIF规范后对应的场景

    a)        PU设备上线后,向CMU发送HELLO消息。

    b)        CMU需要搜寻设备时,向PU发送PROBE消息。

    c)        CMU与PU进行信令交互,请求能力集,获取配置。

    d)        CU上线,向CMU注册,建立连接。

    e)        CMU与CU进行信令交互,传输设备列表。

    f)         在CMU的协调下,CU同PU建立连接传输码流。

     

    上述场景中,ONVIF带来了什么变化?

    a)        PU与CMU的交互方式发生了改变,CMU不再与PU保持长连接。

           b)       遵循ONVIF规范,信令以及消息内容有了统一的标准。

    2

    非常重要的部分就是视频流的对接,即能够在符合onvif标准的监控客户端软件里接收到设备端NVT发来的RTSP视频流。这里,我所用的客户端软件是Onvif Device Manager v2.2。

    ONVIF Profile S Specification文档描述了Device或者说DVT和Client可以使用的一种Profile,Profile这个词在计算机领域非常常见,我们可以理解成一种方案、配置、框架等。

    文档里描述了如果实现VideoStream,device和client应该具备的条件,当然如果实现文档的所有条件,就可以说该设备符合Profile S

    如果单纯实现VideoStream,只需完成下列命令。

     

    1. 1、GetProfiles  
    2. 2、GetStreamUri   
    3. 填充rtsp路径,例如:rtsp://192.168.1.201/petrov.m4e  
    4. 3、Media Streaming using RTSP  
    5. 这里使用开源的live555,完成rtsp功能  
    6. 4、GetVideoEncoderConfiguration  
    7. 5、GetVideoEncoderConfigurationOptions  
    8. 6、GetCapabilities  
    9. NVC为了获取DVT所支持的功能的命令  

     

    参考文档:

     

    1. 1、ONVIF Profile S Specification  
    2. 描述ProfileS是什么样的一个东西,如何实现  
    3. 2、Reference_of_ONVIF_Development_v1.01.02  
    4. Onvif DVT设计参考,指明了一条道路,但没有具体内容  
    5. 3、ONVIF-Media-Service-Spec-v220  
    6. Onvif Media的说明介绍  
    7. 4、http://www.onvif.org/onvif/ver20/util/operationIndex.html  
    8. onvif几乎全部命令的详细说明,非常重要。该文档告诉我们结构体成员的意义和如何填充。Onvif开发其实就是各种结构体的填充。  

     

    一、产生onvif源码框架

    1、从wsdl生成C头文件

     

    1. wsdl2h -o onvif.h -c -s -t .\typemap.dat http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl http://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl http://www.onvif.org/onvif/ver10/display.wsdl http://www.onvif.org/onvif/ver10/deviceio.wsdl http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl  http://www.onvif.org/onvif/ver10/receiver.wsdl http://www.onvif.org/onvif/ver10/recording.wsdl  http://www.onvif.org/onvif/ver10/search.wsdl http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl http://www.onvif.org/onvif/ver10/replay.wsdl http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl http://www.onvif.org/onvif/ver10/analyticsdevice.wsdl  http://www.onvif.org/onvif/ver10/schema/onvif.xsd  http://www.onvif.org/ver10/actionengine.wsdl  

    跟前一篇discovery唯一不同的是,这里多了很多wsdl文件,这次创建完整的onvif代码框架

     

    2、从头文件生成源码框架

     

    1. soapcpp2 -c onvif.h -x -I /root/onvif/gsoap-2.8/gsoap/import -I /root/onvif/gsoap-2.8/gsoap/  

    产生的C文件比较庞大,最大的有十几兆,大部分的内容没有复用导致。

     

    二、创建soap运行环境

     

    1. int main(int argc, char **argv)    
    2. {    
    3.     int m, s;    
    4.     struct soap add_soap;    
    5.     int server_udp;  
    6.   
    7.     server_udp = create_server_socket_udp();  
    8.     //bind_server_udp1(server_udp);  
    9.     pthread_t thrHello;  
    10. 10.     pthread_t thrProbe;  
    11. 11.     //pthread_create(&thrHello,NULL,main_Hello,server_udp);  
    12. 12.     //sleep(2);  
    13. 13.     pthread_create(&thrProbe,NULL,main_Probe,server_udp);  
    14. 14.   
    15. 15.     soap_init(&add_soap);    
    16. 16.     soap_set_namespaces(&add_soap, namespaces);    
    17. 17.   
    18. 18.   
    19. 19.     if (argc < 0) {    
    20. 20.         printf("usage: %s <server_port> \n", argv[0]);    
    21. 21.         exit(1);    
    22. 22.     } else {    
    23. 23.         m = soap_bind(&add_soap, NULL, 80, 100);    
    24. 24.         if (m < 0) {    
    25. 25.             soap_print_fault(&add_soap, stderr);    
    26. 26.             exit(-1);    
    27. 27.         }    
    28. 28.         fprintf(stderr, "Socket connection successful: master socket = %d\n", m);    
    29. 29.         for (;;) {    
    30. 30.             s = soap_accept(&add_soap);    
    31. 31.             if (s < 0) {    
    32. 32.                 soap_print_fault(&add_soap, stderr);    
    33. 33.                 exit(-1);    
    34. 34.             }    
    35. 35.             fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);    
    36. 36.             soap_serve(&add_soap);    
    37. 37.             soap_end(&add_soap);    
    38. 38.         }    
    39. 39.     }    
    40. 40.     return 0;    

    41. }   

    注意,这里绑定了80端口,onvif使用的是http请求,然后附带xml,其实正常的是将onvif集成到web服务器中,普通的http请求有web服务器处理,onvif的http请求则有soap处理。我们这里的做法也可行,只不过onvif的访问web服务器的功能是无法使用的。

     

    三、RTSP视频对接

    1、实现GetCapabilities命令

    客户端发送GetCapabilities命令来得到设备端的能力,然后依据GetCapabilities返回的结果再来进行下一步操作

    在__tds__GetCapabilities函数中我们只需要填充Media部分和一些必要的即可

     

    1. //想要对接RTSP视频,必须设置Media  
    2. tds__GetCapabilitiesResponse->Capabilities->Media = (struct tt__MediaCapabilities*)soap_malloc(soap, sizeof(struct tt__MediaCapabilities));  
    3. tds__GetCapabilitiesResponse->Capabilities->Media->XAddr = (char *) soap_malloc(soap, sizeof(char) * LARGE_INFO_LENGTH);  
    4. strcpy(tds__GetCapabilitiesResponse->Capabilities->Media->XAddr, _IPv4Address);  
    5. tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities = (struct tt__RealTimeStreamingCapabilities*)soap_malloc(soap, sizeof(struct tt__RealTimeStreamingCapabilities));  
    6. tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTPMulticast = (int *)soap_malloc(soap, sizeof(int));   
    7. *tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTPMulticast = _false;     
    8. tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORETCP = (int *)soap_malloc(soap, sizeof(int));  
    9. *tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORETCP = _true;     

    10. tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORERTSP_USCORETCP = (int *)soap_malloc(soap, sizeof(int));  

    11. *tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->RTP_USCORERTSP_USCORETCP = _true;      

    12. tds__GetCapabilitiesResponse->Capabilities->Media->StreamingCapabilities->Extension = NULL;  

    13. tds__GetCapabilitiesResponse->Capabilities->Media->Extension = NULL;  

    14. tds__GetCapabilitiesResponse->Capabilities->Media->__size = 0;  

    15. tds__GetCapabilitiesResponse->Capabilities->Media->__any = 0;  

    另外必要填充的还有

     

     

    1. //下面的重要,这里只实现视频流,需要设置VideoSources  
    2. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->VideoSources = TRUE;  
    3. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->VideoOutputs = FALSE;  
    4. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->AudioSources = FALSE;  
    5. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->AudioOutputs = FALSE;  
    6. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->RelayOutputs = FALSE;  
    7. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->__size = 0;  
    8. tds__GetCapabilitiesResponse->Capabilities->Extension->DeviceIO->__any = NULL;  
    9.   

    10. tds__GetCapabilitiesResponse->Capabilities->Extension->Display = NULL;  

    11. tds__GetCapabilitiesResponse->Capabilities->Extension->Recording = NULL;  

    12. tds__GetCapabilitiesResponse->Capabilities->Extension->Search = NULL;  

    13. tds__GetCapabilitiesResponse->Capabilities->Extension->Replay = NULL;  

    14. tds__GetCapabilitiesResponse->Capabilities->Extension->Receiver = NULL;  

    15. tds__GetCapabilitiesResponse->Capabilities->Extension->AnalyticsDevice = NULL;  

    16. tds__GetCapabilitiesResponse->Capabilities->Extension->Extensions = NULL;  

    17. tds__GetCapabilitiesResponse->Capabilities->Extension->__size = 0;  

    18. tds__GetCapabilitiesResponse->Capabilities->Extension->__any = NULL;  

    2、实现GetServices命令

     

     

    1. int  __tds__GetServices(struct soap* soap, struct _tds__GetServices *tds__GetServices, struct _tds__GetServicesResponse *tds__GetServicesResponse)  
    2. {  
    3.     DBG("__tds__GetServices\n");  
    4.     /*该函数很必要*/  
    5.     char _IPAddr[INFO_LENGTH];  
    6.     int i = 0;  
    7.     sprintf(_IPAddr, "http://%03d.%03d.%03d.%03d/onvif/services", 192, 168, 1, 233);  
    8.     tds__GetServicesResponse->__sizeService = 1;  
    9.   
    10. 10.     tds__GetServicesResponse->Service = (struct tds__Service *)soap_malloc(soap, sizeof(struct tds__Service));  
    11. 11.     tds__GetServicesResponse->Service[0].XAddr = (char *)soap_malloc(soap, sizeof(char) * INFO_LENGTH);  
    12. 12.     tds__GetServicesResponse->Service[0].Namespace = (char *)soap_malloc(soap, sizeof(char) * INFO_LENGTH);  
    13. 13.     strcpy(tds__GetServicesResponse->Service[0].Namespace, "http://www.onvif.org/ver10/events/wsdl");  
    14. 14.     strcpy(tds__GetServicesResponse[0].Service->XAddr, _IPAddr);  
    15. 15.     tds__GetServicesResponse->Service[0].Capabilities = NULL;  
    16. 16.     tds__GetServicesResponse->Service[0].Version = (struct tt__OnvifVersion *)soap_malloc(soap, sizeof(struct tt__OnvifVersion));  
    17. 17.     tds__GetServicesResponse->Service[0].Version->Major = 0;  
    18. 18.     tds__GetServicesResponse->Service[0].Version->Minor = 3;  
    19. 19.     tds__GetServicesResponse->Service[0].__any = (char **)soap_malloc(soap, sizeof(char *));  
    20. 20.     tds__GetServicesResponse->Service[0].__any[0] = (char *)soap_malloc(soap, sizeof(char) * INFO_LENGTH);  
    21. 21.     strcpy(tds__GetServicesResponse->Service[0].__any[0],"why1");  
    22. 22.     tds__GetServicesResponse->Service[0].__any[1] = (char *)soap_malloc(soap,sizeof(char) * INFO_LENGTH);  
    23. 23.     strcpy(tds__GetServicesResponse->Service[0].__any[1],"why2");  
    24. 24.     tds__GetServicesResponse->Service[0].__size = NULL;  
    25. 25.     tds__GetServicesResponse->Service[0].__anyAttribute = NULL;  
    26. 26.     return SOAP_OK;  

    27. }  

    3、实现GetVideoSources命令

    1. int  __tmd__GetVideoSources(struct soap* soap, struct _trt__GetVideoSources *trt__GetVideoSources, struct _trt__GetVideoSourcesResponse *trt__GetVideoSourcesResponse)  
    2. {  
    3.     DBG("__tmd__GetVideoSources\n");  
    4.   
    5.     int size1;  
    6.     size1 = 1;  
    7.     trt__GetVideoSourcesResponse->__sizeVideoSources = size1;  
    8.     trt__GetVideoSourcesResponse->VideoSources = (struct tt__VideoSource *)soap_malloc(soap, sizeof(struct tt__VideoSource) * size1);  
    9.     trt__GetVideoSourcesResponse->VideoSources[0].Framerate = 30;  
    10. 10.     trt__GetVideoSourcesResponse->VideoSources[0].Resolution = (struct tt__VideoResolution *)soap_malloc(soap, sizeof(struct tt__VideoResolution));  
    11. 11.     trt__GetVideoSourcesResponse->VideoSources[0].Resolution->Height = 720;  
    12. 12.     trt__GetVideoSourcesResponse->VideoSources[0].Resolution->Width = 1280;  
    13. 13.     trt__GetVideoSourcesResponse->VideoSources[0].token = (char *)soap_malloc(soap, sizeof(char)*INFO_LENGTH);  
    14. 14.     strcpy(trt__GetVideoSourcesResponse->VideoSources[0].token,"GhostyuSource_token"); //注意这里需要和GetProfile中的sourcetoken相同  
    15. 15.   
    16. 16.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging =(struct tt__ImagingSettings*)soap_malloc(soap, sizeof(struct tt__ImagingSettings));  
    17. 17.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Brightness = (float*)soap_malloc(soap,sizeof(float));  
    18. 18.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Brightness[0] = 128;  
    19. 19.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->ColorSaturation = (float*)soap_malloc(soap,sizeof(float));  
    20. 20.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->ColorSaturation[0] = 128;  
    21. 21.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Contrast = (float*)soap_malloc(soap,sizeof(float));  
    22. 22.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Contrast[0] = 128;  
    23. 23.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->IrCutFilter = (int *)soap_malloc(soap,sizeof(int));  
    24. 24.     *trt__GetVideoSourcesResponse->VideoSources[0].Imaging->IrCutFilter = 0;   
    25. 25.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Sharpness = (float*)soap_malloc(soap,sizeof(float));  
    26. 26.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Sharpness[0] = 128;  
    27. 27.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->BacklightCompensation = (struct tt__BacklightCompensation*)soap_malloc(soap, sizeof(struct tt__BacklightCompensation));  
    28. 28.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->BacklightCompensation->Mode = 0;  
    29. 29.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->BacklightCompensation->Level = 20;  
    30. 30.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Exposure = NULL;  
    31. 31.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Focus = NULL;  
    32. 32.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WideDynamicRange = (struct tt__WideDynamicRange*)soap_malloc(soap, sizeof(struct tt__WideDynamicRange));  
    33. 33.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WideDynamicRange->Mode = 0;     
    34. 34.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WideDynamicRange->Level = 20;  
    35. 35.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WhiteBalance = (struct tt__WhiteBalance*)soap_malloc(soap, sizeof(struct tt__WhiteBalance));  
    36. 36.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WhiteBalance->Mode = 0;   
    37. 37.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WhiteBalance->CrGain = 0;   
    38. 38.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->WhiteBalance->CbGain = 0;   
    39. 39.     trt__GetVideoSourcesResponse->VideoSources[0].Imaging->Extension = NULL;  
    40. 40.     trt__GetVideoSourcesResponse->VideoSources[0].Extension = NULL;    
    41. 41.     return SOAP_OK;  

    42. }  

    __tmd__GetVideoSources最重要的是token的填充,必须要和下面profile中的sourcetoken相同,需要匹配到这个视频源

     

    4、实现GetProfiles命令

     

    1. size = 1;  
    2. trt__GetProfilesResponse->Profiles =(struct tt__Profile *)soap_malloc(soap, sizeof(struct tt__Profile) * size);  
    3. trt__GetProfilesResponse->__sizeProfiles = size;  
    4.   
    5. i=0;  
    6. trt__GetProfilesResponse->Profiles[i].Name = (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    7. strcpy(trt__GetProfilesResponse->Profiles[i].Name,"my_profile");  
    8. trt__GetProfilesResponse->Profiles[i].token= (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    9. strcpy(trt__GetProfilesResponse->Profiles[i].token,"token_profile");  

    10. trt__GetProfilesResponse->Profiles[i].fixed = _false;  

    11. trt__GetProfilesResponse->Profiles[i].__anyAttribute = NULL;  

    除了上面的基本信息,还需要填充两大项:VideoSourceConfiguration和VideoEncoderConfiguration,一个用于描述视频源的信息,另外一个描述视频的编码信息

     

    先给VideoSourceConfiguration分配空间

    1. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration = (struct tt__VideoSourceConfiguration *)soap_malloc(soap,sizeof(struct tt__VideoSourceConfiguration ));  
    2. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Name = (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    3. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->token = (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    4. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->SourceToken = (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    5. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds = (struct tt__IntRectangle *)soap_malloc(soap,sizeof(struct tt__IntRectangle));  

    然后在填充它

     

     

    1. /*注意SourceToken*/  
    2. strcpy(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Name,"VS_Name");  
    3. strcpy(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->token,"VS_Token");  
    4. strcpy(trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->SourceToken,"GhostyuSource_token"); /*必须与__tmd__GetVideoSources中的token相同*/  
    5. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->UseCount = 1;  
    6. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->x = 1;  
    7. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->y = 1;  
    8. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->height = 720;  
    9. trt__GetProfilesResponse->Profiles[i].VideoSourceConfiguration->Bounds->width = 1280;  

    如果是指针必须先用soap_malloc分配内存,然后才能赋值

     

    下面是VideoEncoderConfiguration

     

    1. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration = (struct tt__VideoEncoderConfiguration *)soap_malloc(soap,sizeof(struct tt__VideoEncoderConfiguration));  
    2. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Name = (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    3. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->token= (char *)soap_malloc(soap,sizeof(char)*MAX_PROF_TOKEN);  
    4. strcpy(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Name,"VE_Name1");  
    5. strcpy(trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->token,"VE_token1");  
    6. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->UseCount = 1;  
    7. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Quality = 10;  
    8. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Encoding = 1;//JPEG = 0, MPEG4 = 1, H264 = 2;  
    9. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Resolution = (struct tt__VideoResolution *)soap_malloc(soap, sizeof(struct tt__VideoResolution));  

    10. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Resolution->Height = 720;  

    11. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->Resolution->Width = 1280;  

    12. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->RateControl = (struct tt__VideoRateControl *)soap_malloc(soap, sizeof(struct tt__VideoRateControl));  

    13. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->RateControl->FrameRateLimit = 30;  

    14. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->RateControl->EncodingInterval = 1;  

    15. trt__GetProfilesResponse->Profiles[i].VideoEncoderConfiguration->RateControl->BitrateLimit = 500;  

    5、GetVideoSourceConfiguration和GetVideoEncoderConfiguration

     

    1. int  __trt__GetVideoSourceConfiguration(struct soap* soap, struct _trt__GetVideoSourceConfiguration *trt__GetVideoSourceConfiguration, struct _trt__GetVideoSourceConfigurationResponse *trt__GetVideoSourceConfigurationResponse)  
    2. {  
    3.     DBG("__trt__GetVideoSourceConfiguration\n");  
    4.     //该函数必要,live video需要  
    5.     return SOAP_OK;  
    6. }  
    7.   
    8. int  __trt__GetVideoEncoderConfiguration(struct soap* soap, struct _trt__GetVideoEncoderConfiguration *trt__GetVideoEncoderConfiguration, struct _trt__GetVideoEncoderConfigurationResponse *trt__GetVideoEncoderConfigurationResponse)  
    9. {  
    10. 10.     DBG("__trt__GetVideoEncoderConfiguration\n");  
    11. 11.     return SOAP_OK;  

    12. }  

     

    6、GetVideoEncoderConfigurationOptions

     

     

    1. int  __trt__GetVideoEncoderConfigurationOptions(struct soap* soap, struct _trt__GetVideoEncoderConfigurationOptions *trt__GetVideoEncoderConfigurationOptions, struct _trt__GetVideoEncoderConfigurationOptionsResponse *trt__GetVideoEncoderConfigurationOptionsResponse)  
    2. {  
    3.     DBG("__trt__GetVideoEncoderConfigurationOptions\n");  
    4.     //该函数必要,video streaming需要  
    5.     return SOAP_OK;  
    6. }  

    以上5、6不分的代码直接返回SOAP_OK即可,正常来说是应该填充的,这里不影响RTSP Video Stream,暂时就不去动它

     

    四、运行live555MediaServer服务器

     

    live555官网有很多测试文件,我这里用的是MPEG4的测试文件路劲为rtsp://192.168.1.201/petrov.m4e

    五、启动Onvif Device Manager测试

    有一个问题,OnvifDeviceManager的并不能自动发现设备(OnvifTestTool可以),还好它提供了手动添加功能

    单击add,添加如下内容:http://192.168.1.233/onvif/device_service

    注意,我在程序中固定了两个IP:linux192.168.1.233,windows:192.168.1.201,这里需看情况修改

    测试截图:

    1、Live video

     

    2、Video streaming

     

    3、Profiles

     

    最后是运行的live555 rtsp服务器

     

    终端打印的DEBUG信息

     

    源代码下载地址:http://download.csdn.Net/detail/ghostyu/4796093

    onvif规范的实现:成功实现ONVIF协议RTSP-Video-Stream与OnvifDeviceManager的视频对接   http://blog.csdn.net/ghostyu/article/details/8208428

     

     

     

     

     

     

    转载于:https://www.cnblogs.com/endv/p/6828718.html

    展开全文
  • onvif协议 onvif IP设备摄像机的简单管理。 onvif是用于管理onvif IP设备的ONVIF协议的实现。 该库的目的是方便,轻松地管理IP摄像机和其他支持ONVIF标准的设备。 安装 要安装该库,请使用go get : go get github ...
  • ONVIF协议解读

    2019-03-25 13:45:20
    ONVIF协议解读 一、什么是ONVIF? 1.1形成 2008年5月,由安讯士(AXIS)联合博世(BOSCH)及索尼(SONY)公司三方宣布携手共同成立一个国际开放型网络视频产品标准网络接口开发论坛,取名为ONVIF(Open Network...
  • 1、onvif开发流程 发现设备 ==》 获取能力 ==》 获取媒体信息 ==》 ...如,客户端向网段内的组播地址为239.255.255.250,端口为3702发送广播消息,等待网内Onvif协议设备响应。 响应消息的设备会返回自己的IP、UUI...
  • Onvif协议快速入门

    千次阅读 2020-11-19 17:08:32
    ONVIF网络视频协议的出现,解决了不同厂商之间开发的各类设备不能融合使用的难题,提供了统一的网络视频开发标准,即最终能够通过ONVIF这个标准化的平台实现不同产品之间的集成。 ONVIF主要为网络视频产品提供标准...
  • ONVIF协议详解

    千次阅读 2017-10-31 11:58:40
    ONVIF规范的目标是实现一个网络视频框架协议,使不同厂商所生产的网络视频完全互通。 设备管理? 能力集(Capabilities)询问设备所支持的服务(支持画面设置,流媒体发送和接受,录像及回放) 网络(Network)...
  • Onvif协议学习:5、设备搜索 文章目录Onvif协议学习:5、设备搜索1、前言2、WS-Discovery原理3、单播、多播(组播)和广播的区别4、设备搜索(1)、搜索IPC(方式1)(2)、搜索IPC(方式2) 原文链接:...
  • 海康威视的全系列摄像头都支持onvif协议,但默认都是关闭状态,需要自行手动开启。 在使用迅思维的rtsp转rtmp推流器的时候,需要开启海康威视的onvif协议,这样就能在onvif设备发现里自动获取到海康威视的rtsp地址...
  • gsop工具gsop定义为一个工具,他的作用是根据xml等的配置文件生成符合onvif协议的webserver的c/c++源代码 The gSOAP toolkit is a C and C++ software development toolkit for SOAP and REST XML Web services and ...
  • ONVIF协议学习笔记

    2020-08-20 10:41:09
    ONVIF = 服务端 + 客户端 =(Web Services + RTSP)+ 客户端 = ((WSDL + SOAP) + RTSP) + 客户端 WSDL是服务端用来向客户端描述自己实现哪些请求、发送请求时需要带上哪些参数xml组织格式;SOAP是客户端向...
  • android版本的onvif基本使用介绍简单使用介绍onvif和rtsp(带实现源码)Onvif协议基本介绍rtsp的基本使用和介绍总结 简单使用介绍onvif和rtsp(带实现源码) 5G时代即将到来,万物联网都将成为现实。世面上的...
  • 若该文为原创文章,未经允许不得转载 原博主博客地址:... 目录 前言 Onvif gSOAP 编译gSOAP 步骤一:编译文件夹解压 步骤二:进入文件夹配置 步骤三:编译 步骤四:编译错误...
  • 首先,我们要了解Onvif协议,https://www.onvif.org/这里我们之探讨如何使用gsoap进行onvif客户端的开发,关于gsoap的onvif框
  • discovery,客户端向网段内的组播地址为239.255.255.250,端口为3702发送广播消息,等待网内Onvif协议设备响应响应消息的设备会返回自己的IP、UUID、EP Address、Type等,最重要的会返回设备的Device Service Ad...
  • Onvif设备搜索
  • Onvif协议-设备搜索

    千次阅读 2017-12-12 13:45:14
    导读本人通过百度查找相关资料发现,网上实现Onvif的搜索多过于复杂,同时发现没有人使用“RemoteDiscoveryBindingProxy” 这个类实现相关的搜索功能(个人查找结论)。RomoteDiscoveryBindingProxy类是通过 gsoap生成...
  • 【前言】好久没更新Onvif的这个协议内容了,最近一段时间换成其他内容的开发之后,发现Onvif这部分的知识都快忘了,因此便趁着更新博客的机会重新将Onvif协议的内容再温固一下。 Onvif获取设备能力 一、介绍 Onvif...
  • 我们接受到的大多摄像机包括海康、宇视、大华等,海康威视部分摄像机在默认情况下没有开启ONVIF协议(例如:DS-2CD2320D-I摄像机),需要进入摄像机web管理页面手动开启。 下面是将海康摄像头ONVIF配置进我们流媒体...
  • 但是在windwos服务器下必须绑定一个指定的IP地址,否则无法收到任何的组播探测包 原理 实现该函数,收到对方的探测请求,返回当前服务器Onvif协议协商的IP地址和端口 int SOAP_FMAC6 __wsdd__Probe(struct soap* ...
  • ONVIF协议网络摄像机(IPC)客户端程序开发》专栏,学ONVIF,跟我来!!!
  • onvif协议的海康摄像头读取

    千次阅读 2020-02-25 17:56:14
    import cv2 src_camera0="rtsp://admin:123456@192.168.1.2:554/Streaming/Channels/1" cap0 = cv2.VideoCapture() #cap1 = cv2.VideoCapture(src_camera1) cap2 = cv2.VideoCapture(src_camera2) ...
  • 视频监控安防平台-onvif协议demo

    千次阅读 2018-01-25 10:55:27
    视频监控安防平台-onvif协议demo  最近把onvif设备接入的demo拿出来简单整理了一下,支持的功能有onvif摄像机发现、获取和设置验证状态、获取设备通道数通过通道号获取通道类信息index从0开始、 通过通道号获取...
  • Onvif协议做安防监控的人应该都很熟悉,它广泛被用在各种安防设备中,比如IPC、DVR、NVR。在局域网中发现IPC设备很多就是基于Onvif协议实现的。本文章给大家介绍QuickGBLink开源的一个工具,该工具能够通过Onvif的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 554
精华内容 221
关键字:

onvif协议端口