找回密码
 立即注册
收起左侧

Qt/C++开发监控GB28181系统/云台控制/获取预置位信息/添加删...

0
回复
59
查看
[复制链接]
累计签到:7 天
连续签到:1 天
来源: 2025-5-2 10:54:19 显示全部楼层 |阅读模式

## 一、前言
之前用onvif已经完美实现了设备的云台控制和预置位的功能,这个基础功能在监控系统中是使用频率很高的,所有gb28181肯定也提供了这样的功能,很多人以为是通过包含xml数据,对应节点指定对应的动作来实现,其实不是的,是类似于早期模拟设备的云台的串口协议中的控制指令,16进制格式的数据,一个个字节表示对应的含义,这个在国标文档中写的非常的详细,按照那个规则来肯定错不了,上下左右移动有个字节位是固定的数据,所以程序这边只需要根据要操作的动作填充对应位的数据即可。

和云台控制一起的还有镜头放大缩小、光圈放大缩小、镜头聚焦和放焦,这些也都是一样的规则,奇怪的是,预置位的添加删除修改调用也都是这个规则,之前还以为是单独的xml格式的数据或者指令。不过遗憾的是预置位的信息并不支持名称的修改,而onvif那边是可以的,有时候希望给预置位改成一个中文的名字方便调用查阅等,不知道后续的国标协议会不会增加进去,个人觉得还是要支持比较好。

```cpp
//云台控制:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK801c1bb8b2234e2e94be74f0087e28f5
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1022
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: 6822f48163704effb5b58d7031eba9f4
CSeq: 23 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 251
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>10022</SN>
  <DeviceID>34020000001310000001</DeviceID>
  <PTZCmd>A50F01029600004D</PTZCmd>
  <Info><ControlPriority>5</ControlPriority></Info>
</Control>

//控制应答:设备端-》服务端
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK801c1bb8b2234e2e94be74f0087e28f5
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1022
To: <sip:34020000001320000002@192.168.0.64:5060>;tag=1060605518
Call-ID: 6822f48163704effb5b58d7031eba9f4
CSeq: 23 MESSAGE
User-Agent: IP Camera
Content-Length: 0

//停止云台:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK3cb5f960d94549888269c12f4ed29c9e
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1023
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: f3124084767d48909decda7579e3f96b
CSeq: 24 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 251
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>10023</SN>
  <DeviceID>34020000001310000001</DeviceID>
  <PTZCmd>A50F0100000000B5</PTZCmd>
  <Info><ControlPriority>5</ControlPriority></Info>
</Control>

//停止应答:设备端-》服务端
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK3cb5f960d94549888269c12f4ed29c9e
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1023
To: <sip:34020000001320000002@192.168.0.64:5060>;tag=1071996623
Call-ID: f3124084767d48909decda7579e3f96b
CSeq: 24 MESSAGE
User-Agent: IP Camera
Content-Length: 0

//查询预置位:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK5f11d64dadd7466cb06011e8971b788d
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1024
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: aac3afc576894717a72ed58030479bcb
CSeq: 25 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 155
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Query>
  <CmdType>PresetQuery</CmdType>
  <SN>10024</SN>
  <DeviceID>34020000001310000001</DeviceID>
</Query>

//返回预置位:设备端-》服务端
MESSAGE sip:34020000002000000001@3402000000 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.64:5060;rport;branch=z9hG4bK1149716366
From: <sip:34020000001320000002@3402000000>;tag=2001348774
To: <sip:34020000002000000001@3402000000>
Call-ID: 360379917
CSeq: 20 MESSAGE
Content-Type: Application/MANSCDP+xml
Max-Forwards: 70
User-Agent: IP Camera
Content-Length:   258

<?xml version="1.0" encoding="GB2312"?>
<Response>
<CmdType>PresetQuery</CmdType>
<SN>10024</SN>
<DeviceID>34020000001310000001</DeviceID>
<PresetList Num="1">
<Item>
<PresetID>1</PresetID>
<PresetName>预置点 1</PresetName>
</Item>
</PresetList>
</Response>

//添加预置位:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK76caaff468eb43ca9818e6fb38cfd057
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1025
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: a01a7be3ba6b4214ac0755d92d0096c5
CSeq: 26 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 251
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>10025</SN>
  <DeviceID>34020000001310000001</DeviceID>
  <PTZCmd>A50F018100020038</PTZCmd>
  <Info><ControlPriority>5</ControlPriority></Info>
</Control>

//删除预置位:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK9259fa44edce4797a69c4c58aa408d2c
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1027
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: 1bc5c4f7629b436ca66865c112ba2d47
CSeq: 28 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 251
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>10027</SN>
  <DeviceID>34020000001310000001</DeviceID>
  <PTZCmd>A50F01830002003A</PTZCmd>
  <Info><ControlPriority>5</ControlPriority></Info>
</Control>

//修改预置位:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bKb968612c929f488bb3f105b907a61eba
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1031
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: 37bfa9cea6564707af579159d662db4a
CSeq: 32 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 251
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>10031</SN>
  <DeviceID>34020000001310000001</DeviceID>
  <PTZCmd>A50F018100020038</PTZCmd>
  <Info><ControlPriority>5</ControlPriority></Info>
</Control>

//调用预置位:服务端-》设备端
MESSAGE sip:34020000001320000002@192.168.0.64:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.110:15060;branch=z3hG9bK3a2b16dffa134a25ad7158ef07ad8b07
From: <sip:34020000002000000001@192.168.0.110:15060>;tag=1032
To: <sip:34020000001320000002@192.168.0.64:5060>
Call-ID: 22431fe05dec47cbb789617b38caef58
CSeq: 33 MESSAGE
User-Agent: wx_feiyangqingyun
Max-Forwards: 70
Content-Length: 251
Content-Type: application/MANSCDP+xml
Contact: <sip:34020000002000000001@192.168.0.110:15060>

<?xml version="1.0" encoding="GB2312"?>
<Control>
  <CmdType>DeviceControl</CmdType>
  <SN>10032</SN>
  <DeviceID>34020000001310000001</DeviceID>
  <PTZCmd>A50F018200020039</PTZCmd>
  <Info><ControlPriority>5</ControlPriority></Info>
</Control>
```

## 二、效果图


## 三、相关地址
1. 国内站点:[https://gitee.com/feiyangqingyun](https://gitee.com/feiyangqingyun)
2. 国际站点:[https://github.com/feiyangqingyun](https://github.com/feiyangqingyun)
3. 个人作品:[https://blog.csdn.net/feiyangqingyun/article/details/97565652](https://blog.csdn.net/feiyangqingyun/article/details/97565652)
4. 文件地址:[https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g](https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g) 提取码:01jf 文件名:bin_video_gb28181。

## 四、功能特点
1. 支持设备注册、注销、心跳、校时、注册认证、注销认证等。
2. 设备上线后可以手动获取设备状态、设备信息、配置信息、预置位信息等。
3. 设备上线后自动获取设备通道信息,包括中文通道名称。识别到通道上线离线变化,会重新获取该设备的所有通道信息。
4. 支持视频点播,可以分别点播主码流和子码流,内置rtp解包线程,解包后发给视频播放组件解码播放。
5. 每个设备每个通道支持点播多个视频,通过ssrc区分,支持共用端口和不同端口收流。
6. 支持对某个设备下面所有通道、某个通道、某个通道对应的某个流分别关闭。
7. 支持录像文件查询和回放,回放控制支持暂停播放、继续播放、倍速播放、切换播放进度。
8. 支持录像文件下载,支持倍速比如8倍速下载,可同时多线程批量下载。
9. 回放和下载同时支持IPC和NVR,比如摄像头自带的SD存储卡录像文件回放,NVR上的硬盘录像文件回放。
10. 支持云台控制,向上、向下、向左、向右、左上、右上、左下、右下方位移动,镜头放大缩小,光圈放大缩小,镜头聚焦放焦。
11. 支持预置位信息的查询、调用、添加、修改、删除等操作。
12. 自动目录订阅功能,通道上线下线都有对应的信号通知。
13. 内置定时读取通道信息机制,以保证通道信息是最新的,比如有些NVR是不断更新的通道信息。
14. 支持警情订阅,各种警情事件比如运动目标检测报警、入侵检测报警、徘徊检测报警等自动上报。
15. 国标服务同时支持udp和tcp方式,可选只监听一种或者两种都监听,tcp方式自动处理粘包问题。
16. 国标拉流同时支持udp、tcp被动、tcp主动三种方式,每个通道都可以自由选择何种拉流方式。
17. 内置拉流端口池,每次拉流从中取出一个,关闭流自动回收端口号,重复利用。
18. 收流端口自动纠错,自动跳过被占用的端口,不会出现端口占用导致收流失败的情况。
19. 视频播放自适应硬解码,极低资源占用,实时性极好,带悬浮条显示视频流信息,可以直接在悬浮条单击按钮保存录像文件到本地。
20. 支持几千路国标消息交互并发,实时视频流支持64路同时显示,可以拓展更多路数。
21. 支持阿里云等云服务器,可以分别设置内NETJ听地址和外网访问地址,一般云服务器上是监听地址用内网,对外访问用外网地址。
22. 支持视频分发,也就是推流,视频通道打开后可以自动推流到流媒体服务器,其他需要的地方拉流即可,支持rtsp、rtmp、hls、webrtc等方式拉流。
23. 同时支持gb28181-2011、gb28181-2016、gb28181-2022以及后续可能的所有协议版本。
24. SIP解析和交互采用纯Qt底层代码实现,udp/tcp通信交互,祖传原创代码解析,不依赖任何第三方。
25. 代码量少,gb28181交互部分共几千行代码,注释详细,接口友好,使用极其简单,提供非常详细的使用示例。
26. 支持海康、大华、宇视、华为、天地伟业等所有国标设备。
27. 支持所有Qt版本和编译器以及操作系统,包括但不限于win、linux、mac、android、嵌入式linux、树莓派香橙派、国产os等。

## 五、相关代码
```cpp
//具体格式规范在gb28181-2016文档的第79页
//预置位和巡航等操作也是属于云台部分/速度参数就对应的预置位编号
QString GB28181Body::getPtzCmd(PtzType ptzType, quint8 ptzSpeed)
{
    //协议固定数据格式
    QByteArray data;
    data.append(0xA5);
    data.append(0x0F);
    data.append(0x01);
    data.append((char)0x00);
    data.append((char)0x00);
    data.append((char)0x00);
    data.append((char)0x00);
    data.append((char)0x00);

    //不同动作填充对应数据/下面的与运算是为了防止数据越界
    if (ptzType == PtzType_Right) {
        data[3] = 0x01;
        data[4] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_RightUp) {
        data[3] = 0x09;
        data[4] = ptzSpeed & 0xFF;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_Up) {
        data[3] = 0x08;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_LeftUp) {
        data[3] = 0x0A;
        data[4] = ptzSpeed & 0xFF;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_Left) {
        data[3] = 0x02;
        data[4] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_LeftDown) {
        data[3] = 0x06;
        data[4] = ptzSpeed & 0xFF;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_Down) {
        data[3] = 0x04;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_RightDown) {
        data[3] = 0x05;
        data[4] = ptzSpeed & 0xFF;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_ZoomIn) {
        data[3] = 0x10;
        data[6] = (ptzSpeed & 0x0F) << 4;
    } else if (ptzType == PtzType_ZoomOut) {
        data[3] = 0x20;
        data[6] = (ptzSpeed & 0x0F) << 4;
    } else if (ptzType == PtzType_IrisIn) {
        data[3] = 0x44;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_IrisOut) {
        data[3] = 0x48;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_FocusIn) {
        data[3] = 0x41;
        data[4] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_FocusOut) {
        data[3] = 0x42;
        data[4] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_AddPreset) {
        data[3] = 0x81;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_SetPreset) {
        data[3] = 0x82;
        data[5] = ptzSpeed & 0xFF;
    } else if (ptzType == PtzType_DelPreset) {
        data[3] = 0x83;
        data[5] = ptzSpeed & 0xFF;
    }

    //末尾字节是前面字节加起来
    int end = 0;
    int count = data.size();
    for (int i = 0; i < count - 1; ++i) {
        end += data.at(i);
    }

    data[7] = end;
    return QString(data.toHex()).toUpper();
}
```


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了