Linux onvif协议实现二(C语言客户端)
创作人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语言客户端)相关推荐
- onvif协议_【通用语言】ONVIF协议的秘密
点击上面"蓝字"关注我们!什么是"ONVIF" 说到ONVIF,相信在安防行业打拼多年的大家都不陌生.听是听到过这个词,但还有大部分人不能理解这代表着什么,今天 ...
- linux socket通信编程之c语言(客户端和服务器程序)
最近在学习socket编程,在网上找到一个很好的实例,于是按自己的想把代码修改了一下,算半原创了~~~~ 要保存起来常复习呀~~~ /// //服务器端代码:server.c /// //本文件是服务 ...
- 基于ONVIF协议的(IPC)客户端程序开发-10 设备校时
原文链接:http://blog.csdn.net/benkaoya/article/details/72486511 1 编码流程 ONVIF标准中,有 GetSystemDateAndTime和S ...
- Onvif协议控制球机云台
PTZ(Pan-Tilt-Zoom)控制云台的基本流程如下: 创建 ONVIF 设备服务对象:使用 ONVIF 协议连接到摄像头设备,并创建与设备交互的服务对象. 获取 PTZ 配置信息:通过 ONV ...
- ONVIF协议网络摄像机(IPC)客户端程序开发(3):理解什么是Web Services
ONVIF协议网络摄像机(IPC)客户端程序开发(3):理解什么是Web Services 1. 专栏导读 本专栏第一篇文章「专栏开篇」列出了专栏的完整目录,按目录顺序阅读,有助于你的理解,专栏前面文 ...
- ONVIF协议网络摄像机(IPC)客户端程序开发使用gSOAP生成ONVIF框架代码(C++)03-->Windows
其它的不多说,直接开始步骤. 我的版本是2.8.109,目前最新版本. 实际上,onvif的源码是兼容Linux.Windows版本的,例如如果你已经在这篇文章ONVIF协议网络摄像机(IPC)客户端 ...
- Onvif协议客户端开发(5)--获取设备能力
[前言]好久没更新Onvif的这个协议内容了,最近一段时间换成其他内容的开发之后,发现Onvif这部分的知识都快忘了,因此便趁着更新博客的机会重新将Onvif协议的内容再温固一下. Onvif获取设备 ...
- Atitit onvif协议获取rtsp地址播放java语言 attilx总结
Atitit onvif协议获取rtsp地址播放java语言 attilx总结 1.1. 获取rtsp地址的算法与流程1 1.2. Onvif摄像头的发现,ws的发现机制,使用xcf类库1 2. 调用 ...
- ONVIF协议网络摄像机(IPC)客户端程序开发(2):第一次使用IPC摄像头
ONVIF协议网络摄像机(IPC)客户端程序开发(2):第一次使用IPC摄像头 1. 专栏导读 2. 适合读者 本文只适合第一次拿到IPC摄像头,很好奇该怎么使用IPC的读者.已经玩过IPC的,可以略 ...
最新文章
- css 如何 重设 外部样式的属性值_IT兄弟连 HTML5教程 CSS3揭秘 CSS常见的样式属性和值5...
- python【数据结构与算法】战争之城(分支限界法)
- SQLite数据库存储
- java将json转为hashmap_将JSON字符串转换为HashMap
- 领域驱动设计之领域模型_在领域驱动的设计,贫乏的领域模型,代码生成,依赖项注入等方面……...
- php的range函数
- python去重语句_Python对列表去重的多种方法(四种方法)
- 全球首款五摄手机Nokia 9 PureView国行版发布:价格惊了!
- c语言排队系统,【分享】C语言 银行取票排队系统
- Node.js mzitu图片批量下载爬虫1.00
- 广州行键CRM客户关系管理系统
- 移动APP云测试平台测评分析
- android 程序颜色,android – 以编程方式设置scrim颜色
- Halcon慢慢来(卡尺找线、找圆)
- 怎么用dos命令进入指定的文件夹
- 电梯继续上升,到几楼,才会发现事情真相呢?
- mac es安装踩坑日记
- 《网页美工设计Photoshop+Flash+Dreamweaver从入门到精通》——1.6 网页配色安全
- Python实战:批量修改文本文件
- html最全知识点(超级详细)