创作人QQ:851301776,邮箱:lfr890207@163.com,欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点!

个人座右铭:
1.没有横空出世,只要厚积一定发。
2.你可以学历不高,你可以不上学,但你不能不学习

一、介绍

这里主要是以测试实现功能为准则,并没有进一步的整理和优化,测试完成功能后,后期项目进行整理。

ONVIF网上介绍的很多,还有很多对实现进行介绍的,这里不做介绍,网上很多的获取设备能力、获取音视频数据等都有,这里主要贴云台控制。

二、绝对移动

1.或者云台地址

ONVIF_GetCapabilities(DeviceXAddr, ptzXAddr);

2.获取配置文件token

ONVIF_GetProfiles(ptzXAddr, profilesToken);

3.绝对移动(切记使用动态分配)

int ONVIF_PTZAbsoluteMove(const char *ptzXAddr, const char *ProfileToken)

{

int result = 0;
    struct soap *soap = NULL;
    struct _tptz__AbsoluteMove           absoluteMove;
    struct _tptz__AbsoluteMoveResponse   absoluteMoveResponse;

SOAP_ASSERT(ptzXAddr != NULL);
    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));

ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);
    absoluteMove.ProfileToken = (char *)soap_malloc(soap, 128);
    memcpy(absoluteMove.ProfileToken, "MediaProfile00000", strlen("MediaProfile00000"));    
    printf("absoluteMove.ProfileToken = %s\n", absoluteMove.ProfileToken);

absoluteMove.Position = soap_new_tt__PTZVector(soap,sizeof(struct tt__PTZVector));
    absoluteMove.Position->PanTilt = soap_new_tt__Vector2D(soap, sizeof(struct tt__Vector2D));
    absoluteMove.Position->Zoom = soap_new_tt__Vector1D(soap, sizeof(struct tt__Vector1D));
    absoluteMove.Speed = soap_new_tt__PTZSpeed(soap, sizeof(struct tt__PTZSpeed));
    absoluteMove.Speed->PanTilt = soap_new_tt__Vector2D(soap, sizeof(struct tt__Vector2D));
    absoluteMove.Speed->Zoom = soap_new_tt__Vector1D(soap, sizeof(struct tt__Vector1D));

absoluteMove.Position->PanTilt->x = 0;  // p
    absoluteMove.Position->PanTilt->y = 0;   // t
    absoluteMove.Position->Zoom->x = -1;   // z

// x 和y的绝对值越接近1,表示云台的速度越快
    absoluteMove.Speed->PanTilt->x = 0;
    absoluteMove.Speed->PanTilt->y = 0;
    absoluteMove.Speed->Zoom->x = 1;
    result = soap_call___tptz__AbsoluteMove(soap,ptzXAddr, NULL,&absoluteMove,&absoluteMoveResponse);
    SOAP_CHECK_ERROR(result, soap, "ONVIF_PTZAbsoluteMove");
    
    printf("%s result = %d \n", __func__);

EXIT:
    if (NULL != soap) {
        ONVIF_soap_delete(soap);
    }
    return 0;

}

4.相对移动

void ONVIF_PTZMoveStep(const char *ptzXAddr, char *ProfileToken, enum ptz_common cmd, float move_step)
{
    SOAP_ASSERT(NULL != ptzXAddr);
    SOAP_ASSERT(NULL != ProfileToken);

float MoveStep = 0;
    if(move_step >= 1)
        MoveStep = 0.9;
    else{
        MoveStep = move_step;
    }

struct soap *soap = NULL;
    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));

ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);
    
    
    struct _tptz__RelativeMove RelativeMove;
    struct _tptz__RelativeMoveResponse RelativeMoveResponse;

RelativeMove.ProfileToken = ProfileToken;
    printf("tptz__RelativeMove.ProfileToken:%s\n", RelativeMove.ProfileToken);
    struct tt__PTZVector* Translation = soap_new_tt__PTZVector(soap, -1);
    RelativeMove.Translation = Translation;    
    struct tt__Vector2D* panTilt = soap_new_tt__Vector2D(soap, -1);
    RelativeMove.Translation->PanTilt = panTilt;
    //RelativeMove.Translation->PanTilt->space = "http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace";
    struct tt__Vector1D* zoom = soap_new_tt__Vector1D(soap, -1);
    RelativeMove.Translation->Zoom = zoom;
    
    switch (cmd)
    {
        case PTZ_LEFT:
            RelativeMove.Translation->PanTilt->x = MoveStep;
            break;
        case PTZ_RIGHT:
            RelativeMove.Translation->PanTilt->x = -MoveStep;
            break;
        case PTZ_UP:
            RelativeMove.Translation->PanTilt->y = -MoveStep;
            break;
        case PTZ_DOWN:
            RelativeMove.Translation->PanTilt->y = move_step;
            break;
        case PTZ_LEFTUP:
            RelativeMove.Translation->PanTilt->x = MoveStep;
            RelativeMove.Translation->PanTilt->y = -MoveStep;
            break;
        case PTZ_LEFTDOWN:
            RelativeMove.Translation->PanTilt->x = MoveStep;
            RelativeMove.Translation->PanTilt->y = MoveStep;
            break;
        case PTZ_RIGHTUP:
            RelativeMove.Translation->PanTilt->x = -MoveStep;
            RelativeMove.Translation->PanTilt->y = -move_step;
            break;
        case PTZ_RIGHTDOWN:
            RelativeMove.Translation->PanTilt->x = -MoveStep;
            RelativeMove.Translation->PanTilt->y = MoveStep;
            break;
        case PTZ_ZOOMIN:
            RelativeMove.Translation->Zoom->x = MoveStep;
            break;
        case PTZ_ZOOMOUT:
            RelativeMove.Translation->Zoom->x = -MoveStep;
            break;
        default:
            break;
    }

int result = soap_call___tptz__RelativeMove(soap, ptzXAddr, NULL, &RelativeMove, &RelativeMoveResponse);
    SOAP_CHECK_ERROR(result, soap, "soap_call___tptz__RelativeMove");
    printf("result:%d\n", result);
    
    
 EXIT:
    if (NULL != soap) {
        ONVIF_soap_delete(soap);
    }
    return result;    
    
}

5.持续移动

int ONVIF_PTZContinuousMove(const char *ptzXAddr, char *ProfileToken, enum PTZCMD cmd, float speed)

{

int result = 0;
    struct soap *soap = NULL;
    struct _tptz__ContinuousMove continuousMove;
    struct _tptz__ContinuousMoveResponse continuousMoveResponse;

SOAP_ASSERT(NULL != ptzXAddr);
    SOAP_ASSERT(NULL != ProfileToken);
   SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));
    //SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(5)));

ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);
    continuousMove.ProfileToken = ProfileToken;
    printf("continuousMove.ProfileToken:%s\n", continuousMove.ProfileToken);

struct tt__PTZSpeed* velocity = soap_new_tt__PTZSpeed(soap, -1);
    continuousMove.Velocity = velocity;
    struct tt__Vector2D* panTilt = soap_new_tt__Vector2D(soap, -1);
    continuousMove.Velocity->PanTilt = panTilt;
    continuousMove.Velocity->PanTilt->space = "http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace";
    struct tt__Vector1D* zoom = soap_new_tt__Vector1D(soap, -1);
    continuousMove.Velocity->Zoom = zoom;

switch (cmd)
    {
        case  PTZ_CMD_LEFT:
            continuousMove.Velocity->PanTilt->x = -speed;
            continuousMove.Velocity->PanTilt->y = 0;
            break;
        case  PTZ_CMD_RIGHT:
            continuousMove.Velocity->PanTilt->x = speed;
            continuousMove.Velocity->PanTilt->y = 0;
            break;
        case  PTZ_CMD_UP:
            continuousMove.Velocity->PanTilt->x = 0;
            continuousMove.Velocity->PanTilt->y = speed;
            break;
        case  PTZ_CMD_DOWN:
            continuousMove.Velocity->PanTilt->x = 0;
            continuousMove.Velocity->PanTilt->y = -speed;
            break;
        case  PTZ_CMD_LEFTUP:
            continuousMove.Velocity->PanTilt->x = -speed;
            continuousMove.Velocity->PanTilt->y = speed;
            break;
        case PTZ_CMD_LEFTDOWN:
            continuousMove.Velocity->PanTilt->x = -speed;
            continuousMove.Velocity->PanTilt->y = -speed;
            break;
        case  PTZ_CMD_RIGHTUP:
            continuousMove.Velocity->PanTilt->x = speed;
            continuousMove.Velocity->PanTilt->y = speed;
            break;
        case PTZ_CMD_RIGHTDOWN:
            continuousMove.Velocity->PanTilt->x = speed;
            continuousMove.Velocity->PanTilt->y = -speed;
            break;
        case  PTZ_CMD_ZOOM_IN:
            continuousMove.Velocity->PanTilt->x = 1;
            continuousMove.Velocity->PanTilt->y = 1;
            continuousMove.Velocity->Zoom->x = speed;
            break;
        case  PTZ_CMD_ZOOM_OUT:
            continuousMove.Velocity->PanTilt->x = 0;
            continuousMove.Velocity->PanTilt->y = 0;
            continuousMove.Velocity->Zoom->x = -speed;
            break;
        default:
            break;
    }

result = soap_call___tptz__ContinuousMove(soap,ptzXAddr, NULL,&continuousMove,&continuousMoveResponse);
    SOAP_CHECK_ERROR(result, soap, "soap_call___tptz__ContinuousMove");
    printf("soap_call___tptz__ContinuousMove :result = %d\n", result);

EXIT:
    if (NULL != soap) {
        ONVIF_soap_delete(soap);
    }
    return result;

}

6.停止移动

int ONVIF_PTZStopMove(const char* ptzXAddr, const char* ProfileToken){
    int result = 0;
    struct soap *soap = NULL;
    struct _tptz__Stop tptzStop;
    struct _tptz__StopResponse tptzStopResponse;

SOAP_ASSERT((ptzXAddr != NULL) && (ProfileToken != NULL));
    SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));

ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);
    tptzStop.ProfileToken = ProfileToken;
    result = soap_call___tptz__Stop(soap, ptzXAddr, NULL, &tptzStop, &tptzStopResponse);
    SOAP_CHECK_ERROR(result, soap, "ONVIF_PTZStopMove");
    printf("%s result=%d\n", __func__);
    EXIT:
    if (NULL != soap) {
        ONVIF_soap_delete(soap);
    }
    return result;
}

7.获取云台状态

这个需要根据摄像头了,我这边已经实现,但是获取回来的状态有问题

8.提取音视频数据

(1)安装库

void open_rtsp(char *rtsp)
{
    unsigned int    i;
    int             ret;
    int             video_st_index = -1;
    int             audio_st_index = -1;
    AVFormatContext *ifmt_ctx = NULL;
    AVPacket        pkt;
    AVStream        *st = NULL;
    char            errbuf[64];

av_register_all();                                                          
    avformat_network_init();

if ((ret = avformat_open_input(&ifmt_ctx, rtsp, 0, NULL)) < 0) {            
        printf("avformat_open_input error\n");
        goto EXIT;
    }

if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {         
        printf("avformat_find_stream_info error\n");
        goto EXIT;
    }

for (i = 0; i < ifmt_ctx->nb_streams; i++) {                                // dump information
        av_dump_format(ifmt_ctx, i, rtsp, 0);
    }

for (i = 0; i < ifmt_ctx->nb_streams; i++) {                                // find video stream index
        st = ifmt_ctx->streams[i];
        switch(st->codec->codec_type) {
        case AVMEDIA_TYPE_AUDIO: audio_st_index = i; break;
        case AVMEDIA_TYPE_VIDEO: video_st_index = i; break;
        default: break;
        }
    }
    if (-1 == video_st_index) {
        printf("No H.264 video stream in the input file\n");
        goto EXIT;
    }

av_init_packet(&pkt);                                                       // initialize packet.
    pkt.data = NULL;
    pkt.size = 0;

while (1)
    {

do {
            ret = av_read_frame(ifmt_ctx, &pkt);                                // read frames
        } while (ret == AVERROR(EAGAIN));

if (ret < 0) {
          
            printf("av_read_frame error\n");
            break;
        }
        
        if (pkt.stream_index == video_st_index) {                               // video frame
            printf("Video Packet size = %d\n", pkt.size);
            printf("pkt.data:");
            int i = 0;
            for(i=0;i<pkt.size;i++)
            {
                printf("%02x ", pkt.data[i]);
            }
            printf("\n");
            sleep(1);
        } else if(pkt.stream_index == audio_st_index) {                         // audio frame
            printf("Audio Packet size = %d\n", pkt.size);
        } else {
            printf("Unknow Packet size = %d\n", pkt.size);
        }

av_packet_unref(&pkt);
    }

EXIT:

if (NULL != ifmt_ctx) {
        avformat_close_input(&ifmt_ctx);
        ifmt_ctx = NULL;
    }

return ;
}

int ONVIF_GetStreamUri(const char *MediaXAddr, char *ProfileToken, char *uri, unsigned int sizeuri)
{
    int result = 0;
    struct soap *soap = NULL;
    struct tt__StreamSetup              ttStreamSetup;
    struct tt__Transport                ttTransport;
    struct _trt__GetStreamUri           req;
    struct _trt__GetStreamUriResponse   rep;

SOAP_ASSERT(NULL != MediaXAddr);
    SOAP_ASSERT(NULL != uri);
    memset(uri, 0x00, sizeuri);

SOAP_ASSERT(NULL != (soap = ONVIF_soap_new(SOAP_SOCK_TIMEOUT)));

memset(&req, 0x00, sizeof(req));
    memset(&rep, 0x00, sizeof(rep));
    memset(&ttStreamSetup, 0x00, sizeof(ttStreamSetup));
    memset(&ttTransport, 0x00, sizeof(ttTransport));
    ttStreamSetup.Stream                = tt__StreamType__RTP_Unicast;
    ttStreamSetup.Transport             = &ttTransport;
    ttStreamSetup.Transport->Protocol   = tt__TransportProtocol__RTSP;
    ttStreamSetup.Transport->Tunnel     = NULL;
    req.StreamSetup                     = &ttStreamSetup;
    req.ProfileToken                    = ProfileToken;

ONVIF_SetAuthInfo(soap, USERNAME, PASSWORD);
    result = soap_call___trt__GetStreamUri(soap, MediaXAddr, NULL, &req, &rep);
    SOAP_CHECK_ERROR(result, soap, "GetServices");

dump_trt__GetStreamUriResponse(&rep);

result = -1;
    if (NULL != rep.MediaUri) {
        if (NULL != rep.MediaUri->Uri) {
            if (sizeuri > strlen(rep.MediaUri->Uri)) {
                strcpy(uri, rep.MediaUri->Uri);
                result = 0;
            } else {
                SOAP_DBGERR("Not enough cache!\n");
            }
        }
    }

EXIT:

if (NULL != soap) {
        ONVIF_soap_delete(soap);
    }

return result;
}

void cb_discovery(char *DeviceXAddr)
{
    int stmno = 0;                                                              // 码流序号,0为主码流,1为辅码流
    int profile_cnt = 0;                                                        // 设备配置文件个数
    struct tagProfile *profiles = NULL;                                         // 设备配置文件列表
    struct tagCapabilities capa;                                                // 设备能力信息

char uri[ONVIF_ADDRESS_SIZE] = {0};                                         // 不带认证信息的URI地址
    char uri_auth[ONVIF_ADDRESS_SIZE + 50] = {0};                // 带有认证信息的URI地址

ONVIF_GetCapabilities(DeviceXAddr, &capa);        // 获取设备能力信息(获取媒体服务地址)

profile_cnt = ONVIF_GetProfiles(capa.MediaXAddr, &profiles);    // 获取媒体配置信息(主/辅码流配置信息)

if (profile_cnt > stmno) {
        ONVIF_GetStreamUri(capa.MediaXAddr, profiles[stmno].token, uri, sizeof(uri)); // 获取RTSP地址

make_uri_withauth(uri, USERNAME, PASSWORD, uri_auth, sizeof(uri_auth)); // 生成带认证信息的URI(有的IPC要求认证)

open_rtsp(uri_auth);                                                    // 读取主码流的音视频数据
    }

if (NULL != profiles) {
        free(profiles);
        profiles = NULL;
    }
}

9.其他

其他的没什么难度了,比如获取时间之类的

Linux onvif协议实现二(C语言客户端)相关推荐

  1. onvif协议_【通用语言】ONVIF协议的秘密

    点击上面"蓝字"关注我们!什么是"ONVIF" 说到ONVIF,相信在安防行业打拼多年的大家都不陌生.听是听到过这个词,但还有大部分人不能理解这代表着什么,今天 ...

  2. linux socket通信编程之c语言(客户端和服务器程序)

    最近在学习socket编程,在网上找到一个很好的实例,于是按自己的想把代码修改了一下,算半原创了~~~~ 要保存起来常复习呀~~~ /// //服务器端代码:server.c /// //本文件是服务 ...

  3. 基于ONVIF协议的(IPC)客户端程序开发-10 设备校时

    原文链接:http://blog.csdn.net/benkaoya/article/details/72486511 1 编码流程 ONVIF标准中,有 GetSystemDateAndTime和S ...

  4. Onvif协议控制球机云台

    PTZ(Pan-Tilt-Zoom)控制云台的基本流程如下: 创建 ONVIF 设备服务对象:使用 ONVIF 协议连接到摄像头设备,并创建与设备交互的服务对象. 获取 PTZ 配置信息:通过 ONV ...

  5. ONVIF协议网络摄像机(IPC)客户端程序开发(3):理解什么是Web Services

    ONVIF协议网络摄像机(IPC)客户端程序开发(3):理解什么是Web Services 1. 专栏导读 本专栏第一篇文章「专栏开篇」列出了专栏的完整目录,按目录顺序阅读,有助于你的理解,专栏前面文 ...

  6. ONVIF协议网络摄像机(IPC)客户端程序开发使用gSOAP生成ONVIF框架代码(C++)03-->Windows

    其它的不多说,直接开始步骤. 我的版本是2.8.109,目前最新版本. 实际上,onvif的源码是兼容Linux.Windows版本的,例如如果你已经在这篇文章ONVIF协议网络摄像机(IPC)客户端 ...

  7. Onvif协议客户端开发(5)--获取设备能力

    [前言]好久没更新Onvif的这个协议内容了,最近一段时间换成其他内容的开发之后,发现Onvif这部分的知识都快忘了,因此便趁着更新博客的机会重新将Onvif协议的内容再温固一下. Onvif获取设备 ...

  8. Atitit onvif协议获取rtsp地址播放java语言 attilx总结

    Atitit onvif协议获取rtsp地址播放java语言 attilx总结 1.1. 获取rtsp地址的算法与流程1 1.2. Onvif摄像头的发现,ws的发现机制,使用xcf类库1 2. 调用 ...

  9. ONVIF协议网络摄像机(IPC)客户端程序开发(2):第一次使用IPC摄像头

    ONVIF协议网络摄像机(IPC)客户端程序开发(2):第一次使用IPC摄像头 1. 专栏导读 2. 适合读者 本文只适合第一次拿到IPC摄像头,很好奇该怎么使用IPC的读者.已经玩过IPC的,可以略 ...

最新文章

  1. css 如何 重设 外部样式的属性值_IT兄弟连 HTML5教程 CSS3揭秘 CSS常见的样式属性和值5...
  2. python【数据结构与算法】战争之城(分支限界法)
  3. SQLite数据库存储
  4. java将json转为hashmap_将JSON字符串转换为HashMap
  5. 领域驱动设计之领域模型_在领域驱动的设计,贫乏的领域模型,代码生成,依赖项注入等方面……...
  6. php的range函数
  7. python去重语句_Python对列表去重的多种方法(四种方法)
  8. 全球首款五摄手机Nokia 9 PureView国行版发布:价格惊了!
  9. c语言排队系统,【分享】C语言 银行取票排队系统
  10. Node.js mzitu图片批量下载爬虫1.00
  11. 广州行键CRM客户关系管理系统
  12. 移动APP云测试平台测评分析
  13. android 程序颜色,android – 以编程方式设置scrim颜色
  14. Halcon慢慢来(卡尺找线、找圆)
  15. 怎么用dos命令进入指定的文件夹
  16. 电梯继续上升,到几楼,才会发现事情真相呢?
  17. mac es安装踩坑日记
  18. 《网页美工设计Photoshop+Flash+Dreamweaver从入门到精通》——1.6 网页配色安全
  19. Python实战:批量修改文本文件
  20. html最全知识点(超级详细)

热门文章

  1. Python的简单数据类型案例
  2. 资金指数(ZJZS)指标
  3. C和C++的区别(2) 关键字
  4. 气结、气闭、气郁......百病生于气!
  5. 文件夹重定向路径修改问题
  6. 信息系统集成-辅助知识-知产/法律法规/标准化
  7. 嫁给我是你一生的赌注,我怎么舍得让你输
  8. oracle如何判断数字中有字母,SQL 判断含有字母和数字的字符串
  9. 施工部署主要不包括_施工部署包括什么?
  10. Flink专题四:Flink DataStream 窗口介绍及使用