zoukankan      html  css  js  c++  java
  • 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。

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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在接收到该调用后会返回如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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的协议封一个包

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    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");
    示例代码:

    [java] view plaincopy在CODE上查看代码片派生到我的代码片
     
      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(" ", "");  
      14.     } catch (Exception e) {  
      15.         e.printStackTrace();  
      16.         return "";  
      17.     }  
      18. }  
      19.   
      20. public String getNonce() {  
      21.     String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";  
      22.     Random random = new Random();  
      23.     StringBuffer sb = new StringBuffer();  
      24.     for (int i = 0; i < 24; i++) {  
      25.         int number = random.nextInt(base.length());  
      26.         sb.append(base.charAt(number));  
      27.     }  
      28.     return sb.toString();  
      29. }  
      30.   
      31. private void createAuthString() {  
      32.     SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",  
      33.             Locale.CHINA);  
      34.     mCreated = df.format(new Date());  
      35.     mNonce = getNonce();  
      36.     mAuthPwd = getPasswordEncode(mNonce, mCamera.password, mCreated);  
      37. }  


        http://blog.csdn.net/yanjiee/article/details/18809107
  • 相关阅读:
    阻止元素默认行为
    微信小程序--页面的生命周期和参数传递
    微信小程序-查询快递
    小程序-冒泡事件
    SpringMVC-使用、运行流程、配置文件寻找
    OpenCV-安装使用、图像处理
    Spring-AOP:JoinPoint、各种通知、基于XML和注解的AOP、声明式事务
    Spring-AOP:开发准备、初识动态代理、使用步骤、
    Spring-IOC:Bean的作用域、生命周期、XML的装配、注解注入、@Autowired
    Spring-IOC:复杂值注入、各种类型赋值、bean的复用
  • 原文地址:https://www.cnblogs.com/tianciliangen/p/3988462.html
Copyright © 2011-2022 走看看