音视频学习(十九)——rtsp收流(tcp方式)

前言

本文主要介绍以tcp方式实现rtsp拉流。

流程图

在这里插入图片描述

流程说明:

  1. 客户端发起tcp请求,如向真实相机设备请求,端口一般默认554;
  2. tcp连接成功,客户端与服务端开始rtsp信令交互;
  3. 客户端收到play命令响应后,开启线程等待接收数据,同时开启定时器,定时向服务端发送命令用于心跳保活
  4. 服务端向客户端发送音视频数据;
  5. 客户端接收rtp数据并进行解复用;

设计

  • 发送tcp请求
    • 创建socket
    • connect
    • 设置非阻塞
    • 设置tcp超时时间
// 建立tcp连接
m_tcpClient = std::make_shared<TcpClient>(nullptr, this);
if (!m_tcpClient.get()|| 0 != m_tcpClient->TcpCreate()|| 0 != m_tcpClient->TcpConnectByTime(ip.c_str(), port, 5)|| 0 != m_tcpClient->TcpSetNoBlock(true)|| 0 != m_tcpClient->TcpRecvTimeout(10))break;
  • rtsp信令交互
// 创建command类
m_command = std::make_shared<CRtspCommand>(RTSP_TRANSPORT_RTP_TCP, m_tcpClient, m_func, m_user);
if (!m_command.get())break;// 创建rtsp client
if(!m_command->CreateRtspClient(m_rtspUrl, username, userpasswd))break;// 发送describe
int ret = m_command->SendDescribe();
if (0 != ret)break;
  • 补充:创建rtsp client,发送describe后根据回调进行后续命令操作(使用开源库ireader/librtsp进行rtsp信令交互)
bool CRtspCommand::CreateRtspClient(const std::string& uri, const std::string& username, const std::string& userpasswd)
{if (uri.empty() || username.empty() || userpasswd.empty())return false;rtsp_client_handler_t handler;handler.send = SendCallback;handler.rtpport = RtpPortCallcback;handler.onannounce = AnnounceCallback;handler.ondescribe = DescribeCallback;handler.onsetup = SetupCallback;handler.onplay = PlayCallback;handler.onpause = PauseCallback;handler.onteardown = TeardownCallback;handler.onrtp = RtpDataCallback;m_rtsp = rtsp_client_create(uri.c_str(), username.c_str(), userpasswd.c_str(), &handler, this);if (!m_rtsp)return false;return true;
}
  • 启动线程等待接收数据
#define RECV_DATA_SIZE (64*1024*1024)void CRtsp::RtspWorker()
{std::shared_ptr<char> dataPacket(new char[RECV_DATA_SIZE], std::default_delete<char[]>());memset(dataPacket.get(), 0x00, RECV_DATA_SIZE);int recvLen = 0;while (m_running){recvLen = m_tcpClient->TcpRecv(dataPacket.get(), RECV_DATA_SIZE);if (recvLen <= 0)       // 数据接收失败{break;}if (0 != m_command->InputData(dataPacket.get(), recvLen)){break;}memset(dataPacket.get(), 0x00, STREAM_DATA_SIZE);}
}
  • 启动定时器进行心跳保活(tcp方式需要
// 创建定时器
m_timer = std::make_shared<ZDTimer>(10, 1000);
m_timer->Start();// 开启定时器
m_timer->AddTask(10000, [this]() {// 10s发送一次get parameter命令int count = rtsp_client_media_count((rtsp_client_t*)m_rtsp);if (count > 0)rtsp_client_get_parameter(m_rtsp, 0, NULL);
});// 停止定时器
if (m_timer.get())
{m_timer->Stop();m_timer.reset();
}
  • 接收视频数据并解复用(使用开源库ireader/librtp库进行rtp数据解复用)
// 1.创建解复用器
m_demuxer = rtp_demuxer_create(100, profile ? profile->frequency : 90000, payload, encoding.c_str(), RtpPacketCallback, this);// 2. 塞数据
rtp_demuxer_input(m_demuxer, data, len);// 3. 数据回调
static int RtpPacketCallback (void* param, const void* packet, int bytes, uint32_t timestamp, int flags)
{// 裸流数据处理
}// 4. 销毁
rtp_demuxer_destroy(&m_demuxer);

效果

在这里插入图片描述

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

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

相关文章

Leetcode 501 二叉搜索树中的众数

题意理解&#xff1a; 首先明确&#xff1a; 二叉搜索树中序遍历是严格的单调递增序列&#xff0c;也就是说&#xff0c;传统意义上得到二叉搜索树不存在相同的数&#xff0c;也不可能存在众数。 所以&#xff1a; 这里的二叉搜索树不是严格意义上的二叉搜索树&#xf…

PVE中CT容器安装openwrt X86的极简方法

下载推荐&#xff1a;https://openwrt.ai/ 使用环境PVE8.0&#xff0c;openwrt是以上网址的最新版&#xff0c;内涵及其丰富组件。 问题来源&#xff1a; 在PVE虚拟机可以很方便的使用img文件&#xff0c;转换qm 成一个硬盘文件&#xff0c;加入到虚拟机也就完成了&#xff0c…

五、双向NAT

学习防火墙之前&#xff0c;对路由交换应要有一定的认识 双向NAT1.1.基本原理1.2.NAT Inbound NAT Server1.3.域内NATNAT Server —————————————————————————————————————————————————— 双向NAT 经过前面介绍&#xff0c;…

fiddler设置手机端抓包看这篇文章就足够了,轻松解决!

fiddler设置手机端抓包 安卓手机抓包 第一步&#xff1a;配置电脑和安卓的相关设置 1、手机和fiddler位于同一个局域网内&#xff1b;首先从fiddler处获取到ip地址和端口号&#xff1a; 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; &#xff0c;点…

【Linux】coredump 文件的例子分析

1. 生成 core 文件 网上很多教程&#xff0c;我这里举一种 临时开启 生成 core 文件 # 0 就是没有开 coredump 功能 rootswd-Lenovo-G40-80:/home/swd/pros/c--learn/0.test_codes/demos# ulimit -c 0 # 设置值临时为 unlimited rootswd-Lenovo-G40-80:/home/swd/pros/c--le…

Java基础之常用类

Java基础之常用类 一、包装类1.1、Java基本数据类型及其对应的包装类1.2、包装类的自动装箱、自动拆箱机制1.3、包装类的优点 二、String类三、StringBuffer类和StringBuilder类3.1、主要区别&#xff1a;3.2、StringBuffer/StringBuilder用法(两者用法一致) 四、日期类4.1、Da…

setLineWrapMode 是 QTextEdit 类的成员函数,用于设置文本换行模式(Line Wrap Mode)

setLineWrapMode 是 QTextEdit 类的成员函数&#xff0c;用于设置文本换行模式&#xff08;Line Wrap Mode&#xff09;。 在 Qt 中&#xff0c;文本换行模式指定了文本编辑器中长行文本的显示方式。通过设置不同的换行模式&#xff0c;可以控制是否自动换行、如何换行以及是否…

[DASCTF 2023 0X401七月暑期挑战赛] web刷题记录

文章目录 EzFlask方法一 python原型链污染方法二 flask框架静态文件方法三 pin码计算 MyPicDisk方法一 字符串拼接执行命令方法二 phar反序列化 ez_cms EzFlask 考点&#xff1a;python原型链污染、flask框架理解、pin码计算 源码如下 import uuidfrom flask import Flask, re…

企业源代码防泄密的有什么痛点及难点?

安秉信息作为源代码防泄密的方案的提供商&#xff0c;对企业源代码防泄密有深入的了解。在企业中可以对普通 的文件&#xff0c;图纸进行加密保护这些文件的泄漏。但是企业管理者对于企业的源代码文件防泄密却没有更好的管理方案。 源代码防泄密最大的痛点是&#xff0c;现在企…

近五年—中国十大科技进展(2018年—2022年)

近五年—中国十大科技进展&#xff08;2018-2022&#xff09; 2022年中国十大科技进展1. 中国天眼FAST取得系列重要进展2. 中国空间站完成在轨建造并取得一系列重大进展3. 我国科学家发现玉米和水稻增产关键基因4. 科学家首次发现并证实玻色子奇异金属5. 我国科学家将二氧化碳人…

uni-app 微信小程序 pdf预览

<div click"getPDF">查看体检报告</div>getPDF() {uni.downloadFile({url: ${this.$baseURL}/file/download?id${this.pdfFileId},//编写在线的pdf地址success: function(res) {const filePath res.tempFilePath;uni.openDocument({filePath: filePath…

java stream流map和flatmap的区别

map和flatmap都是用来转换操作。 map()操作后的流与原始流的元素个数一一对应&#xff0c;一对一地进行元素转换&#xff0c;适用于对每个元素进行简单的转换操作&#xff0c;例如将元素的属性提取出来或进行数值计算。 flatMap()操作是一对多的元素转换&#xff0c;对于每个输…

Roll-A-Ball 游戏

Roll-A-Ball 游戏 1&#xff09;学习资料 b站视频教程&#xff1a;https://www.bilibili.com/video/BV18W411671S/文档&#xff1a; * Roll-A-Ball 教程&#xff08;一)&#xff0c; * Roll-A-Ball 教程&#xff08;二)线上体验roll-a-ball成品 * http://www-personal.umich.e…

使用opencv将sRGB格式的图片转换为BT.2020格式【sRGB】【BT.2020】

将sRGB格式的图片转换为BT.2020格式涉及到两个步骤&#xff1a;首先将sRGB转换到线性RGB&#xff0c;然后将线性RGB转换到BT.2020。这是因为sRGB图像通常使用伽马校正&#xff0c;而BT.2020工作在线性色彩空间中。 从sRGB到线性RGB&#xff1a;sRGB图像首先需要进行伽马校正解码…

Spring面向切面编程(AOP);Spring控制反转(IOC);解释一下Spring AOP里面的几个名词;Spring 的 IoC支持哪些功能

文章目录 Spring面向切面编程(AOP)什么是AOPSpring AOP and AspectJ AOP 的区别&#xff1f;Spring AOP中的动态代理如何理解 Spring 中的代理&#xff1f;解释一下Spring AOP里面的几个名词Spring在运行时通知对象Spring切面可以应用5种类型的通知&#xff1a;什么是切面 Aspe…

scoop bucket qq脚本分析(qq绿色安装包制作)

url字段 以qq.json为例&#xff0c;其对应的scoop配置文件在$env:scoop\buckets\extras\bucket\qq.json 其中的url字段 "url":"https://webcdn.m.qq.com/spcmgr/download/QQ9.7.17.29230.exe#/dl.7z"为qq安装包下载地址&#xff0c;后缀#/dl.7z为自行添加…

第八节HarmonyOS @Component自定义组件的生命周期

在开始之前&#xff0c;我们先明确自定义组件和页面的关系&#xff1a; 1、自定义组件&#xff1a;Component装饰的UI单元&#xff0c;可以组合多个系统组件实现UI的复用。 2、页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定…

函数递归所应满足的条件

1.递归的概念 递归是学习C语⾔函数绕不开的⼀个话题&#xff0c;那什么是递归呢&#xff1f; 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。 递归的思想&#xff1a; 把⼀个⼤型复杂问题层层转化为⼀个与原问题相似&#xff0c;但…

ArkUI开发进阶—@Builder函数@BuilderParam装饰器的妙用与场景应用【鸿蒙专栏-05】

ArkUI开发进阶—@Builder函数@BuilderParam装饰器的妙用与场景应用 HarmonyOS,作为一款全场景分布式操作系统,为了推动更广泛的应用开发,采用了一种先进而灵活的编程语言——ArkTS。ArkTS是在TypeScript(TS)的基础上发展而来,为HarmonyOS提供了丰富的应用开发工具,使开…

mybatis <include refid=“xxx“></include>

&#xff1c;include refid"xxx"&#xff1e;&#xff1c;/include&#xff1e;使用在查询字段&#xff0c;多个select查询语句&#xff0c;可能查询的字段是相同的&#xff0c;就可以用这个标签把需要查询的字段抽出来。 <sql id"org_id">id,code,…