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。

界面展示

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

相关推荐
悄悄敲敲敲4 小时前
C++:dfs习题四则
c++·算法·深度优先
安於宿命5 小时前
【Linux】进程间通信——进程池
linux·c++
南郁10 小时前
001-监控你的文件-FSWatch-C++开源库108杰
c++·开源·文件系统·文件监控·fswatch·文件变动信息·libfswatch
linux开发之路11 小时前
C++Linux进阶项目分析-仿写Redis之Qedis
linux·c++·redis·多线程·后端开发
EPSDA11 小时前
Linux线程库与线程库封装
linux·运维·服务器·开发语言·c++
孤独得猿12 小时前
排序算法复习——包括插入排序、希尔排序、冒泡排序、快排(包括霍尔法、挖坑法、快慢指针法)、堆排、选择排序、归并排序等 (代码采用c/c++混编)
c语言·数据结构·c++·笔记·算法·排序算法
编程探索者小陈12 小时前
【C++】智能指针的使用及其原理
开发语言·c++
半桔14 小时前
贪吃蛇解析
c语言·开发语言·数据结构·c++·算法
Pan_peter14 小时前
零基础学QT、C++(一)安装QT
c++·qt
万能的小裴同学14 小时前
MFC 自定义十六进制显示控件
开发语言·c++·mfc