使用Python基于Onvif协议从摄像头获取RTSP播放地址

Published: 2020-05-31

Tags: Python Onvif

本文总阅读量

五月份用 Java 写了一个月的业务代码... 都没时间学点儿技术了。

用上个月整理的笔记打破一下本月0篇博文的事实,印象较深的是,基于 Onvif 协议取 RTSP 播放地址,当时以为引个包就完成了,然而官网示例没找到相关代码,翻了半天的 WSDL 文档才有眉目,因为暂时项目没有用到也没有深入研究,希望有时间能进一步的测试,不过还是小有收获,以前没听过 Onvif,WSDL,SOAP,现在能够顺利拼写了~ 😀

环境

Ubuntu 18.04

安装依赖

1)Valkka

视频监控提供管理与视频展示及分发的解决方案,此处用来获取IP摄像头信息。

$ sudo apt-add-repository ppa:sampsa-riikonen/valkka
$ sudo apt-get update
$ sudo apt-get install valkka

2)lxml

$ sudo pip3 install lxml

PS:如果下载包速度缓慢,可以在命令后指定源地址如:

sudo pip3 install lxml -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com

3)zeep

基于 SOAP 协议的客户端。

$ sudo pip3 install zeep

示例代码

海康 IPC

# -*- coding: utf-8 -*-

from valkka.onvif import OnVif, getWSDLPath, Media
import zeep

def zeep_pythonvalue(self, xmlvalue):
        return xmlvalue

zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue

# 海康
media_service = Media(
    ip          = "192.168.42.128",
    port        = 80,
    user        = "admin",
    password    = "admin"
)

print(media_service.ws_client.GetProfiles())


print(media_service.ws_client.GetProfile("Profile_1"))

print(media_service.ws_client.GetStreamUri({'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'RTSP'}}, "Profile_1"))

大华 IPC

# -*- coding: utf-8 -*-

from valkka.onvif import OnVif, getWSDLPath, Media

import zeep

def zeep_pythonvalue(self, xmlvalue):
        return xmlvalue

zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue

# 大华
media_service = Media(
    ip          = "192.168.42.134",
    port        = 80,
    user        = "admin",
    password    = "admin"
)

print(media_service.ws_client.GetProfiles())

print(media_service.ws_client.GetProfile("MediaProfile000"))

print(media_service.ws_client.GetStreamUri({'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'RTSP'}}, "MediaProfile000"))

取到的RTSP流格式

# 海康
rtsp://192.168.42.134:554/cam/realmonitor?channel=1&subtype=0&unicast=true&proto=Onvif

# 大华
rtsp://192.168.42.128:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1

如果不使用 Onvif,海康 RTSP 预览地址规则如下

# 海康rtsp地址(主码流)
rtsp://admin:admin@192.168.42.128:554/h264/ch1/main/av_stream
rtsp://admin:admin@192.168.42.128:554/mpeg-4/ch1/main/av_stream

# 海康rtsp地址(子码流)
rtsp://admin:admin@192.168.42.128/h264/ch1/sub/av_stream
rtsp://admin:admin@192.168.42.128/h264/mpeg-4/sub/av_stream

补充

以下代码片段是从SF找到的代码片段,不加会报错

def zeep_pythonvalue(self, xmlvalue):
        return xmlvalue

zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue

错误信息

Traceback (most recent call last):
  File "hik.py", line 19, in <module>
    print(media_service.ws_client.GetProfiles())

   ... 省略 ...

    init_kwargs[name] = attribute.parse(value)
  File "/usr/local/lib/python3.6/dist-packages/zeep/xsd/elements/attribute.py", line 22, in parse
    return self.type.pythonvalue(value)
  File "/usr/local/lib/python3.6/dist-packages/zeep/xsd/types/simple.py", line 77, in pythonvalue
    "%s.pytonvalue() not implemented" % self.__class__.__name__
NotImplementedError: AnySimpleType.pytonvalue() not implemented

参考

  1. Valkka 文档
  2. wsdl - https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl
  3. wsdl - https://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl
  4. wsdl - https://www.onvif.org/ver10/media/wsdl/media.wsdl
  5. Onvif 文档