国标28181之服务端下发云台PTZ命令浅谈

一、看协议文档

网上资料挺少的,求人不如求己,打铁还需自身硬,啃文档是最直接的学习方式。国标28181对ptz信令这块,有确切的描述。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
其实文档里已经说的很清楚了,就是一些字节方面的移位操作,当然实现方式很多种。我下面列出我实现的一种方式。

二、具体代码实现

云台请求相关接口:

bool GB28181Srv::RequestPTZ(stuDev *pDev, ePTZCmd eCmd, int iSpeed, int iSpeed2)
{
	if (pDev == NULL)
		return false;

	QString sCmd = GetStrFromPTZCmd(eCmd, iSpeed, iSpeed2);
	QString sBody;
	sBody.sprintf(
		"<?xml version=\"1.0\"?>\r\n"
		"<Control>\r\n"
		"  <CmdType>DeviceControl</CmdType>\r\n"
		"  <SN>%d</SN>\r\n"
		"  <DeviceID>%s</DeviceID>\r\n"
		"  <PTZCmd>%s</PTZCmd>\r\n"
		"</Control>\r\n"
		, ++m_iRequestMessageSN, pDev->m_sDevCode.toStdString().data(), sCmd.toStdString().data());
	int ret = SendRequestMessage(pDev->m_sDevCode, pDev->m_sDevIp, pDev->m_iDevPort, "Application/MANSCDP+xml", sBody);
	return !ret;
}

关键部分,写的比较挫,各位看官将就看下:

QString GB28181Srv::GetStrFromPTZCmd(ePTZCmd eCmd, quint8 iSpeed, quint8 iSpeed2)
{
	QString sCmd = "A50F00";
	switch (eCmd)
	{
	case ePTZUp:
	case ePTZUpStop:
		sCmd += eCmd == ePTZUp ? "0800" : "0000";
		sCmd += eCmd == ePTZUp ? GetHexFromInt(iSpeed) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZUp ? GetCrcFromPTZCmd(165 + 15 + 0 + 8 + 0 + iSpeed + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZDown:
	case ePTZDownStop:
		sCmd += eCmd == ePTZDown ? "0400" : "0000";
		sCmd += eCmd == ePTZDown ? GetHexFromInt(iSpeed) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZDown ? GetCrcFromPTZCmd(165 + 15 + 0 + 4 + 0 + iSpeed + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZLeft:
	case ePTZLeftStop:
		sCmd += eCmd == ePTZLeft ? "02" : "00";
		sCmd += eCmd == ePTZLeft ? GetHexFromInt(iSpeed) : "00";
		sCmd += "0000";
		sCmd += eCmd == ePTZLeft ? GetCrcFromPTZCmd(165 + 15 + 0 + 2 + iSpeed + 0 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZRight:
	case ePTZRightStop:
		sCmd += eCmd == ePTZRight ? "01" : "00";
		sCmd += eCmd == ePTZRight ? GetHexFromInt(iSpeed) : "00";
		sCmd += "0000";
		sCmd += eCmd == ePTZRight ? GetCrcFromPTZCmd(165 + 15 + 0 + 1 + iSpeed + 0 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZUpLeft:
	case ePTZUpLeftStop:
		sCmd += eCmd == ePTZUpLeft ? "0A" : "00";
		sCmd += eCmd == ePTZUpLeft ? GetHexFromInt(iSpeed) : "00";
		sCmd += eCmd == ePTZUpLeft ? GetHexFromInt(iSpeed2) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZUpLeft ? GetCrcFromPTZCmd(165 + 15 + 0 + 10 + iSpeed + iSpeed2 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZUpRight:
	case ePTZUpRightStop:
		sCmd += eCmd == ePTZUpRight ? "09" : "00";
		sCmd += eCmd == ePTZUpRight ? GetHexFromInt(iSpeed) : "00";
		sCmd += eCmd == ePTZUpRight ? GetHexFromInt(iSpeed2) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZUpRight ? GetCrcFromPTZCmd(165 + 15 + 0 + 9 + iSpeed + iSpeed2 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZDownLeft:
	case ePTZDownLeftStop:
		sCmd += eCmd == ePTZDownLeft ? "06" : "00";
		sCmd += eCmd == ePTZDownLeft ? GetHexFromInt(iSpeed) : "00";
		sCmd += eCmd == ePTZDownLeft ? GetHexFromInt(iSpeed2) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZDownLeft ? GetCrcFromPTZCmd(165 + 15 + 0 + 6 + iSpeed + iSpeed2 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZDownRight:
	case ePTZDownRightStop:
		sCmd += eCmd == ePTZDownRight ? "05" : "00";
		sCmd += eCmd == ePTZDownRight ? GetHexFromInt(iSpeed) : "00";
		sCmd += eCmd == ePTZDownRight ? GetHexFromInt(iSpeed2) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZDownRight ? GetCrcFromPTZCmd(165 + 15 + 0 + 5 + iSpeed + iSpeed2 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZZoomIn:
	case ePTZZoomInStop:
		sCmd += eCmd == ePTZZoomIn ? "100000" : "000000";
		sCmd += eCmd == ePTZZoomIn ? GetHexFromInt(iSpeed * 16) : "00";
		sCmd += eCmd == ePTZZoomIn ? GetCrcFromPTZCmd(165 + 15 + 0 + 16 + 0 + 0 + iSpeed * 16) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZZoomOut:
	case ePTZZoomOutStop:
		sCmd += eCmd == ePTZZoomOut ? "200000" : "000000";
		sCmd += eCmd == ePTZZoomOut ? GetHexFromInt(iSpeed * 16) : "00";
		sCmd += eCmd == ePTZZoomOut ? GetCrcFromPTZCmd(165 + 15 + 0 + 32 + 0 + 0 + iSpeed * 16) : GetCrcFromPTZCmd(165 + 15 + 0 + 0 + 0 + 0 + 0);
		break;
	case ePTZFocusFar:
	case ePTZFocusFarStop:
		sCmd += eCmd == ePTZFocusFar ? "41": "40";
		sCmd += eCmd == ePTZFocusFar ? GetHexFromInt(iSpeed) : "00";
		sCmd += "0000";
		sCmd += eCmd == ePTZFocusFar ? GetCrcFromPTZCmd(165 + 15 + 0 + 65 + iSpeed + 0 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 64 + 0 + 0 + 0);
		break;
	case ePTZFocusNear:
	case ePTZFocusNearStop:
		sCmd += eCmd == ePTZFocusNear ? "42" : "40";
		sCmd += eCmd == ePTZFocusNear ? GetHexFromInt(iSpeed) : "00";
		sCmd += "0000";
		sCmd += eCmd == ePTZFocusNear ? GetCrcFromPTZCmd(165 + 15 + 0 + 66 + iSpeed + 0 + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 64 + 0 + 0 + 0);
		break;
	case ePTZIrisIn:
	case ePTZIrisInStop:
		sCmd += eCmd == ePTZIrisIn ? "4400" : "4000";
		sCmd += eCmd == ePTZIrisIn ? GetHexFromInt(iSpeed) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZIrisIn ? GetCrcFromPTZCmd(165 + 15 + 0 + 68 + 0 + iSpeed + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 64 + 0 + 0 + 0);
		break;
	case ePTZIrisOut:
	case ePTZIrisOutStop:
		sCmd += eCmd == ePTZIrisOut ? "4800" : "4000";
		sCmd += eCmd == ePTZIrisOut ? GetHexFromInt(iSpeed) : "00";
		sCmd += "00";
		sCmd += eCmd == ePTZIrisOut ? GetCrcFromPTZCmd(165 + 15 + 0 + 72 + 0 + iSpeed + 0) : GetCrcFromPTZCmd(165 + 15 + 0 + 64 + 0 + 0 + 0);
		break;
	default:
		break;
	}

	return sCmd;
}

先这样,该睡了。不懂的再联系

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
  1、支持国标GB28181平台、国标GB28181 IPC和国标GB28181 NVR设备同时接入 (支持GB28181-2011版本和GB28181-2016版本)     2、支持国标GB28181设备注册和注销,对所有设备进行管理,获取资源 对资源列表进行管理     3、支持国标GB28181的目录订阅,对接收的订阅通知进行处理     4、支持国标GB28181实时视频请求(支持UDP、TCP主动(tcpactive)、TCP被动(tcppassive))     5、支持国标GB28181 PTZ控制     6、支持国标GB28181 录像查询     7、支持国标GB28181 历史视频点播 (支持UDP、TCP主动(tcpactive)、TCP被动(tcppassive))     8、支持国标GB28181 历史视频下载 (支持UDP、TCP主动(tcpactive)、TCP被动(tcppassive))     9、支持对接收的国标实时视频码流和历史视频码流进行管理     10、支持将国标的PS码流转换成ES码流     11、支持丢包打印和断流打印     13、支持RTSP服务和RTSP会话管理     14、支持RTSP客户端 UDP传输和TCP传输     15、支持国标GB28181设备5000路左右的接入管理,支持国标请求视频在100路左右     16、支持国标28181设备和通道写入mysql数据库      17、支持设备的云台PTZ控制,控制类型:上"up",下"down",左"left",右"right",左上"leftup",左下"leftdown",右上"rightup",右下"rightdown",镜头近"zoomin",镜头远"zoomout", 焦距远"focusfar",焦距近"focusnear", 设置预置位"setpos",调预置位"callpos"     18、支持历史视频的查询和历史视频的点播控制     19、支持对国标设备的控制,"record":录像开启和停止-通道id "guard":布放和撤防-报警通道id "reboot":设备重启-设备id "keyfame":强制关键帧-通道id     20、支持对实时视频的图片截图,通过http直接访问图片    21、支持rtmp和hls会话一直保留    22、支持报警消息(设备上线、下线和设备端报警)通过httpclient方式主动通知    23、支持公网和局域网同时存在    24、支持httpserver,接口支持http+json    25、支持设备上线、下线和设备报警通过httpclient通知到指定的httpserver   26、支持http+json设置平台信息  27、支持http+json获取资源组、资源等信息  29、支持国标28181级联上级
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值