音视频学习(二十)——rtsp收流(udp方式)

news2024/11/23 9:57:25

前言

本文主要介绍通过udp方式实现rtsp拉流。

流程图

在这里插入图片描述

流程说明:

  • 相较于tcp方式“信令+数据”复用同一连接拉流,udp方式拉流“信令+数据”采用不同的连接,信令传输采用tcp,流数据传输采用udp;
  • 客户端向服务端(设备等)发起tcp请求,用于后续信令交互;
  • tcp连接成功后,开始rtsp信令交互(describe、setup、play等),rtsp链路需要保活;
  • 客户端选择两个未用的端口创建udp链路,一个用于rtp数据传输,一个用于rtcp数据传输;
  • 连接成功后,服务端(设备等)发送数据至客户端;
  • 客户端对数据解复用、解码、播放;

设计

  1. 客户端向服务端(设备等)发起tcp请求:创建socket、connect、设置recv超时时间
m_tcpClient = std::make_shared<ZDTcpClient>(nullptr, this);
if (!m_tcpClient.get()
    || 0 != m_tcpClient->TcpCreate()
    || 0 != m_tcpClient->TcpConnect(ip.c_str(), port)
    || 0 != m_tcpClient->TcpSetNoBlock(true)
    || 0 != m_tcpClient->TcpRecvTimeout(10))
    break;
  1. tcp连接成功后,创建rtsp客户端,开始rtsp信令交互
// 参数1(RTSP_TRANSPORT_RTP_UDP)指明使用udp方式收流
m_command = std::make_shared<CRtspCommand>(RTSP_TRANSPORT_RTP_UDP, 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;
  1. 创建udp链路
int CRtspCmd::HandleRtpPort(int media, const char* source, unsigned short rtp[2], char* ip, int len)
{
	int ret = -1;
	switch (m_transport)
	{
	case RTSP_TRANSPORT_RTP_UDP:
		ret = sockpair_create("0.0.0.0", m_rtp[media], m_port[media]);
		if (0 != ret)
		{
			return -1;
		}

		rtp[0] = m_port[media][0];
		rtp[1] = m_port[media][1];
		break;
	default:
		assert(0);
		return -1;
	}

	return m_transport;
}
  1. 启动udp收流
int CRtspUdpData::Start(int count, socket_t rtp[2], const char* peer, int peerport[2], int payload, const char* encoding)
{
    // 创建解复用器
	const struct rtp_profile_t* profile = rtp_profile_find(payload);
	m_demuxer = rtp_demuxer_create(100, profile ? profile->frequency : 90000, payload, encoding, RtpPacketCB, this);
	if (!m_demuxer)
		return -1;

	if (0 != CreatePacker_(payload, encoding))
	{
		rtp_demuxer_destroy(&m_demuxer);
		return -1;
	}

	m_encoding = encoding;
	m_payload = payload;
	m_socket[0] = rtp[0];
	m_socket[1] = rtp[1];
    
    // 启动数据接收线程
	m_thread = std::thread(UdpDataThread, this);
	return 0;
}
  1. 读rtp和rtcp数据
// 读rtp数据
int CRtspUdpData::RtpRead_(socket_t s)
{
	if (!m_demuxer)
		return -1;

	struct sockaddr_storage ss;
	socklen_t len = sizeof(ss);
	int dataLen = recvfrom(s, m_rtpBuffer, sizeof(m_rtpBuffer), 0, (struct sockaddr*)&ss, &len);
	if (dataLen < 12)
	{
		return -1;
	}

    // 视频数据解复用
	return rtp_demuxer_input(m_demuxer, m_rtpBuffer, dataLen);
}

// 读rtcp数据
int CRtspUdpData::RtcpRead_(socket_t s)
{
	if (!m_demuxer)
		return -1;

	struct sockaddr_storage ss;
	socklen_t len = sizeof(ss);
	int dataLen = recvfrom(s, m_rtcpBuffer, sizeof(m_rtcpBuffer), 0, (struct sockaddr*)&ss, &len);
	if (dataLen < 12)
	{
		return -1;
	}

	return rtp_demuxer_input(m_demuxer, m_rtcpBuffer, dataLen);
}

效果

在这里插入图片描述

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

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

相关文章

二维码智慧门牌管理系统升级:行政区划维护功能详解

文章目录 前言一、行政区划维护解决方案二、解决方案优势 前言 随着科技不断发展&#xff0c;二维码智慧门牌管理系统已成为物业管理和社区服务等领域的重要工具。在此系统升级解决方案中&#xff0c;行政区划维护功能愈发显得重要。我们将详细介绍这一功能&#xff0c;助您更…

看好美国跨境电商平台Etsy的三个理由

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 不可否认&#xff0c;最近的经济低迷给美国跨境电商平台Etsy(ETSY)的增长带来了一些麻烦。虽然Etsy第三季度营收同比增长了7%&#xff0c;但其商品总量仅增长了1%。如果没有有利的汇率&#xff0c;Etsy的销售额基本上会与前…

【赠书活动】Java程序员,你掌握了多线程吗?

文章目录 摘要01 多线程对于Java的意义02 为什么Java工程师必须掌握多线程03 Java多线程使用方式04 如何学好Java多线程赠书活动 摘要 互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流量洪峰&…

名创优品股份有限公司

用户简介 名创优品股份有限公司&#xff08;以下简称&#xff1a;名创优品&#xff09;奉行“简约、自然、富质感”的生活哲学和“回归自然&#xff0c;还原产品本质”的设计主张&#xff0c;秉承“尊重消费主义者”的品牌精神&#xff0c;致力于为全球消费者提供真正“优质、…

Avalonia中如何实现文件拖拽上传

前言 前面我们讲了在Avalonia中如何将View事件映射到ViewModel层感兴趣的读者可以看一下&#xff0c;本章我们将讲一下在Avalonia框架下如何实现文件和文字的拖拽到指定区域进行处理和上传。 先看效果 界面设计比较简单&#xff0c;还是在前一张的基础上加了一个指定区域&…

十六、FreeRTOS之FreeRTOS队列集

本节需要掌握以下内容&#xff1a; 1&#xff0c;队列集简介&#xff08;了解&#xff09; 2&#xff0c;队列集相关API函数介绍&#xff08;熟悉&#xff09; 3&#xff0c;队列集操作实验&#xff08;掌握&#xff09; 一、队列集简介&#xff08;了解&#xff09; 一个…

就一个css的bug,害我找了大半天儿

大家好&#xff0c;我是风筝 事情是这样子的&#xff0c;我前两天用 Hugo 搭了一个个人网站&#xff0c;我添加了几个菜单&#xff0c;其中有一个菜单是「可爱的 Java」。 但是&#xff0c;当网站跑起来之后&#xff0c;发现「可爱的 Java」在菜单栏并不是原样输出的&#xf…

推荐一个FL Studio最适配的midi键盘?

Hello大家好&#xff01;好消息&#xff01;好消息&#xff01;特大好消息&#xff01; 水果党们&#xff01;终于有属于自己的专用MIDI键盘啦&#xff01; 万众期待的Novation FLKEY系列 正式出炉&#xff01; 做编曲和音乐制作的朋友们&#xff0c;对水果软件FLSTUDIO应该…

2.vue学习笔记(目录结构+模板语法+属性绑定)

1.目录结构 1.vscode ——VSCode工具的配置文件夹 2.node_modules ——Vue项目的运行依赖文件夹 3.public ——资源文件夹&#xff08;浏览器图标&#xff09; 4.src ——源码文件夹 5..gitgnore ——git忽略文件 6.index.html ——如果html文件 7.package.json —…

【Unity动画】Unity 2D动画创建流程

本文以2D为案例&#xff0c;讲解Unity 播放动画的流程 准备和导入2D动画资源 外部导入序列帧生成的 Unity内部制作的 外部导入的3D动画 2.创建动画过程 打开时间轴Ctrl6 选中场景中的一个未来需要播放动画的物体 回到时间轴点击Create一个新动画片段 拖动2D动画资源放入…

class059 建图、链式前向星、拓扑排序【算法】

class059 建图、链式前向星、拓扑排序【算法】 code1 建图 package class059;import java.util.ArrayList; import java.util.Arrays;public class Code01_CreateGraph {// 点的最大数量public static int MAXN 11;// 边的最大数量// 只有链式前向星方式建图需要这个数量// 注…

选择最适合你的接口测试工具:SoapUI、JMeter、Postman!

在软件开发的过程中&#xff0c;接口测试是确保系统正常运行的关键环节。为了有效地执行接口测试&#xff0c;选择适当的工具至关重要。在这篇文章中&#xff0c;我们将比较分析三种常见的接口测试工具&#xff1a;SoapUI、JMeter和Postman&#xff0c;以帮助你了解它们的优势和…

MVSNeRF:多视图立体视觉的快速推广辐射场重建(2021年)

MVSNeRF&#xff1a;多视图立体视觉的快速推广辐射场重建&#xff08;2021年&#xff09; 摘要1 引言2 相关工作3 MVSNeRF实现方法3.1 构建代价体3.2 辐射场的重建3.3 体渲染和端到端训练 3.4 优化神经编码体 Anpei Chen and Zexiang Xu and Fuqiang Zhao et al. MVSNeRF: Fast…

Leetcode 92 反转链表II

反转链表II 题解1 一遍遍历&#xff08;穿针引线&#xff09; 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 提示&#xff1a; 链表中节点数目…

JVM 类的加载器的基本特征和作用

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 1、作用 类加载器是 JVM 执行类加载机制的前提 ClassLoader的作用&#xff1a; ClassLoader是Java的核心组件&#xff0c;所有的Class都是由ClassLoader进行加载的&#xff0c;ClassLoader负责通过各种方式将Class信…

汽车软件大时代,如何提升软件工程创新力?

当前&#xff0c;传统汽车产业正加速数字化转型&#xff0c;“软件定义汽车”不断深化。在电动化、智能化和网联化趋势下&#xff0c;汽车软件已经成为汽车技术革新和发展的核心驱动力之一。根据亿欧智库发布的《2023中国智能电动汽车车载软件市场分析报告》&#xff0c;2022年…

<蓝桥杯软件赛>零基础备赛20周--第9周--前缀和与差分

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

Docker-compose容器编排与容器监控

一、Docker-compose 1、概念&#xff1a; Docker-Compose 是 Docker 官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 2、作用&#xff1a; Docker-Compose可以管理多个Docker容器组成一个应用。需要定义一个yaml格式的配置文件 docker-compose.yml&#…

2023-12-06 LeetCode每日一题(最小化旅行的价格总和)

2023-12-06每日一题 一、题目编号 2646. 最小化旅行的价格总和二、题目链接 点击跳转到题目位置 三、题目描述 现有一棵无向、无根的树&#xff0c;树中有 n 个节点&#xff0c;按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges &#xff0…