Onvif协议及其在Android下的实现
好久没有写博客,今天将前段时间做的Onvif协议在Android上的实现分享给大家。
首先,我们先来了解一下什么是Onvif协议:ONVIF 协议是由Open Network Video Interface Forum (开放型网络视频接口论坛)制定的开放性行业标准。这一接口标准的目的是确保不同厂商生产的网络视频产品具有互通性。
ONVIF规范中设备管理和控制部分所定义的接口均以Web Services的形式提供。ONVIF规范涵盖了完全的XML及WSDL的定义。每一个支持ONVIF规范的终端设备均须提供与功能相应的Web Service。服务端与客户端的数据交互采用SOAP协议。ONVIF中的其他部分比如音视频流则通过RTP/RTSP进行 。
如图所示就是Onvif协议要实现的内容,其中IPCAM就是指网络摄像机(IP Camera)。
接下去我们分步骤来说:
(1)发现ipcam
客户端首先发起ws-discovery,查找所在网络段内的所有的ipcam。Ipcam在接收到ws-discovery之后可以进行响应。
在android下的实现方式
1)DatagramPacket类,UDP的方式
2)计算广播地址(192.168.1.255)
3)socket send probe
4)开启一个线程去receive
5)解析收到的probematch
(2)对IP Camera参数配置
通过soap调用web server的方法,可根据wsdl进行方法的请求封装,实现具体的方法。
Soap:简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。
Wsdl:Web Services Description Language的缩写,是一个用来描述Web服务和说明如何与Web服务通信的XML语言。为用户提供详细的接口说明书。
在android下实现方式:
1)实例化一个HttpURLConnection,并使用POST的方式
2)POST一个遵从WSDL定义的接口的包,例如GetStreamUri。
- <GetStreamUri xmlns="http://www.onvif.org/ver10/media/wsdl">
- <StreamSetup>
- <Stream xmlns="http://www.onvif.org/ver10/schema">RTP-Unicast</Stream>
- <Transport xmlns="http://www.onvif.org/ver10/schema">
- <Protocol>UDP</Protocol>
- </Transport>
- </StreamSetup>
- <ProfileToken>profile-0_0</ProfileToken>
- </GetStreamUri>
IP Camera在接收到该调用后会返回如下:
- <trt:GetStreamUriResponse>
- <trt:MediaUri>
- <tt:Uri>rtsp://192.168.0.105/live1.sdp</tt:Uri>
- <tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
- <tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
- <tt:Timeout>P1Y</tt:Timeout>
- </trt:MediaUri>
- </trt:GetStreamUriResponse>
3)接收返回值(保证返回代码是200),解析XML,获取RTSP的流地址。
(3)获取视频流
android下的实现方式
1)实例化Socket对象
2)根据RTSP的协议封一个包
- DESCRIBE
- RTSP/1.0
- CSeq:0
- Accept:application/sdp
- Authorization:Basic (admin:12345的base64编码)
3)解析RTSP流
PS:
实际上,在Android中,我们只要获得IPCAM的rtsp地址之后,有几种方法可以直接在SurfaceView上播放视频了:1.JavaCV;2.VLC;3.支持硬解码的MediaPlayer和VideoPlayer;(4)Vitamio
最后说一下第二步中SOAP的实现中,从开始设置ipcam的包中,需要在包头中加入ipcam的鉴权。官方给的公式是:
其中base64编码容易实现,nonce只是一个16位随机数即可。Sha-1在JAVA中的实现方式是:
MessageDigest md = MessageDigest.getInstance("SHA-1");
示例代码:
- public String getPasswordEncode(String nonce, String password, String date) {
- try {
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- byte[] b1 = Base64.decode(nonce.getBytes(), Base64.DEFAULT);
- byte[] b2 = date.getBytes(); // "2013-09-17T09:13:35Z";
- byte[] b3 = password.getBytes();
- byte[] b4 = new byte[b1.length + b2.length + b3.length];
- md.update(b1, 0, b1.length);
- md.update(b2, 0, b2.length);
- md.update(b3, 0, b3.length);
- b4 = md.digest();
- String result = new String(Base64.encode(b4, Base64.DEFAULT));
- return result.replace("\n", "");
- } catch (Exception e) {
- e.printStackTrace();
- return "";
- }
- }
- public String getNonce() {
- String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- Random random = new Random();
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < 24; i++) {
- int number = random.nextInt(base.length());
- sb.append(base.charAt(number));
- }
- return sb.toString();
- }
- private void createAuthString() {
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
- Locale.CHINA);
- mCreated = df.format(new Date());
- mNonce = getNonce();
- mAuthPwd = getPasswordEncode(mNonce, mCamera.password, mCreated);
- }
Onvif协议及其在Android下的实现的更多相关文章
- EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案-Onvif(一)使用Onvif协议进行设备发现以及指定设备信息探测
背景分析 众所周知,EasyNVR不拘泥.不受限于摄像机的品牌厂商及其配套平台,只要是网络监控摄像机IPC.硬盘录像机NVR.且设备支持标准的RTSP/Onvif协议,都可以接入实时视频流进入Easy ...
- android下tcpdump抓包
tcpdump是最快捷方便的抓包方式,还可以加深对网络协议的理解.android下可以通过如下方式抓包: 1 Android上启动tcpdump Android设备可以把tcpdump的可执行文件上传 ...
- ONVIF协议学习笔记
一.理解 1.1 技术理解 ONVIF = 服务端 + 客户端 =(Web Services + RTSP)+ 客户端 = ((WSDL + SOAP) + RTSP) + 客户端 WSDL是服务端用 ...
- onvif 协议
1.ONVIF 协议解读 https://www.onvif.org 一.什么是ONVIF? 1.1形成 2008年5月,由安讯士(AXIS)联合博世(BOSCH)及索尼(SONY)公司三方宣布携手共 ...
- EasyNVR RTSP摄像机转HLS直播服务器中使用Onvif协议控制预置位
EasyNVR支持预置位控制,包括转到指定预置位,设置指定预置位,删除指定预置位 预置位在安防领域有较为普遍的应用,可以进行很多既定位置的跳转,很方便 之前我们说过如何用Onvif协议进行设备的发现, ...
- android下JNI开发
android下JNI开发 what 什么是JNI JNI java native interface native本地 java本地接口 通过JNI可以实现java和本地代码之间相互调用 jni可以 ...
- 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)
在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...
- EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案中使用Onvif协议控制视频设备预置位转动
EasyNVR支持预置位控制,包括转到指定预置位,设置指定预置位,删除指定预置位.预置位在安防领域有较为普遍的应用,可以进行很多既定位置的跳转,很方便.之前我们说过如何用Onvif协议进行设备的发现, ...
- EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案-Onvif(三)使用Onvif协议进行设备PTZ云台控制
背景分析 熟悉EasyNVR产品的盆友们应该都知道,EasyNVR主要完成的是RTSP视频流到RTMP/HLS/Flv的转码,并提供了一套api和一个可视化管理平台来便于调用.同时支持ONVIF协议进 ...
随机推荐
- Django drf:幂等性
一.什么叫做幂等性 用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用.举个最简单的例子,那就是支付,用户购买商品使用约支付,支付扣款成功,但是返回结果的时候网络 ...
- 库克谈新iPhone不支持5G的理由,学习一下如何高手怎么应答
库克谈新iPhone不支持5G的理由 投递人 itwriter 发布于 2019-09-12 08:41 评论(14) 有1623人阅读 原文链接 [收藏] « » 9 月 12 日消息,苹果公司 C ...
- c多线程不加锁demo
// // Created by gxf on 2019/12/13. // #include <stdio.h> #include <stdlib.h> #include & ...
- 使用pyinstaller打包使用cx_Oracle模块的程序出现The specified module could not be found的问题
pyinstaller看起来并不会将动态链接库自动打包,所以我们需要告诉pyinstaller要打包哪些动态链接库,步骤如下(假设python文件名为 oracletest.py): 1. 使用pyi ...
- 0007SpringBoot配置不同环境内容及指定启动哪个环境
1.多profiles的形式 分别新增application-dev.properties和application-prod.properties配置文件, 其中application-dev.pro ...
- 跨域问题——学习ing
问题 跨域:我写了一个页面,在js中写了请求,这个请求的url跟我这个页面不在一个域名,那么这个请求就是跨域请求. 跨域会怎么样:没见过,可能就不让你请求呗,为了安全考虑之类的.(涉及浏览器的同源策略 ...
- Django的ManyToManyField(多对多)中的through的作用
创建一个经典的多对多关系:一本书可以有多个作者,一个作者可以有多本书(如下) 运行“python manage.py makemigratons"和"python manage.p ...
- 检测 gcc 是否支持 C99 标准的方法
一般来说 gcc 3.0 以上都是支持 C99 的 但是编译的时候得加上 -std=c99 检测 gcc 是否支持 C99 方法,新建 c99.c 文件,内容如下 #include <stdio ...
- 5、Spring Boot 2.x 启动原理解析
1.5 Spring Boot 启动原理解析 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏 ...
- SIGAI深度学习第四集 深度学习简介
讲授机器学习面临的挑战.人工特征的局限性.为什么选择神经网络.深度学习的诞生和发展.典型的网络结构.深度学习在机器视觉.语音识别.自然语言处理.推荐系统中的应用 大纲: 机器学习面临的挑战 特征工程的 ...