【问题标题】:how to discovery Onvif device with python如何使用 python 发现 Onvif 设备
【发布时间】:2019-11-19 01:45:41
【问题描述】:

在我的项目中,我需要找到一个使用 onvif 的摄像头设备。 我通过multicast-socket得到了想要的结果,但并不像预期的那样。

这是我的代码:

my_ip = "192.168.1.88"
mul_ip = "239.255.255.250"
mul_port = 37020
xml_str = '<?xml version="1.0" encoding="utf-8"?><Envelope xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns="http://www.w3.org/2003/05/soap-envelope"><Header><wsa:MessageID xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">uuid:05ebeac7-ab22-4f3c-ac10-71a6bed6788b</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>tds:Device</Types><Scopes /></Probe></Body></Envelope><?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:6604dcab-ae78-4b39-86af-71a3c71884a6</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>'

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
s.bind((my_ip, mul_port))
s.setsockopt(
    socket.IPPROTO_IP,
    socket.IP_ADD_MEMBERSHIP,
    socket.inet_aton(mul_ip) + socket.inet_aton(my_ip)
)

s.setblocking(False)

s.sendto(xml_str.encode(), (mul_ip, mul_port))
while True:
    try:
        data, address = s.recvfrom(65535)
        print('address: ', address)
        print('data: ', data)
    except Exception as e:
        pass

这个结果返回原始的xml_str 输入和我自己的IP/PORT(my_ipmul_port)。


我想了解两个问题:

  1. 这个 python 多播套接字有什么问题吗?
  2. 还有其他获取 onvif 设备的方法吗?我使用了 python-ws-discovery (https://github.com/andreikop/python-ws-discovery),但它不起作用 在 Windows10 操作系统上。

【问题讨论】:

  • 端口是3702,不是37020
  • @OttavioCampana,是的,我改变了我的代码。我明白了。 :)

标签: python-3.x onvif


【解决方案1】:

我无法回答第一个问题,因为我对多插槽不太熟悉, 但我可以帮忙做第二个。

我用来在我的网络中发现 ONVIF 设备的代码(在 Windows 10 和 macOS 上) 如下:

from wsdiscovery.discovery import ThreadedWSDiscovery as WSDiscovery
from wsdiscovery import Scope
import re

def display(any_list):
    for item in any_list:
        print(item)

def fetch_devices():
    wsd = WSDiscovery()
    scope1 = Scope("onvif://www.onvif.org/Profile")
    wsd.start()
    services = wsd.searchServices(scopes=[scope1])
    ipaddresses = []
    for service in services:
    #filter those devices that dont have ONVIF service
        ipaddress = re.search('(\d+|\.)+', str(service.getXAddrs()[0])).group(0)
        ipaddresses.append(ipaddress)
        print(display(service.getScopes()))
        print('----------END')

    print(f'\nnumber of devices detected: {len(services)}')
    wsd.stop()
    return ipaddresses

if __name__ == "__main__":
    onvif_devices_IPs = fetch_devices()
    display(onvif_devices_IPs)

我正在使用scope1 = Scope("onvif://www.onvif.org/Profile") 行来过滤和显示那些带有配置文件的设备。

【讨论】:

    猜你喜欢
    • 2012-11-05
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    相关资源
    最近更新 更多