onvif请求关键帧

1.概述

        在我们使用onvif对接监控,使用onvif获取到的rtsp地址取流时,会出现这样的一种应用场景,只取流一路rtsp流,分发给多个客户端进行显示,客户端取流的时间点不相同,此时如果摄像头的关键帧间隔设置的很大,那么其余后续的客户端就需要等待摄像头编码出下一个关键帧才能进行显示,这样需要等待很长的时间,体验很差。我们可以通过onvif向摄像头发送插入关键帧的请求来优化这种情况。

2.整个流程使用到的接口

3.demo

//OnvifTool.h

#include "stdsoap2.h"
#include "soapH.h"
#include "soapStub.h"
#include "wsseapi.h"
#include <string>

using namespace std;

class OnvifTool
{
public:
    OnvifTool();
    ~OnvifTool();

    bool GetCapabilities(const string& ip, uint16_t port, const string& userName,
                         const string& password, string& xAddr);
    
    bool GetProfiles(const string& userName, const string& password, const string& xAddr,
                     string& profileToken);

    bool SetSynchronizationPoint(const string& userName, const string& password,
                                 const string& xAddr, const string& profileToken);
private:
    void InitSoap(soap *pSoap);

    void FreeSoap(soap *pSoap);

    soap* m_pSoap;
};
// OnvifTool.cxx
// 只获取第一个profile文件来做测试

#include "OnvifTool.h"
#include <iostream>

OnvifTool::OnvifTool()
{
    m_pSoap = soap_new();
}

OnvifTool::~OnvifTool()
{
    if (m_pSoap) {
        FreeSoap(m_pSoap);
        soap_free(m_pSoap);
    }
}

bool OnvifTool::GetCapabilities(const string& ip, uint16_t port, const string& userName,
                                const string& password, string& xAddr)
{
    InitSoap(m_pSoap);

    char endp[128] = {0};
    if (port != 0)
        snprintf(endp, sizeof(endp), "http://%s:%d/onvif/device_service", ip, port);
    else
        snprintf(endp, sizeof(endp), "http://%s/onvif/device_service", ip);

    struct _tds__GetCapabilities req;
    struct _tds__GetCapabilitiesResponse resp;

    req.Category.push_back(tt__CapabilityCategory__All);    //获取所有能力

    soap_wsse_add_UsernameTokenDigest(m_pSoap, NULL, userName.c_str(),
                                      password.c_str());
    int ret = soap_call___tds__GetCapabilities(m_pSoap, endp, NULL,
                                               &req, resp);
    if (ret != SOAP_OK) {
        cout << "GetCapabilities failed!!!!" << endl;
        FreeSoap(m_pSoap);
        return false;
    }

    if (resp.Capabilities && resp.Capabilities->Media 
        && resp.Capabilities->Media->XAddr) {
        xAddr = resp.Capabilities->Media->XAddr;
        cout << "GetCapabilities success, xAddr=" << xAddr << endl;
        FreeSoap(m_pSoap);
        return true;
    }

    cout << "GetCapabilities failed!!!!" << endl;
    FreeSoap(m_pSoap);
    return false;
}

bool OnvifTool::GetProfiles(const string& userName,const string& password, 
                            string& xAddr, const string& profileToken)
{
    InitSoap(m_pSoap);

    struct _trt__GetProfiles req;
    struct _trt__GetProfilesResponse resp;

    soap_wsse_add_UsernameTokenDigest(m_pSoap, NULL, userName.c_str(),
                                      password.c_str());

    int ret = soap_call___trt__GetProfiles(m_pSoap, xAddr.c_str(), NULL, &req, resp);
    if (ret != SOAP_OK) {
        cout << "GetProfiles failed!!!!" << endl;
        FreeSoap(m_pSoap);
        return false;
    }

    if (resp.Profiles.size() > 0) {
        // 只取第一个profile做测试
        profileToken = resp.Profiles[0]->token;
        cout << "GetProfiles success, profileToken=" << profileToken << endl;
        FreeSoap(m_pSoap);
        return true;
    }

    cout << "GetProfiles failed!!!!" << endl;
    FreeSoap(m_pSoap);
    return false;
}

bool OnvifTool::SetSynchronizationPoint(const string& userName, const string& password,
                                        const string& xAddr, const string& profileToken)
{
    InitSoap(m_pSoap);

    struct _trt__SetSynchronizationPoint req;
    struct _trt__SetSynchronizationPointResponse resp;

    req.ProfileToken = profileToken;

    soap_wsse_add_UsernameTokenDigest(m_pSoap, NULL, userName.c_str(), password.c_str());

    int ret = soap_call___trt__SetSynchronizationPoint(m_pSoap, xAddr.c_str(), NULL,
                                                       &req, resp);
    if (ret != SOAP_OK) {
        cout << "SetSynchronizationPoint failed!!!!" << endl;
        FreeSoap(m_pSoap);
        return false;
    }

    cout << "SetSynchronizationPoint success" << endl;
    FreeSoap(m_pSoap);
    return true;
}

void OnvifTool::InitSoap(soap *pSoap)
{
    soap_init(pSoap);
    pSoap->recv_timeout = 1;
    pSoap->send_timeout = 1;
    pSoap->connect_timeout = 1;
    soap_set_namespaces(pSoap, namespaces);
}

void OnvifTool::FreeSoap(soap *pSoap)
{
    soap_destroy(pSoap);
    soap_end(pSoap);
    soap_done(pSoap);
}
// main.cxx

#include "OnvifTool.h"

int main()
{
    string ip = "192.168.1.2";
    string userName = "admin";
    string password = "admin";

    uint16_t port = 80;
    
    string xAddr, profileToken;
    
    OnvifTool tool;
    bool ret = tool.GetCapabilities(ip, port, userName, password, xAddr);
    if (!ret)
        return -1;

    ret = tool.GetProfiles(userName, password, xAddr, profileToken);
    if (!ret)
        return -1;

    ret = tool.SetSynchronizationPoint(userName, password, xAddr, profileToken);
    if (!ret)
        return -1;

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值