Linux c++ onvif客户端开发(9):GetProfiles

本文是Linux c++ onvif客户端开发系列文章之一:

  • Linux c++ onvif客户端开发(1): 根据wsdl生成cpp源文件
  • Linux c++ onvif客户端开发(2): 获取摄像头H264/H265 RTSP地址
  • Linux c++ onvif客户端开发(3): 扫描设备
  • Linux c++ onvif客户端开发(4): 扫描某个设备是否支持onvif
  • Linux c++ onvif客户端开发(5):gsoap内存管理
  • Linux c++ onvif客户端开发(6):获取设备信息

  • Linux c++ onvif客户端开发(7):struct soap包装类

  • Linux c++ onvif客户端开发(8):GetServices

 1. 什么是Profile

这个接口的Profile可以理解为一条通道。 主码流、主码流是不同的通道,因此它们有不同的Profle。

每个Profile有独立的VideoSource,VideoEncoder,Analytics,Metadata等。

每个Profle的属性包括Profile token和Profile name。其中Profile token是很重要的属性,访问这个Profle属性的时候都会要求传这个数据。

2. Media2

Media2是https://www.onvif.org/onvif/ver20/media/wsdl/media.wsdl,这个规范支持H265。本文所讲解的也是这个规范。

3. GetProfiles

接口有两个可选参数Token和Type

ONVIF Device Test Tool 随手掏 

4. 获取所有 Profile token和name

发送

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetProfiles xmlns="http://www.onvif.org/ver20/media/wsdl">
      <Token>Profile000</Token>
    </GetProfiles>
  </s:Body>
</s:Envelope>

接收

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:sc="http://www.w3.org/2003/05/soap-encoding" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema">
  <s:Body>
    <tr2:GetProfilesResponse>
      <tr2:Profiles token="Profile000" fixed="true">
        <tr2:Name>Profile000</tr2:Name>
      </tr2:Profiles>
      <tr2:Profiles token="Profile001" fixed="true">
        <tr2:Name>Profile001</tr2:Name>
      </tr2:Profiles>
    </tr2:GetProfilesResponse>
  </s:Body>
</s:Envelope>

token是很重要的数据,后面要考的。

C++实现

先声明

struct Media20Profile {
    std::string token;
    std::string name;
};

class Device {
public:
    Device(const std::string &ip, const std::string &user,
           const std::string &passwd, int default_timeout = 2);
    ~Device();

    int Probe(int timeout = 1);

    std::string xaddr() const { return xaddr_; }

    int GetDeviceInformation(DeviceInformation &device_info,
                             Fault *fault = nullptr);


    // 获取服务地址集
    int GetServices(std::map<std::string, Service> &services,
                    Fault *fault = nullptr);

    // 获取Profiles 名称和token
    int GetProfiles(std::vector<Media20Profile> &profiles,
                    Fault *fault = nullptr,
                    const std::string &media_xaddr = std::string());

    // 根据profile token 获取source 和video encoder配置
    int GetProfiles(ProfileConfigurations &profile_configurations,
                    const std::string &profile_token,
                    const std::string &media_xaddr = std::string());


private:
    std::string ip_;
    std::string username_;
    std::string password_;
    int default_timeout_;

    std::string xaddr_;
};

 实现

int Device::GetProfiles(std::vector<Media20Profile> &profiles, Fault *fault,
                        const std::string &media_xaddr) {
    //  xmlns:trt="http://www.onvif.org/ver10/media/wsdl
    //  xmlns:ns1="http://www.onvif.org/ver20/media/wsdl"

    std::unique_ptr<Soap> soap(new Soap(default_timeout_));

    soap_wsse_add_UsernameTokenDigest(soap->soap(), nullptr, username_.data(),
                                      password_.data());

    // 支持H265
    struct _ns1__GetProfiles media2_req;
    struct _ns1__GetProfilesResponse media2_resp;

    int result = 0;
    result = soap_call___ns1__GetProfiles(
        soap->soap(), media_xaddr.empty() ? xaddr_.data() : media_xaddr.data(),
        NULL, &media2_req, media2_resp);

    if (SOAP_OK != result) {
        soap->FillFault(fault);
    } else {
        for (auto &i : media2_resp.Profiles) {
            Media20Profile prof{.token = i->token, .name = i->Name};
            profiles.emplace_back(prof);
        }
    }

    return result;
}

media_xaddr 是通过GetServices拿到的数据,对应命名空间http://www.onvif.org/ver20/media/wsdl的 xaddr。一般也可以直接用设备的xaddr。

5. 获取Profles详细信息

如果请求里面指定 Token和Type,那么接口也会返回这个Profile的详细信息。比如视频源信息、视频编码器信息等。

发送

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetProfiles xmlns="http://www.onvif.org/ver20/media/wsdl">
      <Token>Profile000</Token>
      <Type>VideoEncoder</Type>
    </GetProfiles>
  </s:Body>
</s:Envelope>

接收

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:sc="http://www.w3.org/2003/05/soap-encoding" xmlns:tr2="http://www.onvif.org/ver20/media/wsdl" xmlns:tt="http://www.onvif.org/ver10/schema">
  <s:Body>
    <tr2:GetProfilesResponse>
      <tr2:Profiles token="Profile000" fixed="true">
        <tr2:Name>Profile000</tr2:Name>
        <tr2:Configurations>
          <tr2:VideoEncoder token="VideoEncoder000" GovLength="16" Profile="Main">
            <tt:Name>VideoEncoder000</tt:Name>
            <tt:UseCount>1</tt:UseCount>
            <tt:Encoding>H265</tt:Encoding>
            <tt:Resolution>
              <tt:Width>1280</tt:Width>
              <tt:Height>960</tt:Height>
            </tt:Resolution>
            <tt:RateControl ConstantBitRate="false">
              <tt:FrameRateLimit>10</tt:FrameRateLimit>
              <tt:BitrateLimit>2304</tt:BitrateLimit>
            </tt:RateControl>
            <tt:Multicast>
              <tt:Address>
                <tt:Type>IPv4</tt:Type>
                <tt:IPv4Address>224.1.2.4</tt:IPv4Address>
              </tt:Address>
              <tt:Port>40000</tt:Port>
              <tt:TTL>64</tt:TTL>
              <tt:AutoStart>false</tt:AutoStart>
            </tt:Multicast>
            <tt:Quality>3.000000</tt:Quality>
          </tr2:VideoEncoder>
        </tr2:Configurations>
      </tr2:Profiles>
    </tr2:GetProfilesResponse>
  </s:Body>
</s:Envelope>

C++实现

声明

这里我只定义了VideoSource,VideoEncoder相关配置。


struct Resolution {
    int width = 0;
    int height = 0;
};

struct RateControl {
    bool constant_bit_rate = false;
    float frame_rate_limit = 0;
    int bitrate_limit = 0;
};

struct VideoSourceConfiguration {
    std::string token;
    std::string source_token;
    std::string name;
};

struct VideoEncoderConfiguration {
    // GetVideoEncoderConfigurations 中的token和name,不是profile token。示例:
    // token="VideoEncoder000"   <tt:Name>VideoEncoder000</tt:Name>
    std::string token;
    int gov_length = 0;
    // Baseline Main High
    std::string profile;

    std::string name;
    std::string encoding;

    Resolution resolution;
    RateControl rate_control;

    float quality = 0;
};

struct ProfileConfigurations {
    Media20Profile profile;
    VideoSourceConfiguration video_source_config;
    VideoEncoderConfiguration video_encoder_config;
};

实现


int Device::GetProfiles(ProfileConfigurations &profile_configurations,
                        const std::string &token,
                        const std::string &media_xaddr) {

    std::unique_ptr<Soap> soap(new Soap(default_timeout_));

    soap_wsse_add_UsernameTokenDigest(soap->soap(), nullptr, username_.data(),
                                      password_.data());

    // 支持H265
    struct _ns1__GetProfiles media2_req;
    struct _ns1__GetProfilesResponse media2_resp;

    std::string profile_token(token);
    media2_req.Token = &profile_token;
    media2_req.Type.push_back(soap_ns1__ConfigurationEnumeration2s(
        soap->soap(), ns1__ConfigurationEnumeration::VideoSource));
    media2_req.Type.push_back(soap_ns1__ConfigurationEnumeration2s(
        soap->soap(), ns1__ConfigurationEnumeration::VideoEncoder));

    int result = 0;
    result = soap_call___ns1__GetProfiles(
        soap->soap(), media_xaddr.empty() ? xaddr_.data() : media_xaddr.data(),
        NULL, &media2_req, media2_resp);

    if (SOAP_OK != result) {
        return result;
    }

    for (auto &i : media2_resp.Profiles) {
        profile_configurations.profile.name = i->Name;
        profile_configurations.profile.token = i->token;

        if (i->Configurations) {
            if (i->Configurations->VideoSource) {
                auto vs = i->Configurations->VideoSource;
                profile_configurations.video_source_config.token = vs->token;
                profile_configurations.video_source_config.source_token =
                    vs->SourceToken;
                profile_configurations.video_source_config.name = vs->Name;
            }

            if (i->Configurations->VideoEncoder) {
                auto ve = i->Configurations->VideoEncoder;

                profile_configurations.video_encoder_config.token = ve->token;
                profile_configurations.video_encoder_config.gov_length =
                    *ve->GovLength;

                profile_configurations.video_encoder_config.profile =
                    *ve->Profile;
                profile_configurations.video_encoder_config.name = ve->Name;
                profile_configurations.video_encoder_config.encoding =
                    ve->Encoding;
                profile_configurations.video_encoder_config.resolution.width =
                    ve->Resolution->Width;
                profile_configurations.video_encoder_config.resolution.height =
                    ve->Resolution->Height;
                profile_configurations.video_encoder_config.rate_control
                    .constant_bit_rate = *ve->RateControl->ConstantBitRate;
                profile_configurations.video_encoder_config.rate_control
                    .bitrate_limit = ve->RateControl->BitrateLimit;
                profile_configurations.video_encoder_config.rate_control
                    .frame_rate_limit = ve->RateControl->FrameRateLimit;
                profile_configurations.video_encoder_config.quality =
                    ve->Quality;
            }
        }
    }

    return result;
}

6. 后记

1. 其他功能比如AudioSource, AudioEncoder自己去扩展

2. Soap,Fault 的定义参考前面文章 Linux c++ onvif客户端开发(7):struct soap包装类

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

js基础知识(2)

一、事件的含义 JavaScript事件是指在文档或者浏览器中发生的一些特定交互瞬间&#xff0c;比如打开某一个网页&#xff0c;浏览器加载完成后会触发load事件&#xff0c;当鼠标悬浮于某一个元素上时会触发hover事件&#xff0c;当鼠标点击某一个元素时会触发click事件等等。 三…

电子签章与SSL证书:区别与功能对比

电子签章是一种用于电子文档的签名技术&#xff0c;它通过密码学方法确保文档的完整性、真实性和签署行为的不可否认性。电子签章技术结合了图像处理技术和电子签名技术&#xff0c;使得电子文档在法律上与传统纸质文件具有同等效力。这种技术通常用于需要法律认可的电子合同、…

【Matlab函数分析】对二维或三维散点数据插值函数scatteredInterpolant

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

部署和发布

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、打包 Spring Boot 项⽬二、上传jar包至服务器三.启动项目四.停止项目总结 前言 确认服务器已安装好 Java 环境&#xff1b;确保服务器有可⽤的 MySQL&…

指标+AI:迈向智能化,让指标应用更高效

近日&#xff0c;以“DataAI&#xff0c;构建新质生产力”为主题的袋鼠云春季发布会圆满落幕&#xff0c;大会带来了一系列“AI”的数字化产品与最新行业沉淀&#xff0c;旨在将数据与AI紧密结合&#xff0c;打破传统的生产力边界&#xff0c;赋能企业实现更高质量、更高效率的…

Mac读写U盘软件哪个好用 Mac读写U盘很慢怎么解决 macbookpro读取u盘

在使用Mac电脑时&#xff0c;读写U盘是一个常见的需求&#xff0c;特别是当U盘格式为NTFS时。选择适合的软件来实现这一操作至关重要。下面我们来看Mac读写U盘软件哪个好用&#xff0c;Mac读写U盘很慢怎么解决的相关内容。 一、Mac读写U盘软件哪个好用 在Mac上选择一款适合的…

美国网站服务器解决方案

在当今互联网时代&#xff0c;网站是企业宣传、营销和销售的最好方式&#xff0c;因此&#xff0c;选择一个适合自己企业的网站服务器解决方案很重要。美国作为全球网络基础设施最发达的国家之一&#xff0c;其网站服务器解决方案具有以下特点&#xff1a; 一、安全性高 作为全…

5个方便好用的Python自动化脚本

相比大家都听过自动化生产线、自动化办公等词汇&#xff0c;在没有人工干预的情况下&#xff0c;机器可以自己完成各项任务&#xff0c;这大大提升了工作效率。 编程世界里有各种各样的自动化脚本&#xff0c;来完成不同的任务。 尤其Python非常适合编写自动化脚本&#xff0…

【JAVA】PO、VO、DAO、BO、DTO、POJO你分得清吗?

在Java开发中&#xff0c;PO、VO、DAO、BO、DTO、POJO这些词汇是比较常见的&#xff0c;每个术语都有其特定的含义和用途。下面是它们的具体区别&#xff1a; 名称简要概况用途和特定PO (Persistence Object) 持…

c++11详解

目录 1.列表初始化 2.声明 3.右值引用和移动语句 4. c11新的类功能 5. 可变参数模板 6.lambda表达式 7.包装器 8. 后言 1. 列表初始化 1.1 {}的初始化 (1) c98标准规定可以使用{}对数组以及结构体进行统一的列表初始化. struct Point {int _x;int _y; };int main() {in…

OpenStack的基本操作

1.实例类型管理 首先用管理员账号登录OpenStack 点击创建实例类型后&#xff1a;可以看见实例类型创建成功 2.项目与租户管理 Openstack有严格的项目及租户管理制度&#xff0c;在项目中使用管理员创建项目&#xff0c;然后为该项目创建一个以你姓名命名的账户为该项目的管理…

N5245B PNA-X 微波网络分析仪

N5245B PNA-X 微波网络分析仪 " 900 Hz/10 MHz 至 50 GHz " N5245B PNA-X 微波网络分析仪&#xff0c;900 Hz/10 MHz 至 50 GHz&#xff0c;2 端口和 4 端口&#xff0c;多达三个信号源。 特点 实现卓越性能 这款 PNA-X 分析仪不仅仅是一款矢量网络分析仪&a…

每日两题 / 46. 全排列 41. 缺失的第一个正数(LeetCode热题100)

46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 经典回溯题&#xff0c;每次搜索选择未选择数字中的一个 当选择了n个数时&#xff0c;将已经选择的数加入答案 class Solution { public:vector<vector<int>> permute(vector<int>& nums) {vector…

进制转换问题

1.十进制转二进制&#xff08;善于使用__int128&#xff09; 3373. 进制转换 - AcWing题库 #include<bits/stdc.h> using namespace std; __int128 x; int x_; string s1; int main(){stack<int> s;while(cin>>s1){int lens1.size();for(int i0;i<len;i)…

短视频素材怎么做?视频素材库那个好?

在这个视频内容占据主导的时代&#xff0c;高质量的无水印视频素材不仅能够丰富视觉体验&#xff0c;还能显著提升你的作品吸引力。为了帮助你在广阔的创意海洋中航行&#xff0c;下面介绍的一系列视频素材网站将为你的项目注入新的活力&#xff0c;让每个创意的火花都能闪耀发…

react之初识state

第二章 - 添加交互 State: 组件的记忆 组件通常需要根据交互更改屏幕上显示的内容。输入表单应该更新输入字段&#xff0c;单击轮播图上的“下一个”应该更改显示的图片&#xff0c;单击“购买”应该将商品放入购物车。组件需要“记住”某些东西&#xff1a;当前输入值、当前…

Multitouch 1.27.28 免激活版 mac电脑多点触控手势增强工具

Multitouch 应用程序可让您将自定义操作绑定到特定的魔术触控板或鼠标手势。例如&#xff0c;三指单击可以执行粘贴。通过执行键盘快捷键、控制浏览器的选项卡、单击鼠标中键等来改进您的工作流程。 Multitouch 1.27.28 免激活版下载 强大的手势引擎 精心打造的触控板和 Magic …

怎么办xgp会员一年多少钱xgp会员怎么开轻松教你xgp会员开通教程

怎么办&#xff1f;xgp会员一年多少钱&#xff1f;xgp会员怎么开&#xff1f;轻松教你xgp会员开通教程 XGP平台是由微软公司开发的xbox游戏平台的pc版本&#xff0c;为电脑玩家提供了一个游玩微软游戏的平台&#xff0c;XGP平台因其独特的会员服务而广受玩家们好评&#xff0…

浓眉大眼的Apple开源OpenELM模型;IDM-VTON试衣抱抱脸免费使用;先进的语音技术,能够轻松克隆任何人的声音

✨ 1: openelm OpenELM是苹果机器学习研究团队发布的高效开源语言模型家族 OpenELM是苹果机器学习研究团队开发的一种高效的语言模型&#xff0c;旨在推动开放研究、确保结果的可信赖性、允许对数据和模型偏见以及潜在风险进行调查。其特色在于采用了一种分层缩放策略&#x…

融合公式调权思考

一般在多目标任务任务中有加法公式、乘法公式、混合加法、非线性公式等&#xff0c;通过业务特性和应用场景选择不同方式&#xff0c;线上调参也有很多方案&#xff0c;自动寻参&#xff08;成本较高&#xff0c;比如进化算法、网格搜索、随机搜索、贝叶斯优化、自动调参工具如…