Qt/C++编写GB28181服务/前后端分离/定义一套交互协议/视频点播/录像回放和控制/警情通知

一、前言说明

之前已经实现了GB28181服务端程序,为了方便调试使用,直接是做成的一个程序,可以直接在界面上看到连接上来的设备,双击通道查看实时视频,选择时间范围录像回放和下载。随着用户的增多,现在有了新的需求,而且也是刚需,那就是把这个做成服务后台运行,定义一套交互协议,可以是tcp或者http或者mqtt,然后通过协议获取在线设备信息,点播视频,录像回放,切换回放进度,倍速回放,警情上报等,这样的话相当于暴露给第三方使用,至于第三方用Qt还是VB或者C#或者其他网页的,都可以都支持,视频点播后的流推到了流媒体服务程序,会分发成rtsp、rtmp、http、webrtc等格式,网页上可以选择flv或者webrtc来播放,客户端CS架构的可以直接播放rtsp这种,这样受众就非常多,拓展了兼容性,而且程序直接互不干扰,服务端这边有改动和升级,完全不影响请求端。这个思路很好,按照这个模式走下去,后面视频监控系统估计也要定义一套交互协议,尤其是和AI交互。

二、效果图



三、相关地址

  1. 国内站点:https://gitee.com/feiyangqingyun
  2. 国际站点:https://github.com/feiyangqingyun
  3. 个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
  4. 文件地址: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. 支持语音对讲功能,可以直接在视频窗体的悬浮条上单击语音对讲按钮,再次单击关闭对讲,对讲期间悬浮条常驻显示。
  16. 支持设备布防撤防,布防后警情信息会主动上报。
  17. 国标服务同时支持udp和tcp方式,可选只监听一种或者两种都监听,tcp方式自动处理粘包问题。
  18. 国标拉流同时支持udp、tcp被动、tcp主动三种方式,每个通道都可以自由选择何种拉流方式。
  19. 内置拉流端口池,每次拉流从中取出一个,关闭流自动回收端口号,重复利用。
  20. 收流端口自动纠错,自动跳过被占用的端口,不会出现端口占用导致收流失败的情况。
  21. 支持三种取流方式自动检测离线重连,检测到离线后,自动重启点播拉流整个流程。
  22. 录像文件回放,上一个完成后自动切换到下一个继续回放,直到所有回放完成。支持高达8倍速回放。
  23. 视频播放自适应硬解码,极低资源占用,实时性极好,带悬浮条显示视频流信息,可以直接在悬浮条单击按钮保存录像文件到本地。
  24. 支持几千路国标消息交互并发,实时视频流支持64路同时显示,可以拓展更多路数。
  25. 支持阿里云等云服务器,可以分别设置内网监听地址和外网访问地址,一般云服务器上是监听地址用内网,对外访问用外网地址。
  26. 支持视频分发,也就是推流,视频通道打开后可以自动推流到流媒体服务器,其他需要的地方拉流即可,支持rtsp、rtmp、hls、webrtc等方式拉流。
  27. 支持注册重定向,方便做负载均衡和区域化部署,这样可以支持几十万个设备连接都没问题。
  28. 支持图像抓拍,可以设置抓拍最多10张图片,可设置抓拍间隔,抓拍到的图片会通过信号通知。
  29. 实时预览和录像回放都支持推流,推流支持叠加文字和图片水印以及各种ffmpeg支持的滤镜效果,支持多个水印同时叠加。
  30. 同时支持gb28181-2011、gb28181-2016、gb28181-2022以及后续可能的所有协议版本。
  31. SIP解析和交互采用纯Qt底层代码实现,udp/tcp通信交互,祖传原创代码解析,不依赖任何第三方。
  32. 代码量少,gb28181交互部分共几千行代码,注释详细,接口友好,使用极其简单,提供非常详细的使用示例。
  33. 支持海康、大华、宇视、华为、天地伟业等所有国标设备,包括一些没有ssrc的设备。
  34. 支持所有Qt版本和编译器以及操作系统,包括但不限于win、linux、mac、android、嵌入式linux、树莓派香橙派、国产os等。

五、通信协议

1 协议说明

  1. 本程序作为服务端,同时支持tcp、websocket、http、mqtt等多种模式。
  2. tcp模式是本地监听端口,连接上线后进行数据交互。
  3. websocket模式是本地监听websocketserver端口,连接上线后进行数据交互。
  4. http采用post请求,其实和tcp类似,只不过加了http请求头,方便网页中发送对应的请求进行应答。
  5. mqtt需要专门的mqtt服务做中转,服务端这边订阅固定的request主题,客户端所有数据发往这个request主题,请求数据中带有response指令,用于告知服务端应答数据发往哪个主题,相当于单独的主题专门用于应答。
  6. mqtt服务端这边的消息通知,主动发送到message主题,意味着客户端只要订阅这个主题,可以收到主动发送的设备信息变化、警情通知等信息。
  7. 为了区分不同的mqtt客户端,还可以在response主题加上后缀,用以区分。比如response/device1、response/device2。客户端这边只要监听自身的应答主题即可。
  8. 数据格式采用标准json数据格式,以便统一解析,也方便网页这边请求解析。
  9. 数据体中有对应type字段,区分请求的什么内容,根据不同的内容作出不同的应答。
  10. 每一条发送的指令,都带有唯一的一个uuid,用于区分是哪个发送的指令,应答指令中的uuid必须和发送的uuid完全一致。

2 特别说明

  1. tcp默认监听9001端口。
  2. websocketserver默认监听9002端口,地址ws://127.0.0.1:9002。
  3. http默认监听9003端口,地址http://127.0.0.1:9003
  4. mqtt默认通信端口1883,地址mqtt://127.0.0.1:1883。
  5. tcp和websocket模式需要心跳协议来交互,用于判断客户端的离线。
  6. mqtt模式在发送数据中需要额外带上response字段,方便服务端应答。

心跳协议:

cpp 复制代码
//发送心跳:客户端-》服务端
{
    "type": "heartBeat",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

//心跳应答:服务端-》客户端
{
    "type": "heartBeat",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

应答主题:

cpp 复制代码
//发送请求:客户端-》服务端
{
    "type": "xxx",
    "response": "response/device1",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

3 服务控制

cpp 复制代码
//启动国标服务:客户端-》服务端
{
    "type": "startServer",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"    
}

//执行结果应答:服务端-》客户端
{
    "type": "startServer",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

//停止国标服务:客户端-》服务端
{
    "type": "stopServer",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"    
}

//执行结果应答:服务端-》客户端
{
    "type": "stopServer",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

字段说明:

  1. 收到启动服务指令,如果服务运行中,会先停止服务再启动服务,相当于重启服务。
  2. 后面去掉了执行动作,改成了下发新的配置参数后,由服务器程序本身重启去应用新的配置。也就是不再支持动态指令控制服务的启动和停止。

4 配置参数

cpp 复制代码
//读取配置参数:客户端-》服务端
{
    "type": "getConfig",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

//返回配置参数:服务端-》客户端
{
    "type": "getConfig",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": {
        "serverId": "34020000002000000001",
        "serverRealm": "3402000000",
        "serverHost": "192.168.0.110",
        "serverIp": "192.168.0.110",
        "serverPort": 15060,
        "serverPwd": "12345678",
        "snapPort": 6930,
        "queryInterval": 0,
        "minPort": 6900,
        "maxPort": 7900,
        "checkInterval": 0,
        "listenMode": 2,
        "transmitMode": 0
    }
}

//写入配置参数:客户端-》服务端
{
    "type": "setConfig",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "config": {
        "serverId": "34020000002000000001",
        "serverRealm": "3402000000",
        "serverHost": "192.168.0.110",
        "serverIp": "192.168.0.110",
        "serverPort": 15060,
        "serverPwd": "12345678",
        "snapPort": 6930,
        "queryInterval": 0,
        "minPort": 6900,
        "maxPort": 7900,
        "checkInterval": 0,
        "listenMode": 2,
        "transmitMode": 0
    }
}

//写入参数应答:服务端-》客户端
{
    "type": "setConfig",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

字段说明:

  1. 国标编码:serverId,对应设备端填的sip服务器编号,固定长度,具体编码规则按照国标文档约定来。
  2. 国标区域:serverRealm,对应设备端填的sip域。
  3. 外网地址:serverHost,在云服务器上,对外提供公网访问的地址。在本地一般外网地址和监听网卡地址是相同的。
  4. 监听网卡:serverIp,本地监听地址,填0.0.0.0表示监听所有。
  5. 监听端口:serverPort,本地监听的端口号,对应设备端填的sip服务器端口。
  6. 认证密码:serverPwd,默认为空表示不认证,也就是设备注册注销期间不做密码认证。对应设备端的注册密码。设置了密码后,还会对国标编码的正确性进行验证,比如设备传过来的注册指令带的国标编码不正确则会拒绝注册。
  7. 抓图端口:snapPort,gb28181-2022版本开始支持抓图,对应服务端这边要提供端口进行抓图上报。
  8. 查询间隔:queryInterval,定期查询通道信息,默认0表示不启用。
  9. 最小端口:minPort,提供一个端口范围,用于点播拉流使用。
  10. 最大端口:maxPort,提供一个端口范围,用于点播拉流使用。
  11. 离线检测:checkInterval,实时监测在线设备视频画面是否在线,不在线则会自动重连,默认0表示不启用。
  12. 监听模式:listenMode,0=仅udp,表示只监听udp通道,1=仅tcp,表示只监听tcp通道,2=udp和tcp,表示两者都监听,默认两者都监听。
  13. 传输模式:transmitMode,对应拉流的时候数据的传输模式,0=udp,1=tcp被动,2=tcp主动。

5 设备列表

cpp 复制代码
//获取设备列表:客户端-》服务端
{
    "type": "getDeviceInfo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

//返回设备列表:服务端-》客户端
{
    "type": "getDeviceInfo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": [
        {
            "deviceId": "34020000001320000001",
            "deviceName": "市场部",
            "deviceIp": "192.168.0.64",
            "devicePort": 5060,
            "online": true,
            "channels": [
                {
                    "channelId": "34020000001310000001",
                    "channelName": "市场部-01",
                    "online": true
                },{
                    "channelId": "34020000001310000002",
                    "channelName": "市场部-02",
                    "online": false
                }
            ]
        },{
            "deviceId": "34020000001320000002",
            "deviceName": "研发部",
            "deviceIp": "192.168.0.65",
            "devicePort": 5060,
            "online": true,
            "channels": [
                {
                    "channelId": "34020000001310000008",
                    "channelName": "研发部-01",
                    "online": true
                }
            ]
        }
    ]
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 设备名称:deviceName,对应设备的别名,一般是中文,方便理解。
  3. 设备地址:deviceIp,设备对应的IP地址。
  4. 设备端口:devicePort,设备国标通信用的端口。
  5. 设备状态:online,设备在线状态,true表示在线。
  6. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  7. 通道名称:channelName,对应通道的别名,一般是中文,方便理解。
  8. 通道状态:online,通道在线状态,true表示在线。
  9. 特别说明:每次最多同时返回10个设备,超过会拆分成多个返回数据,对应uuid相同。
  10. 其他说明:设备信息中后续可能会陆续增加一些其他的信息,比如心跳时间等。

6 在线通道

cpp 复制代码
//获取在线通道:客户端-》服务端
{
    "type": "getLiveInfo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

//返回在线通道:服务端-》客户端
{
    "type": "getLiveInfo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": [
        {
            "deviceId": "34020000001320000001",
            "channelId": "34020000001310000001"
        },{
            "deviceId": "34020000001320000001",
            "channelId": "34020000001310000002"
        }
    ]
}

字段说明:

  1. 设备编码:deviceId,发送和应答的参数都需要带上。
  2. 通道编码:channelId,发送和应答的参数都需要带上。
  3. 特别说明:会将所有已经点播好的通道的信息上报。一般在客户端首次运行的时候,可以获取下哪些已经处于点播状态。

7 视频地址

cpp 复制代码
//获取视频地址:客户端-》服务端
{
    "type": "getUrl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001"
}

//返回视频地址:服务端-》客户端
{
    "type": "getUrl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "directPlay": true,
    "result": {
        "rtsp": "rtsp://192.168.0.110:8554/stream/34020000001320000001_34020000001310000001",
        "rtmp": "rtmp://192.168.0.110:5541/stream/34020000001320000001_34020000001310000001",
        "hls": "http://192.168.0.110:8888/stream/34020000001320000001_34020000001310000001",
        "webrtc": "http://192.168.0.110:8889/stream/34020000001320000001_34020000001310000001"
    }
}

字段说明:

  1. 设备编码:deviceId,发送和应答的参数都需要带上。
  2. 通道编码:channelId,发送和应答的参数都需要带上。
  3. 直接播放:directPlay,true的话表示对应的hls和webrtc地址,可以直接在网页浏览器中嵌入到一个iframe中播放,对应地址也可以直接输入到地址栏然后回车访问,不需要依赖特定的js播放器。false的话就需要特定的支持hls或者flv格式数据的播放器,比如liveplayer.js。
  4. 发送说明:发送的时候,需要指定设备编码和通道编码,也就是唯一确定一个通道。应答的时候,会带上设备编码和通道编码信息。
  5. 其他说明:一般来说,网页上只支持hls、flv、webrtc的播放,rtsp和rtmp都是在电脑播放器上播放器,比如vlc播放器,网页上并不支持直接播放rtsp之类的流。

8 云台控制

cpp 复制代码
//云台右转移动:客户端-》服务端
{
    "type": "ptzControl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "ptzType": "right",
    "ptzSpeed": 150
}

//云台左上移动:客户端-》服务端
{
    "type": "ptzControl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "ptzType": "leftUp",
    "ptzSpeed": 150
}

//执行结果应答:服务端-》客户端
{
    "type": "ptzControl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 控制类型:ptzType,云台移动的类型,stop-停止移动、right-往右移动、rightUp-右上移动、up-往上移动、leftUp-左上移动、left-往左移动、leftDown-左下移动、down-往下移动、rightDown-右下移动、zoomIn-镜头放大、zoomOut-镜头缩小、irisIn-光圈放大,irisOut-光圈缩小、focusIn-镜头聚焦、focusOut-镜头放焦。
  4. 移动速度:ptzSpeed,云台移动的速度,范围值1-255,值越大速度越快。
  5. 应答结果:result,ok表示收到了指令,并不是执行完成。

9 预置位置

cpp 复制代码
//添加预置位:客户端-》服务端
{
    "type": "addPreset",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "presetId": 1
}

//调用预置位:客户端-》服务端
{
    "type": "setPreset",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "presetId": 1
}

//删除预置位:客户端-》服务端
{
    "type": "delPreset",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",   
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "presetId": 1
}

//获取预置位:客户端-》服务端
{
    "type": "getPreset",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001"
}

//执行结果应答:服务端-》客户端
{
    "type": "xxxxx",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 预置位编号:presetId,预置位的唯一编号。添加删除和调用预置位需要带上这个参数。
  4. 预置位名称:presetName,对应预置位的别名,一般是中文,方便理解。
  5. 特别说明:预置位信息返回通过异步通知返回。

10 视频点播

cpp 复制代码
//开始点播视频:客户端-》服务端
{
    "type": "openVideo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "enableAudio": false
}

//点播视频返回:服务端-》客户端
{
    "type": "openVideo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "directPlay": true,
    "result": {
        "rtsp": "rtsp://192.168.0.110:8554/stream/34020000001320000001_34020000001310000001",
        "rtmp": "rtmp://192.168.0.110:5541/stream/34020000001320000001_34020000001310000001",
        "hls": "http://192.168.0.110:8888/stream/34020000001320000001_34020000001310000001",
        "webrtc": "http://192.168.0.110:8889/stream/34020000001320000001_34020000001310000001"
    }
}

//关闭点播视频:客户端-》服务端
{
    "type": "closeVideo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 启用音频:enableAudio,点播通道的时候是否开启声音,很多场景可能不需要声音。
  4. 点播返回:点播成功后,会返回对应视频流的地址,可以按需选择需要的地址进行播放。
  5. 特别说明:如果已经处于点播状态,则不会重新点播,直接复用。

11 录像查询

cpp 复制代码
//查询录像文件:客户端-》服务端
{
    "type": "selectRecord",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "startTime": "2025-10-28T00:00:00",
    "endTime": "2025-10-28T23:59:59"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 开始时间:startTime,录像文件的开始时间。
  4. 结束时间:endTime,录像文件的结束时间。
  5. 特别说明:查询时间范围建议一天内,查询结果返回通过异步通知返回。

12 录像回放

cpp 复制代码
//回放录像文件:客户端-》服务端
{
    "type": "openVideo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "enableAudio": false,
    "startTime": "2025-10-10T18:00:00",
    "endTime": "2025-10-10T19:00:00"
}

//回放录像应答:服务端-》客户端
{
    "type": "openVideo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "directPlay": true,
    "result": {
        "rtsp": "rtsp://192.168.0.110:8554/stream/34020000001320000001_34020000001310000001",
        "rtmp": "rtmp://192.168.0.110:5541/stream/34020000001320000001_34020000001310000001",
        "hls": "http://192.168.0.110:8888/stream/34020000001320000001_34020000001310000001",
        "webrtc": "http://192.168.0.110:8889/stream/34020000001320000001_34020000001310000001"
    }
}

//关闭录像回放:客户端-》服务端
{
    "type": "closeVideo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 启用音频:enableAudio,点播通道的时候是否开启声音,很多场景可能不需要声音。
  4. 点播返回:点播成功后,会返回对应视频流的地址,可以按需选择需要的地址进行播放。
  5. 其他说明:其实录像回放和视频点播一样,只不过多了开始时间和结束时间的参数。

13 回放控制

cpp 复制代码
//执行回放控制:客户端-》服务端
{
    "type": "playControl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "controlType": "play",
    "controlValue": 0
}

//执行结果应答:服务端-》客户端
{
    "type": "playControl",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 控制类型:controlType,play-继续播放、pause-暂停播放、scale-倍速播放、position-切换进度。
  4. 控制数据:controlValue,倍速播放这个值对应倍速值,切换进度对应进度值,对应当前文件从开始到进度的秒数值,和28181规范一样。

14 录像下载

cpp 复制代码
//请求录像下载:客户端-》服务端
{
    "type": "downRecord",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "enableAudio": false,
    "startTime": "2025-10-10T18:00:00",
    "endTime": "2025-10-10T19:00:00",
    "downSpeed": 4
}

//执行结果应答:服务端-》客户端
{
    "type": "downRecord",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "result": "ok"
}

//查询下载进度:客户端-》服务端
{
    "type": "downProgress",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001"
}

//返回下载进度:服务端-》客户端
{
    "type": "downProgress",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "progress": 6000
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 开始时间:startTime,录像文件的开始时间。
  4. 结束时间:endTime,录像文件的结束时间。
  5. 启用音频:enableAudio,点播通道的时候是否开启声音,很多场景可能不需要声音。
  6. 下载速度:downSpeed,默认1,可以到8倍速,前提是要设备支持。
  7. 下载进度:progress,下载进度pts值,放大了10倍,拿到这个值要除以10才是真实进度。
  8. 保存文件:filePath,录像文件保存的相对路径,可以通过这个路径自行访问文件进行下载。
  9. 特别说明:同一个通道只能同时存在一个文件下载,下载完成通知在异步通知返回。

15 消息通知

cpp 复制代码
//设备信息变更:服务端-》客户端
{
    "type": "deviceChange",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693"
}

//警情信息通知:服务端-》客户端
{
    "type": "alarmInfo",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "alarmType": 1-255,
    "alarmContent": "视频异常检测报警",
    "alarmTime": "2025-04-22T11:26:02"
}

//文件下载完成:服务端-》客户端
{
    "type": "downFinsh",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "fileSize": 1024000,
    "filePath": "/record/2025-10-10-18-18-18_34020000001320000001_34020000001310000001.mp4"
}

字段说明:

  1. 设备编码:deviceId,对应设备的国标编码,在整个系统中唯一。
  2. 通道编码:channelId,对应通道的国标编码,在同一个设备下唯一。
  3. 报警类型:alarmType,报警对应的类型,1-255,具体参考对照表。
  4. 报警内容:alarmContent,报警具体对应的内容,中文内容。
  5. 报警时间:alarmTime,报警触发的时间。
  6. 其他说明:设备信息变更后,可以重新读取所有设备信息,服务端可能也可以主动发送所有设备信息。

16 异步通知

cpp 复制代码
//返回预置位:服务端-》客户端
{
    "type": "getPreset",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "result": [
        {
            "presetId": 1,
            "presetName": "预置位1"
        },{
            "presetId": 2,
            "presetName": "预置位2"
        }
    ]
}

//返回录像文件:服务端-》客户端
{
    "type": "selectRecord",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",    
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "result": [
        {
            "startTime": "2025-10-10T18:00:00",
            "endTime": "2025-10-10T18:30:00"
        },{
            "startTime": "2025-10-10T18:30:00",
            "endTime": "2025-10-10T19:00:00"
        }
    ]
}

//文件下载完成:服务端-》客户端
{
    "type": "downFinsh",
    "uuid": "c7b91a2dbb2f4fe984d7d5fba11a7693",
    "deviceId": "34020000001320000001",
    "channelId": "34020000001310000001",
    "fileSize": 1024000,
    "filePath": "/record/2025-10-10-18-18-18_34020000001320000001_34020000001310000001.mp4"
}
相关推荐
m0_748248022 小时前
C++与C#布尔类型深度解析:从语言设计到跨平台互操作
c++·stm32·c#
虾米Life3 小时前
基于微服务脚手架的视频点播系统 (仿B站) [客户端] -1
c++·qt·微服务·架构
落羽的落羽3 小时前
【C++】现代C++的新特性constexpr,及其在C++14、C++17、C++20中的进化
linux·c++·人工智能·学习·机器学习·c++20·c++40周年
CAU界编程小白4 小时前
数据结构系列之十大排序算法
数据结构·c++·算法·排序算法
头发还没掉光光4 小时前
Linux网络初始及网络通信基本原理
linux·运维·开发语言·网络·c++
m0_748248025 小时前
揭开 C++ vector 底层面纱:从三指针模型到手写完整实现
开发语言·c++·算法
海盗猫鸥5 小时前
「C++」string类(2)常用接口
开发语言·c++
序属秋秋秋5 小时前
《Linux系统编程之开发工具》【实战:倒计时 + 进度条】
linux·运维·服务器·c语言·c++·ubuntu·系统编程
yugi9878385 小时前
基于Qt框架开发多功能视频播放器
开发语言·qt