ONVIF 摄像头视频流获取 - 步骤与Python例程

news2024/9/19 9:51:24

1.基本流程

  1. 加入组播udp接口,查询子网内在线的ONVIF摄像头的设备地址:
    设备地址形如:http://192.168.0.6/onvif/device_service
    这一步,参看上一篇发文:[ONVIF系列 - 01] 简介 - 设备发现 - 相关工具-CSDN博客
  2. 查询mediaService Uri地址
    mediaService地址形如:
    http://192.168.0.6/onvif/Media
  3. 查询用户的Profiles,得到一个我们需要的Profile
    Profile形如:Profile_1
  4. 发出查询Profile详情请求给ONVIF mediaServiceUri得到最终的媒体流Uri:
    形如:rtsp://192.168.0.6:554/Streaming/Channels/101?transportmode=unicast&profile=Profile_1

1.1 Python代码

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 获取当前脚本文件所在目录的父目录,并构建相对路径
import os
import sys
current_dir = os.path.dirname(os.path.abspath(__file__))
project_path = os.path.join(current_dir, '..')
sys.path.append(project_path)
sys.path.append(current_dir)

import asyncio
import aiohttp
import xml.etree.ElementTree as ET
from httpx import AsyncClient, DigestAuth
import httpx

# ONVIF 设备服务 URL
device_service_url = 'http://192.168.0.6/onvif/device_service'
username = 'xxxxx'
password = 'xxxxxxx'

async def get_device_information(session, url):
    headers = {'Content-Type': 'application/soap+xml'}
    body = """<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
                        xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
                <s:Header/>
                <s:Body>
                  <tds:GetServices>
                    <tds:IncludeCapability>false</tds:IncludeCapability>
                  </tds:GetServices>
                </s:Body>
              </s:Envelope>"""
    
    try:
        response = httpx.post(url, headers=headers, data=body, auth=DigestAuth(username, password))
        return response.text
    except Exception as e:
        print(f'An error occurred: {e}')
        return None
        
def parse_media_service_url(device_response):
    media_service_url = None
    root = ET.fromstring(device_response)
    ns = {'soap': 'http://www.w3.org/2003/05/soap-envelope', 'tds': 'http://www.onvif.org/ver10/device/wsdl'}
    services = root.find('.//tds:GetServicesResponse', namespaces=ns)
    #print(services)
    # 查找 <tds:XAddr> 元素
    for s in services:
        ns1 = s.find('.//tds:Namespace', namespaces=ns)
        if(ns1 is not None):
            print('........ns................',ns1.text)
            if('media' in ns1.text) and ('ver10' in ns1.text):
                 addr = s.find('.//tds:XAddr', namespaces = ns)
                 if(addr is not None):
                      #print('........addr................',addr)
                      media_service_url = addr.text
    return media_service_url

async def get_media_profiles(session, media_service_url):
    headers = {'Content-Type': 'application/soap+xml'}
    body = """<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:media="http://www.onvif.org/ver10/media/wsdl">
                <soapenv:Header/>
                    <soapenv:Body>
                        <media:GetProfiles/>
                    </soapenv:Body>
                </soapenv:Envelope>"""
    try:
        response = httpx.post(media_service_url, headers=headers, data=body, auth=DigestAuth(username, password))
        return response.text
    except Exception as e:
        print(f'An error occurred: {e}')
        return None
        
def parse_media_profile(profile_response):
    profile_token = None
    root = ET.fromstring(profile_response)
    ns = {'trt': 'http://www.onvif.org/ver10/media/wsdl', 'tt': 'http://www.onvif.org/ver10/schema'}
    profiles = root.find('.//trt:GetProfilesResponse', namespaces=ns)
    # 查找 <tds:XAddr> 元素
    for s in profiles:
        profile_token = s.get('token')
        print(profile_token)
        break
    return profile_token

async def get_video_stream_url(session, media_service_url, profileToken):
    headers = {'Content-Type': 'application/soap+xml'}
    body = """<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
                 xmlns:t="http://www.onvif.org/ver10/media">
        <s:Body>
            <t:GetStreamUri>
                <t:StreamSetup>
                    <t:Stream>RTP-Unicast</t:Stream>
                    <t:Transport>
                        <t:Protocol>RTSP</t:Protocol>
                    </t:Transport>
                </t:StreamSetup>
                <t:ProfileToken>YourProfileToken</t:ProfileToken>
            </t:GetStreamUri>
        </s:Body>
    </s:Envelope>"""
    
    try:
        src_sub_str = '<t:ProfileToken>YourProfileToken</t:ProfileToken>'
        real_sub_str = f'<t:ProfileToken>{profileToken}</t:ProfileToken>'
        body = body.replace(src_sub_str, real_sub_str)
        response = httpx.post(media_service_url, headers=headers, data=body, auth=DigestAuth(username, password))
        return response.text
    except Exception as e:
        print(f'An error occurred: {e}')
        return None
        
def parse_video_stream_url(media_response):
    root = ET.fromstring(media_response)
    ns = {'soap': 'http://www.w3.org/2003/05/soap-envelope', 'trt': 'http://www.onvif.org/ver10/media/wsdl','tt': 'http://www.onvif.org/ver10/schema'}
    uri = root.find('.//trt:GetStreamUriResponse//trt:MediaUri//tt:Uri', namespaces=ns) #//trt:MediaUri
    if uri is not None:
        return uri.text
    return None

async def main():
     async with httpx.AsyncClient() as session:
        device_response = await get_device_information(session, device_service_url)
        #print(device_response)
        print('>>>>>>>>>>>>>>>>>>>>>>>>>>>step1 get media soap addr')
        media_service_url = parse_media_service_url(device_response)
        print(media_service_url)
        if not media_service_url:
            print("Media service URL not found")
            return   
        profile_response = await get_media_profiles(session, media_service_url)
        #print(profile_response)
        print('>>>>>>>>>>>>>>>>>>>>>>>>>>>step2 get profile token')
        profile = parse_media_profile(profile_response)
        #print(profile)
        if not profile:
            print("Media profile not found")
            
        media_response = await get_video_stream_url(session, media_service_url, profile)
        print(media_response)
        print('>>>>>>>>>>>>>>>>>>>>>>>>>>>step3 get stream url')
        video_stream_url = parse_video_stream_url(media_response)
        print("Video Stream URL:", video_stream_url)

# 运行异步主函数
if __name__ == '__main__':
    asyncio.run(main())

1.2 代码说明

1.2.1 权限控制

soap消息如果涉及权限控制,asyncio需要借助httpx才能进行——就是ONVIF,Post Soap消息时涉及的auth=DigestAuth()。

1.2.2 soap消息

soap消息是一个xml, 我们使用ET.fromstring(device_response)来进行处理。

1.2.3 xml解析的名字空间

xml解析中一个重要的概念是ns,名字空间,如果我们需要的信息被包裹为:

<trt:GetStreamUriResponse><trt:MediaUri><tt:Uri>rtsp://192.168.0.6:554/Streaming/Channels/101?transportmode=unicast&amp;profile=Profile_1</tt:Uri>
<tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
<tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
<tt:Timeout>PT60S</tt:Timeout>
</trt:MediaUri>
</trt:GetStreamUriResponse>

注意xml元素的被冒号:分割的前导部分,比如trt,tt,这些元素在进行解析前需要预先声明:

ns = {'soap': 'http://www.w3.org/2003/05/soap-envelope', 'tds': 'http://www.onvif.org/ver10/device/wsdl'}

1.2.4 xml元素的逐级搜索

xml解析类似json,可以先拿到一个分支节点,再以分支节点为搜索起点,继续搜索,比如:

def parse_media_service_url(device_response):
    media_service_url = None
    root = ET.fromstring(device_response)
    ns = {'soap': 'http://www.w3.org/2003/05/soap-envelope', 'tds': 'http://www.onvif.org/ver10/device/wsdl'}
    services = root.find('.//tds:GetServicesResponse', namespaces=ns)
    #print(services)
    # 查找 <tds:XAddr> 元素
    for s in services:
        ns1 = s.find('.//tds:Namespace', namespaces=ns)
        if(ns1 is not None):
            print('........ns................',ns1.text)
            if('media' in ns1.text) and ('ver10' in ns1.text):
                 addr = s.find('.//tds:XAddr', namespaces = ns)
                 if(addr is not None):
                      #print('........addr................',addr)
                      media_service_url = addr.text
    return media_service_url

1.2.5  xml元素的按照路径信息一次定位

def parse_video_stream_url(media_response):
    root = ET.fromstring(media_response)
    ns = {'soap': 'http://www.w3.org/2003/05/soap-envelope', 'trt': 'http://www.onvif.org/ver10/media/wsdl','tt': 'http://www.onvif.org/ver10/schema'}
    uri = root.find('.//trt:GetStreamUriResponse//trt:MediaUri//tt:Uri', namespaces=ns) #//trt:MediaUri
    if uri is not None:
        return uri.text
    return None 

2交互过程的回应帧和特征信息

2.1查询onvif device uri得到media services uri

2.1.1 查询帧

    headers = {'Content-Type': 'application/soap+xml'}
    body = """<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
                        xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
                <s:Header/>
                <s:Body>
                  <tds:GetServices>
                    <tds:IncludeCapability>false</tds:IncludeCapability>
                  </tds:GetServices>
                </s:Body>
              </s:Envelope>"""

2.1.2 回应帧( 片段)

<tds:Service><tds:Namespace>http://www.onvif.org/ver10/media/wsdl</tds:Namespace>
<tds:XAddr>http://192.168.0.6/onvif/Media</tds:XAddr>
<tds:Version><tt:Major>2</tt:Major>
<tt:Minor>60</tt:Minor>
</tds:Version>
</tds:Service>

回应帧中可能有多个media services接口,选择版本最低的就行:

........ns................ http://www.onvif.org/ver10/device/wsdl
........ns................ http://www.onvif.org/ver10/media/wsdl
........ns................ http://www.onvif.org/ver10/events/wsdl
........ns................ http://www.onvif.org/ver20/imaging/wsdl
........ns................ http://www.onvif.org/ver10/deviceIO/wsdl
........ns................ http://www.onvif.org/ver20/analytics/wsdl
........ns................ http://www.onvif.org/ver20/media/wsdl 

2.2 查询media sevices uri Profiles得到所需Profile

2.2.1 查询帧

    headers = {'Content-Type': 'application/soap+xml'}
    body = """<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:media="http://www.onvif.org/ver10/media/wsdl">
                <soapenv:Header/>
                    <soapenv:Body>
                        <media:GetProfiles/>
                    </soapenv:Body>
                </soapenv:Envelope>"""

2.2.2 回应帧(片段)

<trt:GetProfilesResponse><trt:Profiles token="Profile_1" fixed="true"><tt:Name>mainStream</tt:Name>
<tt:VideoSourceConfiguration token="VideoSourceToken"><tt:Name>VideoSourceConfig</tt:Name>
<tt:UseCount>2</tt:UseCount>
<tt:SourceToken>VideoSource_1</tt:SourceToken>
<tt:Bounds x="0" y="0" width="1920" height="1080"></tt:Bounds>
</tt:VideoSourceConfiguration>
<tt:VideoEncoderConfiguration token="VideoEncoderToken_1"><tt:Name>VideoEncoder_1</tt:Name>
<tt:UseCount>1</tt:UseCount>
<tt:Encoding>H264</tt:Encoding>
<tt:Resolution><tt:Width>1920</tt:Width>
<tt:Height>1080</tt:Height>
</tt:Resolution>
<tt:Quality>3.000000</tt:Quality>
<tt:RateControl><tt:FrameRateLimit>10</tt:FrameRateLimit>
<tt:EncodingInterval>1</tt:EncodingInterval>
<tt:BitrateLimit>1024</tt:BitrateLimit>
</tt:RateControl>
<tt:H264><tt:GovLength>20</tt:GovLength>
<tt:H264Profile>Main</tt:H264Profile>
</tt:H264>

2.3 查询 media services uri得到流媒体uri

2.3.1 查询帧

    headers = {'Content-Type': 'application/soap+xml'}
    body = """<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
                 xmlns:t="http://www.onvif.org/ver10/media">
        <s:Body>
            <t:GetStreamUri>
                <t:StreamSetup>
                    <t:Stream>RTP-Unicast</t:Stream>
                    <t:Transport>
                        <t:Protocol>RTSP</t:Protocol>
                    </t:Transport>
                </t:StreamSetup>
                <t:ProfileToken>YourProfileToken</t:ProfileToken>
            </t:GetStreamUri>
        </s:Body>
    </s:Envelope>"""

2.3.2 回应帧(片段)

<trt:GetStreamUriResponse><trt:MediaUri><tt:Uri>rtsp://192.168.0.6:554/Streaming/Channels/101?transportmode=unicast&amp;profile=Profile_1</tt:Uri>
<tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
<tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
<tt:Timeout>PT60S</tt:Timeout>
</trt:MediaUri>
</trt:GetStreamUriResponse>

附录A 与ONVIF视频流地址获取相关的摄像头回应帧

1. MediaService Uri查询回应

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tst="http://www.onvif.org/ver10/storage/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:dn="http://www.onvif.org/ver10/network/wsdl" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12" xmlns:http="http://schemas.xmlsoap.org/wsdl/http" xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:wsadis="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2" xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:tnshik="http://www.hikvision.com/2011/event/topics" xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema" xmlns:tas="http://www.onvif.org/ver10/advancedsecurity/wsdl" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:axt="http://www.onvif.org/ver20/analytics"><env:Body><tds:GetServicesResponse><tds:Service><tds:Namespace>http://www.onvif.org/ver10/device/wsdl</tds:Namespace>
<tds:XAddr>http://192.168.0.6/onvif/device_service</tds:XAddr>
<tds:Version><tt:Major>17</tt:Major>
<tt:Minor>12</tt:Minor>
</tds:Version>
</tds:Service>
<tds:Service><tds:Namespace>http://www.onvif.org/ver10/media/wsdl</tds:Namespace>
<tds:XAddr>http://192.168.0.6/onvif/Media</tds:XAddr>
<tds:Version><tt:Major>2</tt:Major>
<tt:Minor>60</tt:Minor>
</tds:Version>
</tds:Service>
<tds:Service><tds:Namespace>http://www.onvif.org/ver10/events/wsdl</tds:Namespace>
<tds:XAddr>http://192.168.0.6/onvif/Events</tds:XAddr>
<tds:Version><tt:Major>2</tt:Major>
<tt:Minor>60</tt:Minor>
</tds:Version>
 

2.Profiles 查询回应

消息中对我们需要的部分做了标注

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tst="http://www.onvif.org/ver10/storage/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:dn="http://www.onvif.org/ver10/network/wsdl" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12" xmlns:http="http://schemas.xmlsoap.org/wsdl/http" xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:wsadis="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2" xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:tnshik="http://www.hikvision.com/2011/event/topics" xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema" xmlns:tas="http://www.onvif.org/ver10/advancedsecurity/wsdl" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:axt="http://www.onvif.org/ver20/analytics"><env:Body><trt:GetProfilesResponse><trt:Profiles token="Profile_1" fixed="true"><tt:Name>mainStream</tt:Name>
<tt:VideoSourceConfiguration token="VideoSourceToken"><tt:Name>VideoSourceConfig</tt:Name>
<tt:UseCount>2</tt:UseCount>
<tt:SourceToken>VideoSource_1</tt:SourceToken>
<tt:Bounds x="0" y="0" width="1920" height="1080"></tt:Bounds>
</tt:VideoSourceConfiguration>
<tt:VideoEncoderConfiguration token="VideoEncoderToken_1"><tt:Name>VideoEncoder_1</tt:Name>
<tt:UseCount>1</tt:UseCount>
<tt:Encoding>H264</tt:Encoding>
<tt:Resolution><tt:Width>1920</tt:Width>
<tt:Height>1080</tt:Height>
</tt:Resolution>
<tt:Quality>3.000000</tt:Quality>
<tt:RateControl><tt:FrameRateLimit>10</tt:FrameRateLimit>
<tt:EncodingInterval>1</tt:EncodingInterval>
<tt:BitrateLimit>1024</tt:BitrateLimit>
</tt:RateControl>
<tt:H264><tt:GovLength>20</tt:GovLength>
<tt:H264Profile>Main</tt:H264Profile>
</tt:H264>
<tt:Multicast><tt:Address><tt:Type>IPv4</tt:Type>
<tt:IPv4Address>0.0.0.0</tt:IPv4Address>
</tt:Address>
<tt:Port>8860</tt:Port>
<tt:TTL>128</tt:TTL>
<tt:AutoStart>false</tt:AutoStart>
</tt:Multicast>
<tt:SessionTimeout>PT5S</tt:SessionTimeout>
</tt:VideoEncoderConfiguration>
<tt:VideoAnalyticsConfiguration token="VideoAnalyticsToken"><tt:Name>VideoAnalyticsName</tt:Name>
<tt:UseCount>2</tt:UseCount>
<tt:AnalyticsEngineConfiguration><tt:AnalyticsModule Name="MyCellMotionModule" Type="tt:CellMotionEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="60"/>
<tt:ElementItem Name="Layout"><tt:CellLayout Columns="22" Rows="18"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.090909" y="0.111111"/>
</tt:Transformation>
</tt:CellLayout>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
<tt:AnalyticsModule Name="MyLineDetectorModule" Type="tt:LineDetectorEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="50"/>
<tt:ElementItem Name="Transformation"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.002000" y="0.002000"/>
</tt:Transformation>
</tt:ElementItem>
<tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="1000"/>
<tt:Point x="1000" y="1000"/>
<tt:Point x="1000" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
<tt:AnalyticsModule Name="MyFieldDetectorModule" Type="tt:FieldDetectorEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="50"/>
<tt:ElementItem Name="Transformation"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.002000" y="0.002000"/>
</tt:Transformation>
</tt:ElementItem>
<tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="1000"/>
<tt:Point x="1000" y="1000"/>
<tt:Point x="1000" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
<tt:AnalyticsModule Name="MyTamperDetecModule" Type="hikxsd:TamperEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="0"/>
<tt:ElementItem Name="Transformation"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.002841" y="0.003472"/>
</tt:Transformation>
</tt:ElementItem>
<tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="576"/>
<tt:Point x="704" y="576"/>
<tt:Point x="704" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
</tt:AnalyticsEngineConfiguration>
<tt:RuleEngineConfiguration><tt:Rule Name="MyMotionDetectorRule" Type="tt:CellMotionDetector"><tt:Parameters><tt:SimpleItem Name="MinCount" Value="5"/>
<tt:SimpleItem Name="AlarmOnDelay" Value="1000"/>
<tt:SimpleItem Name="AlarmOffDelay" Value="1000"/>
<tt:SimpleItem Name="ActiveCells" Value="0P8A8A=="/>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector1" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector2" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector3" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector4" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector1" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="50.000000" y="250.000000"/>
<tt:Point x="50.000000" y="1000.000000"/>
<tt:Point x="950.000000" y="1000.000000"/>
<tt:Point x="950.000000" y="250.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector2" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector3" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector4" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyTamperDetectorRule" Type="hikxsd:TamperDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="0"/>
<tt:Point x="0" y="0"/>
<tt:Point x="0" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
</tt:RuleEngineConfiguration>
</tt:VideoAnalyticsConfiguration>
<tt:Extension></tt:Extension>
</trt:Profiles>
<trt:Profiles token="Profile_2" fixed="true"><tt:Name>subStream</tt:Name>
<tt:VideoSourceConfiguration token="VideoSourceToken"><tt:Name>VideoSourceConfig</tt:Name>
<tt:UseCount>2</tt:UseCount>
<tt:SourceToken>VideoSource_1</tt:SourceToken>
<tt:Bounds x="0" y="0" width="1920" height="1080"></tt:Bounds>
</tt:VideoSourceConfiguration>
<tt:VideoEncoderConfiguration token="VideoEncoderToken_2" encoding="H265"><tt:Name>VideoEncoder_2</tt:Name>
<tt:UseCount>1</tt:UseCount>
<tt:Encoding>H264</tt:Encoding>
<tt:Resolution><tt:Width>640</tt:Width>
<tt:Height>360</tt:Height>
</tt:Resolution>
<tt:Quality>3.000000</tt:Quality>
<tt:RateControl><tt:FrameRateLimit>10</tt:FrameRateLimit>
<tt:EncodingInterval>1</tt:EncodingInterval>
<tt:BitrateLimit>512</tt:BitrateLimit>
</tt:RateControl>
<tt:H264><tt:GovLength>20</tt:GovLength>
<tt:H264Profile>Main</tt:H264Profile>
</tt:H264>
<tt:Multicast><tt:Address><tt:Type>IPv4</tt:Type>
<tt:IPv4Address>0.0.0.0</tt:IPv4Address>
</tt:Address>
<tt:Port>8866</tt:Port>
<tt:TTL>128</tt:TTL>
<tt:AutoStart>false</tt:AutoStart>
</tt:Multicast>
<tt:SessionTimeout>PT5S</tt:SessionTimeout>
</tt:VideoEncoderConfiguration>
<tt:VideoAnalyticsConfiguration token="VideoAnalyticsToken"><tt:Name>VideoAnalyticsName</tt:Name>
<tt:UseCount>2</tt:UseCount>
<tt:AnalyticsEngineConfiguration><tt:AnalyticsModule Name="MyCellMotionModule" Type="tt:CellMotionEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="60"/>
<tt:ElementItem Name="Layout"><tt:CellLayout Columns="22" Rows="18"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.090909" y="0.111111"/>
</tt:Transformation>
</tt:CellLayout>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
<tt:AnalyticsModule Name="MyLineDetectorModule" Type="tt:LineDetectorEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="50"/>
<tt:ElementItem Name="Transformation"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.002000" y="0.002000"/>
</tt:Transformation>
</tt:ElementItem>
<tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="1000"/>
<tt:Point x="1000" y="1000"/>
<tt:Point x="1000" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
<tt:AnalyticsModule Name="MyFieldDetectorModule" Type="tt:FieldDetectorEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="50"/>
<tt:ElementItem Name="Transformation"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.002000" y="0.002000"/>
</tt:Transformation>
</tt:ElementItem>
<tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="1000"/>
<tt:Point x="1000" y="1000"/>
<tt:Point x="1000" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
<tt:AnalyticsModule Name="MyTamperDetecModule" Type="hikxsd:TamperEngine"><tt:Parameters><tt:SimpleItem Name="Sensitivity" Value="0"/>
<tt:ElementItem Name="Transformation"><tt:Transformation><tt:Translate x="-1.000000" y="-1.000000"/>
<tt:Scale x="0.002841" y="0.003472"/>
</tt:Transformation>
</tt:ElementItem>
<tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="576"/>
<tt:Point x="704" y="576"/>
<tt:Point x="704" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:AnalyticsModule>
</tt:AnalyticsEngineConfiguration>
<tt:RuleEngineConfiguration><tt:Rule Name="MyMotionDetectorRule" Type="tt:CellMotionDetector"><tt:Parameters><tt:SimpleItem Name="MinCount" Value="5"/>
<tt:SimpleItem Name="AlarmOnDelay" Value="1000"/>
<tt:SimpleItem Name="AlarmOffDelay" Value="1000"/>
<tt:SimpleItem Name="ActiveCells" Value="0P8A8A=="/>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector1" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector2" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector3" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyLineDetector4" Type="tt:LineDetector"><tt:Parameters><tt:SimpleItem Name="Direction" Value="Any"/>
<tt:ElementItem Name="Segments"><tt:Polyline><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polyline>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector1" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="50.000000" y="250.000000"/>
<tt:Point x="50.000000" y="1000.000000"/>
<tt:Point x="950.000000" y="1000.000000"/>
<tt:Point x="950.000000" y="250.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector2" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector3" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyFieldDetector4" Type="tt:FieldDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:Polygon><tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
<tt:Point x="0.000000" y="0.000000"/>
</tt:Polygon>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
<tt:Rule Name="MyTamperDetectorRule" Type="hikxsd:TamperDetector"><tt:Parameters><tt:ElementItem Name="Field"><tt:PolygonConfiguration><tt:Polygon><tt:Point x="0" y="0"/>
<tt:Point x="0" y="0"/>
<tt:Point x="0" y="0"/>
<tt:Point x="0" y="0"/>
</tt:Polygon>
</tt:PolygonConfiguration>
</tt:ElementItem>
</tt:Parameters>
</tt:Rule>
</tt:RuleEngineConfiguration>
</tt:VideoAnalyticsConfiguration>
<tt:Extension></tt:Extension>
</trt:Profiles>
</trt:GetProfilesResponse>
</env:Body>
</env:Envelope>

3. stream uri - Profile Desc 查询回应

 <?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:soapenc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tt="http://www.onvif.org/ver10/schema" xmlns:tds="http://www.onvif.org/ver10/device/wsdl" xmlns:trt="http://www.onvif.org/ver10/media/wsdl" xmlns:timg="http://www.onvif.org/ver20/imaging/wsdl" xmlns:tev="http://www.onvif.org/ver10/events/wsdl" xmlns:tptz="http://www.onvif.org/ver20/ptz/wsdl" xmlns:tan="http://www.onvif.org/ver20/analytics/wsdl" xmlns:tst="http://www.onvif.org/ver10/storage/wsdl" xmlns:ter="http://www.onvif.org/ver10/error" xmlns:dn="http://www.onvif.org/ver10/network/wsdl" xmlns:tns1="http://www.onvif.org/ver10/topics" xmlns:tmd="http://www.onvif.org/ver10/deviceIO/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl" xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12" xmlns:http="http://schemas.xmlsoap.org/wsdl/http" xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:wsadis="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wstop="http://docs.oasis-open.org/wsn/t-1" xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2" xmlns:wsntw="http://docs.oasis-open.org/wsn/bw-2" xmlns:wsrf-rw="http://docs.oasis-open.org/wsrf/rw-2" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsrf-r="http://docs.oasis-open.org/wsrf/r-2" xmlns:trc="http://www.onvif.org/ver10/recording/wsdl" xmlns:tse="http://www.onvif.org/ver10/search/wsdl" xmlns:trp="http://www.onvif.org/ver10/replay/wsdl" xmlns:tnshik="http://www.hikvision.com/2011/event/topics" xmlns:hikwsd="http://www.onvifext.com/onvif/ext/ver10/wsdl" xmlns:hikxsd="http://www.onvifext.com/onvif/ext/ver10/schema" xmlns:tas="http://www.onvif.org/ver10/advancedsecurity/wsdl" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:axt="http://www.onvif.org/ver20/analytics"><env:Body><trt:GetStreamUriResponse><trt:MediaUri><tt:Uri>rtsp://192.168.0.6:554/Streaming/Channels/101?transportmode=unicast&amp;profile=Profile_1</tt:Uri>
<tt:InvalidAfterConnect>false</tt:InvalidAfterConnect>
<tt:InvalidAfterReboot>false</tt:InvalidAfterReboot>
<tt:Timeout>PT60S</tt:Timeout>
</trt:MediaUri>
</trt:GetStreamUriResponse>
</env:Body>
</env:Envelope>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970472.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

叉车车队管理系统怎么选,满足监管要求!

在现代物流与仓储管理中&#xff0c;选择一个高效且可靠的叉车车队管理系统至关重要。一个高性能的管理系统不仅提升作业效率&#xff0c;还能保障作业安全。企业管理者在采购叉车车队管理系统前需要考虑几个关键因素&#xff1a; 1、提升管理效率&#xff1a;‌确保系统能够实…

机器学习赋能的智能光子学器件系统研究与应用

在人工智能与光子学设计融合的背景下&#xff0c;科研的边界持续扩展&#xff0c;创新成果不断涌现。从理论模型的整合到光学现象的复杂模拟&#xff0c;从数据驱动的探索到光场的智能分析&#xff0c;机器学习正以前所未有的动力推动光子学领域的革新。据调查&#xff0c;目前…

【计算机毕业设计】707高校宿舍管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

电脑数据有没有办法恢复?适用于 Windows电脑的的 14 款Windows 恢复工具

如果您在笔记本电脑上安装了 Windows 10&#xff0c;却发现文件均未复制到新系统&#xff0c;该怎么办&#xff1f;您可以在线搜索 Windows 10 恢复工具下载&#xff0c;结果会有很多。 确实&#xff0c;优秀的 Windows 恢复工具能够有效地恢复已删除的文件。问题是市场上有太…

为什么有时候银行贷款审核会查大数据信用?

在申请银行贷款时&#xff0c;不少人会疑惑为何银行会深入审查申请人的大数据信用信息。这背后&#xff0c;其实是银行风险控制与精准决策的体现。 首先&#xff0c;大数据信用信用能全面反映申请人的信用状况 它不仅仅局限于传统的征信报告&#xff0c;还涵盖了消费行为、社交…

无线麦克风可以唱歌吗?领夹麦克风十大品牌,麦克风什么牌子好

追求卓越音质与无拘无束表现力的今天&#xff0c;无线领夹麦克风已成为众多创作者、主播、演讲者以及表演艺术家的得力助手。它们不仅提供了更大的自由度和灵活性&#xff0c;还确保了声音的清晰度和传输的稳定性&#xff0c;有专业的装备才能生成高质量的视频作品&#xff0c;…

WPF中调用UWP API

最近在github上看到一个音乐播放器项目&#xff0c;dopamine(项目地址&#xff1a;GitHub - digimezzo/dopamine-windows: Audio player which tries to make organizing and listening to music as simple and pretty as possible.) 在编译时&#xff0c;提示有一个库找不到 …

免费泛域名证书申请(永久免费,不限申请次数)

免费泛域名证书&#xff08;也称为通配符SSL证书&#xff09;的申请过程通常涉及以下几个步骤。以下是一个详细的指南&#xff0c;帮助您了解如何申请免费泛域名证书&#xff1a; 一、选择合适的证书提供商 目前&#xff0c;市场上提供免费泛域名证书的服务商主要有Lets Encr…

从零开始学习网络安全渗透测试之基础入门篇——(六)网络抓包全局协议封包监听网卡模式科来wiresharkPC应用

网络抓包技术是一种用于捕获和分析网络数据包的技术手段。它能够帮助我们深入了解网络中的数据传输情况&#xff0c;对于网络故障排查、性能优化、安全监测等方面都具有重要意义。 网络抓包的工作原理通常是通过将网络接口设置为混杂模式&#xff0c;使其能够接收流经该接口的…

openEuler使用mariadb

1.安装mariadb 两者互为依赖 解决&#xff1a; 2.开机自启 3.进入数据库 数据库默认没有密码&#xff0c;直接回车进入 4.安全初始化 5.修改密码 远程用户无法登录 6.创建远程登录用户 7.创建数据库 8.赋予远程用户bbs数据库的操作权限 查看用户权限 9.使用普通账号&…

[Docker][Docker NetWork][下]详细讲解

目录 1.网络管理命令1.docker network creatre2.docker network inspect3.docker network connect4.docker network disconnect5.docker network prune6.docker network rm7.docker network ls 2.docker bridge 详解0.基本概念1.默认 bridge2.自定义 bridge3.DNS解析4.端口暴露…

45 标准库 collections 中与字典有关的类

Python 标准库中提供了很多扩展功能&#xff0c;大幅度提高了开发效率。主要介绍 collections 中 OrderedDict 类、defaultdict 类和 Counter类。 1 OrderedDict 类 Python 内置字典 dict 是无序的&#xff0c;如果需要一个可以记住元素插入顺序的字典&#xff0c;则可以使用…

大厂的风控引擎架构设计

1 架构师能力思维模型 全局思维抽象思维 2 新需求的思考路径 需求是否合理&#xff0c;是否能解决问题&#xff1f; 能划分多少个子系统&#xff1f; 每个子系统能划分多少个模块&#xff1f;这个系统需要可靠性吗&#xff0c;需要扩展能力吗&#xff1f;成本需要控制吗&a…

路径规划——广度优先搜索与深度优先搜索

路径规划——广度优先搜索与深度优先搜索 https://www.hello-algo.com/chapter_graph/graph_traversal/ 1.广度优先搜索 Breath-First-Search 在图论中也称为广度优先遍历&#xff0c;类似于树的层序遍历。 算法原理 从起始节点出发&#xff0c;首先访问它的邻近节点&…

openEuler中安装数据库

目录 一.安装数据库 二.出现报错解决方法 1.根据报错查看冲突软件包 2.忽略软件依赖性解决 3.再次查看是否删掉冲突软件 三.再次执行安装数据库命令 四.启动数据库可直接输入mysql进入数据库&#xff0c;此时不安全 五.安全初始化 1.是否有root密码&#xff0c;没有直…

从表型感知到全链路贯通:数字孪生与LLM重塑设施农业新范式

当前,设施农业正处于从传统模式向现代智慧农业加速跃迁的关键时期。数字孪生和大语言模型引领的技术变革浪潮为催生设施农业的创新发展模式提供了新的可能。二者携手打造的全场景数字化运营新范式,必将重塑农业生产的业态和价值链。农业科技工作者应顺应时代发展潮流,将数字孪生…

iOS-Swift 数据库 WCDB 二次封装使用/自定义字段映射类型

WCDB官方使用文档 WCDB简介 WCDB 是一个易用、高效、完整的移动数据库框架&#xff0c;它基于 SQLite 和 SQLCipher 开发&#xff0c;在微信中应用广泛&#xff0c;且支持在 C、Java、Kotlin、Swift、Objc 五种语言环境中使用。 整体架构&#xff1a; 对于WCDB详细的介绍和…

Tomcat安装教程

Tomcat官方网站&#xff1a;http://tomcat.apache.org/ 1.找到左边一栏有个Download&#xff0c;点击Tomcat 10 注意&#xff1a;Tomcat也是要下载JDK环境的&#xff0c;这里我使用Tomcat 10&#xff0c;JDK环境要大于等于11版本&#xff0c;具体可看下图&#xff1a; 2.下拉找…

更小、更安全、更透明:Google发布的Gemma推动负责任AI的进步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…