好久没有写博客,今天将前段时间做的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。

  1. <GetStreamUri xmlns="http://www.onvif.org/ver10/media/wsdl">
  2. <StreamSetup>
  3. <Stream xmlns="http://www.onvif.org/ver10/schema">RTP-Unicast</Stream>
  4. <Transport xmlns="http://www.onvif.org/ver10/schema">
  5. <Protocol>UDP</Protocol>
  6. </Transport>
  7. </StreamSetup>
  8. <ProfileToken>profile-0_0</ProfileToken>
  9. </GetStreamUri>

IP Camera在接收到该调用后会返回如下:

  1. <trt:GetStreamUriResponse>
  2. <trt:MediaUri>
  3. <tt:Uri>rtsp://192.168.0.105/live1.sdp</tt:Uri>
  4. <tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
  5. <tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
  6. <tt:Timeout>P1Y</tt:Timeout>
  7. </trt:MediaUri>
  8. </trt:GetStreamUriResponse>

3)接收返回值(保证返回代码是200),解析XML,获取RTSP的流地址。

(3)获取视频流


 

android下的实现方式
1)实例化Socket对象
2)根据RTSP的协议封一个包

  1. DESCRIBE
  2. RTSP/1.0
  3. CSeq:0
  4. Accept:application/sdp
  5. 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");
示例代码:

    1. public String getPasswordEncode(String nonce, String password, String date) {
    2. try {
    3. MessageDigest md = MessageDigest.getInstance("SHA-1");
    4. byte[] b1 = Base64.decode(nonce.getBytes(), Base64.DEFAULT);
    5. byte[] b2 = date.getBytes(); // "2013-09-17T09:13:35Z";
    6. byte[] b3 = password.getBytes();
    7. byte[] b4 = new byte[b1.length + b2.length + b3.length];
    8. md.update(b1, 0, b1.length);
    9. md.update(b2, 0, b2.length);
    10. md.update(b3, 0, b3.length);
    11. b4 = md.digest();
    12. String result = new String(Base64.encode(b4, Base64.DEFAULT));
    13. return result.replace("\n", "");
    14. } catch (Exception e) {
    15. e.printStackTrace();
    16. return "";
    17. }
    18. }
    19. public String getNonce() {
    20. String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    21. Random random = new Random();
    22. StringBuffer sb = new StringBuffer();
    23. for (int i = 0; i < 24; i++) {
    24. int number = random.nextInt(base.length());
    25. sb.append(base.charAt(number));
    26. }
    27. return sb.toString();
    28. }
    29. private void createAuthString() {
    30. SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",
    31. Locale.CHINA);
    32. mCreated = df.format(new Date());
    33. mNonce = getNonce();
    34. mAuthPwd = getPasswordEncode(mNonce, mCamera.password, mCreated);
    35. }  

      http://blog.csdn.net/yanjiee/article/details/18809107

Onvif协议及其在Android下的实现的更多相关文章

  1. EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案-Onvif(一)使用Onvif协议进行设备发现以及指定设备信息探测

    背景分析 众所周知,EasyNVR不拘泥.不受限于摄像机的品牌厂商及其配套平台,只要是网络监控摄像机IPC.硬盘录像机NVR.且设备支持标准的RTSP/Onvif协议,都可以接入实时视频流进入Easy ...

  2. android下tcpdump抓包

    tcpdump是最快捷方便的抓包方式,还可以加深对网络协议的理解.android下可以通过如下方式抓包: 1 Android上启动tcpdump Android设备可以把tcpdump的可执行文件上传 ...

  3. ONVIF协议学习笔记

    一.理解 1.1 技术理解 ONVIF = 服务端 + 客户端 =(Web Services + RTSP)+ 客户端 = ((WSDL + SOAP) + RTSP) + 客户端 WSDL是服务端用 ...

  4. onvif 协议

    1.ONVIF 协议解读 https://www.onvif.org 一.什么是ONVIF? 1.1形成 2008年5月,由安讯士(AXIS)联合博世(BOSCH)及索尼(SONY)公司三方宣布携手共 ...

  5. EasyNVR RTSP摄像机转HLS直播服务器中使用Onvif协议控制预置位

    EasyNVR支持预置位控制,包括转到指定预置位,设置指定预置位,删除指定预置位 预置位在安防领域有较为普遍的应用,可以进行很多既定位置的跳转,很方便 之前我们说过如何用Onvif协议进行设备的发现, ...

  6. android下JNI开发

    android下JNI开发 what 什么是JNI JNI java native interface native本地 java本地接口 通过JNI可以实现java和本地代码之间相互调用 jni可以 ...

  7. 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)

    在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...

  8. EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案中使用Onvif协议控制视频设备预置位转动

    EasyNVR支持预置位控制,包括转到指定预置位,设置指定预置位,删除指定预置位.预置位在安防领域有较为普遍的应用,可以进行很多既定位置的跳转,很方便.之前我们说过如何用Onvif协议进行设备的发现, ...

  9. EasyNVR网页摄像机无插件H5、谷歌Chrome直播方案-Onvif(三)使用Onvif协议进行设备PTZ云台控制

    背景分析 熟悉EasyNVR产品的盆友们应该都知道,EasyNVR主要完成的是RTSP视频流到RTMP/HLS/Flv的转码,并提供了一套api和一个可视化管理平台来便于调用.同时支持ONVIF协议进 ...

随机推荐

  1. Go语言——值方法 & 指针方法

    1 package main import ( "fmt" "sort" ) type SortableStrings []string type Sortab ...

  2. toolbox 中创建nginx服务器,使用localhost不能访问

    使用toolbox 工具使用docker创建nginx 容器,使用localhost不能访问? 使用docker run --rm -d --name dweb  -p 80:80 nginx 命令执 ...

  3. 解决python中调用 imread 报错:ImportError: cannot import name imread

    安装了scipy后,报cannot import name imread错误, 1.网上查阅资料后说是需要安装pillow,安装pillow之后,仍然报该错误, 2.网上说是pillow与SciPy安 ...

  4. 【二进制优化-多重背包】zznu-oj-2120 : 安详--如何用尽钱币打赏主播获得最大好感度

    2120 : 安详 题目描述 spring最近喜欢上了B站新秀主播,身为顿顿吃黄焖鸡的土豪,当然要过去打赏一番,但是spring还是喜欢精打细算,所以在打赏的时候,想要掏出有限的钱,获得主播的最大好感 ...

  5. 遍历windows窗口

    原文 1. GetDesktopWindow GetNextWindow HWND hAll = ::GetDesktopWindow(); HWND hCurrent = ::GetNextWind ...

  6. java 下拉控件 转自 http://www.cnblogs.com/lhb25/p/form-enhanced-with-javascript-three.html

    表单元素让人爱恨交加.作为网页最重要的组成部分,表单几乎无处不在,从简单的邮件订阅.登陆注册到复杂的需要多页填写的信息提交功能,表单都让开发者花费了大量的时间和精力去处理,以期实现好用又漂亮的表单功能 ...

  7. UCOSIII(二)

    #include "sys.h" #include "delay.h" #include "usart.h" #include " ...

  8. [POI2008]BLO-Blockade 割点

    [POI2008]BLO-Blockade 割点 题面 容易想到用\(\text{Tarjan}\)求割点.对于非割点,会损失\(2\times(n-1)\)次访问(注意是互相访问,所以要乘2):对于 ...

  9. 顺序表应用7:最大子段和之分治递归法(SDUT 3664)

    #include <bits/stdc++.h> using namespace std; const int maxn = 50005; int num = 0; struct node ...

  10. 1635:【例 5】Strange Way to Express Integers

    #include<bits/stdc++.h> #define ll long long using namespace std; ll n,m,a,lcm,now; bool flag; ...