GB28181学习(八)——历史视音频的回放

要求

  • 采用SIP协议实现会话;
  • 采用SIP扩展协议INFO方法的消息体携带视音频回放控制命令;
  • 采用RTP/RTCP实现媒体传输;
  • 媒体回放控制命令引用MANSRTSP协议中的PLAY、PAUSE、TEARDOWN的请求消息和应答消息;
  • 媒体流接收者可为SIP客户端、SIP设备(如视频解码器),媒体流发送者可为SIP设备、网关、媒体服务器;
  • 应符合媒体流保活机制;

流程

录像回放的流程与实时点播类似,主要区别为INVITE请求时xml格式有差异:

  • 实时点播

关于实时点播可查看:

实时点播(信令处理):https://blog.csdn.net/www_dong/article/details/132950064

实时点播(数据处理):https://blog.csdn.net/www_dong/article/details/133581370

注意:

  • "t=0 0"中开始时间和结束时间均为0表示实时点播
  • "s=Play"
c++ 复制代码
static std::string CreateRealStreamSDP(const GB28181MediaContext& mediaContext)
{
    char str[500] = { 0 };
    pj_ansi_snprintf(str, 500,
                     "v=0\n"
                     "o=%s 0 0 IN IP4 %s\n"
                     "s=Play\n"
                     "c=IN IP4 %s\n"
                     "t=0 0\n"
                     "m=video %d RTP/AVP 96 98 97\n"
                     "a=recvonly\n"
                     "a=rtpmap:96 PS/90000\n"
                     "a=rtpmap:98 H264/90000\n"
                     "a=rtpmap:97 MPEG4/90000\n"
                     "y=001\n",
                     mediaContext.GetDeviceId().c_str(),
                     mediaContext.GetRecvAddress().c_str(),
                     mediaContext.GetRecvAddress().c_str(),
                     mediaContext.GetRecvPort()
                    );
    return str;
}
  • 录像回放

注意:

  • "t=%lld %lld"中开始时间和结束时间为点播的开始时间和结束时间
  • "s=Playback"
c++ 复制代码
static std::string CreatePlayBackSDP(const GB28181MediaContext& mediaContext)
{
    char str[500] = { 0 };
    pj_ansi_snprintf(str, 500,
                     "v=0\n"
                     "o=%s 0 0 IN IP4 %s\n"
                     "s=Playback\n"
                     "c=IN IP4 %s\n"
                     "t=%lld %lld\n"
                     "m=video %d RTP/AVP 96 98 97\n"
                     "a=recvonly\n"
                     "a=rtpmap:96 PS/90000\n"
                     "a=rtpmap:98 H264/90000\n"
                     "a=rtpmap:97 MPEG4/90000\n"
                     "y=001\n",
                     mediaContext.GetDeviceId().c_str(),
                     mediaContext.GetRecvAddress().c_str(),
                     mediaContext.GetRecvAddress().c_str(),
                     mediaContext.GetPBStartTime(),
                     mediaContext.GetPBEndTime(),
                     mediaContext.GetRecvPort()
                    );
    return str;
}

抓包

查看历史文件成功后,选中某一条记录,开始录像回放。

  • 发送INVITE请求(107--->111)
bash 复制代码
INVITE sip:xxx@192.168.0.111:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.107:5060;rport;branch=xxx
Max-Forwards: 70
From: sip:xxx@192.168.0.107;tag=xx
To: sip:xxx@192.168.0.111
Contact: <sip:xxx@192.168.0.107:5060>
Call-ID: xxx
CSeq: xx INVITE
Allow: INVITE, ACK, BYE, CANCEL, UPDATE, PRACK  # 支持的方法
Supported: 100rel
Subject: xxx:xx,xxx:xx
Content-Type: application/sdp
Content-Length:   233

v=0
o=xxx 0 0 IN IP4 192.168.0.107
s=Playback                  # 请求方法 
c=IN IP4 192.168.0.107
t=1697264152 1697266715     # 请求的开始时间和结束时间
m=video 36000 RTP/AVP 96 98 97
a=recvonly
a=rtpmap:96 PS/90000
a=rtpmap:98 H264/90000
a=rtpmap:97 MPEG4/90000
y=0100000001
  • 接收INVITE请求响应(111--->107)
bash 复制代码
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.0.107:5060;rport=5060;branch=xxx
From: <sip:xxx@192.168.0.107>;tag=xxx
To: <sip:xxx@192.168.0.111>
Call-ID: xxx
CSeq: 26500 INVITE
User-Agent: IP Camera
Content-Length: 0
  • 接收INVITE响应(111--->107)
bash 复制代码
# 忽略头信息
...

v=0
o=xxx 1080 1080 IN IP4 192.168.0.111
s=Playback
c=IN IP4 192.168.0.111
t=0 0
m=video 15060 RTP/AVP 96
a=sendonly
a=rtpmap:96 PS/90000   # 为PS流
a=filesize:0
y=0100000001
  • INVITE响应返回(107--->111)
bash 复制代码
ACK sip:xxx@192.168.0.111:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.107:5060;rport;branch=xxx
Max-Forwards: 70
From: sip:xxx@192.168.0.107;tag=xxx
To: sip:xxx@192.168.0.111;tag=xx
Call-ID: xx
CSeq: 26500 ACK
Content-Length:  0
  • 接收数据(111--->107)

设备端以RTP协议方式发送数据,数据的封装格式为PS。

界面展示

历史视音频文件查询成功后,选中一条记录,右键选择录像回放,即可弹窗显示录像数据。

相关推荐
汉克老师9 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者9 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
天若有情67310 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_1998868710 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao173383710 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
shada11 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
别动我齐刘海12 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人
朝朝辞暮i13 小时前
C++第 2 课
c++
代码中介商13 小时前
C++ 预约系统实战(三):服务端实现——libevent 事件驱动与业务路由
c++·json·c/s
布莱克60514 小时前
C++中的内存分区详解
c++