GB28181学习(十)——视音频文件下载

要求

  • SIP服务器接收到媒体接收者发送的视音频文件下载请求后向媒体流发送者发送媒体文件下载命令,媒体流发送者采用RTP将视频流传输给媒体流接收者,媒体流接收者直接将视频流保存为媒体文件;
  • 媒体流接收者或SIP服务器可通过配置查询等方式获取媒体流发送者支持的下载发送倍速,并在请求的SDP消息体中携带下载倍速;
  • 视音频文件下载宜支持媒体流保活机制;

流程

在这里插入图片描述

录像下载的流程与录像点播、录像回放类似,主要区别为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“
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;
}
  • 录像回放

历史视音频回放:https://blog.csdn.net/www_dong/article/details/133826739

注意:

  • “t=%lld %lld”中开始时间和结束时间为点播的开始时间和结束时间
  • “s=Playback”
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;
}
  • 录像下载

注意:

  • “t=%lld %lld”中开始时间和结束时间为需要下载文件的开始时间和结束时间
  • “s=Download”
  • "a=downloadspeed:8"表示8倍速下载
static std::string CreateSDPForDownload(const GB28181MediaContext& mediaContext){char str[500] = { 0 };pj_ansi_snprintf(str, 500,"v=0\n""o=%s 0 0 IN IP4 %s\n""s=Download\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""a=downloadspeed:%d\n""y=0100000001\n",mediaContext.GetDeviceId().c_str(),mediaContext.GetRecvAddress().c_str(),mediaContext.GetRecvAddress().c_str(),mediaContext.GetDownloadStartTime(),mediaContext.GetDownloadEndTime(),mediaContext.GetRecvPort(),mediaContext.GetDownloadSpeed());return str;}

抓包

在这里插入图片描述

  1. 查询历史视音频文件,查询结果如图所示:

在这里插入图片描述

  1. 选中一条文件记录,右键选择录像下载,弹出如下界面:

在这里插入图片描述

  1. 选择8倍速,点击开始下载,向设备发送下载请求:
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=xxx
To: sip:xxx@192.168.0.111
Contact: <sip:xxx@192.168.0.107:5060>
Call-ID: xxx
CSeq: 15724 INVITE
Allow: SUBSCRIBE, NOTIFY, INVITE, ACK, BYE, CANCEL, UPDATE
Supported: 
Subject: xxx:xx,xxx:xx
Content-Type: application/sdp
Content-Length:   251v=0
o=xxx 0 0 IN IP4 192.168.0.107
s=Download
c=IN IP4 192.168.0.107
t=1697955233 1697958114      # 下载的文件开始时间和结束时间
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
a=downloadspeed:8            # 8倍速下载
y=001
  1. 设备返回下载请求结果:
# 100 Trying
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: 15724 INVITE
User-Agent: IP Camera
Content-Length: 0# 200 OK
SIP/2.0 200 OK
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>;tag=904233038
Call-ID: xxx
CSeq: 15724 INVITE
Contact: <sip:xxx@192.168.0.111:5060>
Content-Type: application/sdp
User-Agent: IP Camera
Content-Length:   198v=0
o=xxx 2131 2131 IN IP4 192.168.0.111
s=Download
c=IN IP4 192.168.0.111
t=0 0
m=video 15060 RTP/AVP 96
a=sendonly
a=rtpmap:96 PS/90000
a=filesize:62224924          # 请求的文件大小
y=001
  1. 接收数据
    在这里插入图片描述

  2. 文件下载结束通知

当接收到MediaStatus命令且NotifyType为121是表示历史媒体文件发送结束。

在这里插入图片描述

抓包如下所示:

MESSAGE sip:xxx@192.168.0.107:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.111:5060;rport;branch=xxx
From: <sip:xxx@192.168.0.111>;tag=xxx
To: <sip:xxx@192.168.0.107>;tag=xxx
Call-ID: xxx
CSeq: 2 MESSAGE
Contact: <sip:xxx@192.168.0.111:5060>
Content-Type: Application/MANSCDP+xml
Max-Forwards: 70
User-Agent: IP Camera
Content-Length:   174<?xml version="1.0" encoding="GB2312"?>
<Notify>
<CmdType>MediaStatus</CmdType>
<SN>151</SN>
<DeviceID>xxx</DeviceID>
<NotifyType>121</NotifyType>
</Notify>

下载的文件如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/114318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Hello Algorithm】暴力递归到动态规划(五)

死亡概率问题 现在给定你三个参数 N M K 怪兽有 N 滴血 等着英雄来砍自己 英雄每一次打击会让怪兽流失 0 ~ M 滴血 概率相同 请求在K次之后 英雄把怪兽砍死的概率 递归版本 面对这个问题 我们首先来想递归函数怎么写 首先是返回值 我们无法直接返回一个概率给上层 所以我…

gRPC之gRPC转换HTTP

1、gRPC转换HTTP 我们通常把RPC用作内部通信&#xff0c;而使用Restful Api进行外部通信。为了避免写两套应用&#xff0c;我们使用grpc- gateway 把gRPC转成HTTP。服务接收到HTTP请求后&#xff0c;grpc-gateway把它转成gRPC进行处理&#xff0c;然后以JSON 形式返回数据。…

Go 语言的垃圾回收机制:自动化内存管理

在编程的世界中&#xff0c;内存管理一直是一个重要的问题。不正确的内存管理可能导致内存泄漏和程序崩溃。Go 语言以其高效的垃圾回收机制而闻名&#xff0c;使开发者从手动内存管理的烦恼中解脱出来。本文将深入探讨Go语言的垃圾回收机制&#xff0c;介绍它的工作原理以及如何…

消息队列 RocketMQ 消息重复消费问题(原因及解决)

目录 1.出现重复消费的原因 2.解决 2.1 数据库插入法 2.2 使用布隆过滤器 2.2.1 添加hutool的依赖 2.2.2 测试生产者 2.2.2 测试消费者 1.出现重复消费的原因 BROADCASTING(广播) 模式下&#xff0c;所有注册的消费者都会消费&#xff0c;而这些消费者通常是集群部署的…

ubuntu20.04下安装nc

前言 nc在网络渗透测试中非常好用&#xff0c;这里的主要记一下Ubuntu20.04中nc的安装 编译安装 第一种方式是自己编译安装&#xff0c;先下载安装包 nc.zip wget http://sourceforge.net/projects/netcat/files/netcat/0.7.1/netcat-0.7.1.tar.gz/download -O netcat-0.7.…

当你学会这项python数据提取神器时,请做好升职准备!

一、什么是 jsonpath ● JsonPath 是一种信息抽取类库&#xff0c;是从 JSON 文档中抽取指定信息的工具&#xff0c;提供多种语言实现版本&#xff0c;包括&#xff1a;JavaScript、Python、PHP 和 Java。 二、特点 ● 只能提取 JSON 格式的数据 ● 提取后的数据类型与原数据…

2023秋招笔试算法Python3题解

诸神缄默不语-个人CSDN博文目录 签两方了&#xff0c;感觉秋招已经结束了&#xff0c;所以发布一下之前写的笔试编程题题解。 不全。可能有些题我会继续补。 不保证能过。 后续依然有可能继续刷算法题&#xff0c;但是就另外专门写博文来解析了。 打码是因为原则上其实是不让公…

国密https访问

前言 现在的SSL的加密算法实际上主要是国际算法&#xff0c;包括JDK&#xff0c;Go等语言也仅支持国际算法加密&#xff08;毕竟是国外开源项目&#xff09;&#xff0c;hash。随着国密算法的普及&#xff0c;比如openssl就支持国密了&#xff0c;还要新版本的Linux内核也开始…

【Python第三方包】实现自动化(pyautogui包)

文章目录 前言一、如何安装pyautogui二、pyautogui鼠标操作2.1 鼠标移动2.2 鼠标点击2.3 拖动鼠标三、键盘操作3.1 按下和释放按键3.2 键盘输入四、截图和图像识别4.1 截图4.2 图像识别总结前言 自动化是现代计算机编程和软件开发中的一个重要概念。通过自动化,我们可以节省时…

解决因d3dx9_30.dll丢失程序无法运行,电脑缺失d3dx9_30.dll报错解决方案

我们的生活和工作都离不开电脑。然而&#xff0c;电脑作为一种复杂的工具&#xff0c;也会出现各种各样的问题。其中&#xff0c;丢失d3dx9_30.dll文件是一个常见的问题。d3dx9_30.dll是DirectX的动态链接库文件&#xff0c;如果丢失或损坏&#xff0c;可能会导致许多软件和游戏…

[论文笔记]GPT-1

引言 今天带来论文Improving Language Understanding by Generative Pre-Training的笔记,它的中文题目为:通过生成式预训练改进语言理解。其实就是GPT的论文。 自然语言理解可以应用于大量NLP任务上,比如文本蕴含、问答、语义相似和文档分类。虽然无标签文本语料是丰富的,…

Js使用ffmpeg在视频中添加png或gif

Js使用ffmpeg在视频中添加png或gif ffmpeg 使用场景是需要在web端对视频进行编辑 添加图片和gif。 注意: 以下所有的使用案例均基于vue3 setup。 同时由于ffmpeg版本不同会导致使用的api不同&#xff0c;使用案例前需要注意ffmpeg版本问题。 如果使用的是0.12需要使用新的…

通讯录和内存动态管理

目录 (通讯录)动态增长版 实现效果 找单身狗 题目 源码 思路 三个内存函数的模拟实现 模拟实现strncpy 模拟实现strncat 模拟实现atoi (通讯录)动态增长版 该版本通讯录在原版的基础上增加了检查容量函数&#xff0c;实现了通讯录的动态…

Linux中的shell编程

shell编程 重定向 cat >temp 输入内容到temp文件中&#xff0c;如果存在temp则覆盖&#xff0c;没有则新建 cat >>temp 追加内容 cat temp1>>temp2 将temp1中的内容追加到temp 命令执行控制符号 ; 一个命令行执行多条语句 命令替换符 1.双引号&#…

插槽的基本使用和作用域插槽

1.编译作用域 父级模板里的所有内容都是在父级作用域中编译的&#xff1b;子模板里的所有内容都是在子作用域中编译的。 即父子组件只能使用各自作用域的数据 2.插槽的后备内容&#xff08;slot中默认配置内容&#xff09; 可以在slot中提前设置一段内容作为默认值&#xf…

数据结构--线性表回顾

目录 线性表 1.定义 2.线性表的基本操作 3.顺序表的定义 3.1顺序表的实现--静态分配 3.2顺序表的实现--动态分配 4顺序表的插入、删除 4.1插入操作的时间复杂度 4.2顺序表的删除操作-时间复杂度 5 顺序表的查找 5.1按位查找 5.2 动态分配的方式 5.3按位查找的时间…

Spark简介

文章目录 一、简介二、安装1、简介2、本地部署(Local模式)2.1 安装2.2 官方WordCount实例 3、Standlong模式3.1 简介2.2 安装集群2.3 官方测试案例 4、Yarn模式3.1 安装3.2 配置历史服务器3.3 配置查看历史日志 5、Mesos模式6、几种模式对比7、常用端口 三、Yarn模式详解1、简介…

3. 无重复字符的最长子串 --力扣 --JAVA

题目 给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 解题思路 遍历字符串&#xff0c;遇到重复字符计算进行下一个子串的统计&#xff1b;从发生重复的字符第一次出现的位置进行继续循环&#xff1b;输出最长子串的长度。 代码展示 class S…

sql语句数据库查询:如果当前元素已经使用过,下拉框不显示该元素该如何查询?

写宿舍管理系统&#xff0c;做到宿管和楼栋关系时&#xff0c;新增一个宿管&#xff0c;一个宿管管理一栋楼&#xff0c;如果当前楼栋已选择&#xff0c;那么就不能再选&#xff0c;如图所示&#xff1a; 最开始使用的是&#xff1a; SELECT DISTINCT b.building_num,b.TYPE,b…

项目二开笔记-萤火商城https://www.yiovo.com/doc

很久没写过php代码了&#xff0c;二开过程中笔记如下 注意事项 打开APP_DEBUG 关于建表 .在store进行开发&#xff0c;新建表的时候需要加上store_id字段 增加页面 前端页面 增加新的菜单&#xff0c;需要在router.config.js中增加对应的配置增加新的页面&#xff0c;需要…