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

news/2024/5/18 14:26:17 标签: 音视频, 学习, udp, c++

前言

本文主要介绍通过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.niftyadmin.cn/n/5246235.html

相关文章

MacOS VSCode 配置远程服务器ssh remote链接,并上传文件文件服务器

环境&#xff1a; MacOS & VSCode & ssh remote 1. VSCode安装插件 2. 配置ssh remote链接 Host 10.128.200.101HostName 10.128.200.101User rootForwardAgent yesIdentityFile ~/.ssh/id_rsa # 服务器免密登录本地秘钥文件路径 配置完保存&#xff1b; 3. 在ssh…

什么是css初始化

什么是css初始化 CSS初始化是指重设浏览器的样式。 因为浏览器的兼容问题&#xff0c;不同浏览器对有些标签的默认值是不同的&#xff0c;如果没对CSS初始化往往会出现浏览器之间的页面显示差异。 每次新开发网站或新网页时候通过初始化CSS样式的属性&#xff0c;为我们将用…

偷窃别人的密码

在工作中都用到virtual machine吧&#xff0c;同事之间还互相借用机器&#xff0c;或者不借用但凭借自己的域账号能登录任意机器&#xff0c;而且每个域账号都有sudo权限&#xff1f; 那你要小心了&#xff01; 因为我可以轻易记录下每个ssh登录到我机器&#xff0c;或者我在…

Kafka Connect :构建强大分布式数据集成方案

Kafka Connect 是 Apache Kafka 生态系统中的关键组件&#xff0c;专为构建可靠、高效的分布式数据集成解决方案而设计。本文将深入探讨 Kafka Connect 的核心架构、使用方法以及如何通过丰富的示例代码解决实际的数据集成挑战。 Kafka Connect 的核心架构 Kafka Connect 的核…

如何选择靠谱的软件测试外包公司?CMA、CNAS软件测试报告获取

作为信息科技产业的代表之一&#xff0c;软件公司受到了越来越多的关注&#xff0c;它们的发展为我国的科技创新提供了强大的战略支撑。软件测试作为提升软件产品质量的后盾&#xff0c;日益成为一个专业化、标准化和规范化的行业&#xff0c;软件测试外包公司就是这种背景下成…

JVM的内存结构详解「重点篇」

一、JVM虚拟机数据区 虚拟机栈 1、 线程私有 2、 每个方法被执行的时候都会创建一个栈帧用于存储局部变量表&#xff0c;操作栈&#xff0c;动态链接&#xff0c;方法出口等信息。每一个方法被调用的过程就对应一个栈帧在虚拟机栈中从入栈到出栈的过程。 3、栈帧: 是用来存储…

java使用ffmpeg拆分和拼接音频

ffmpeg是一个开源的跨平台音视频处理工具&#xff0c;它可以对音视频进行格式转换、压缩、采集、裁剪、剪辑等操作。ffmpeg能够处理的音视频格式很多&#xff0c;包括常见的mp4、avi、mov等格式&#xff0c;也包括一些不那么常见的格式。 ffmpeg最初是由法国程序员Fabrice Bell…

m1编译xgboost的jar报错

1、编译 cd jvm-package包&#xff0c;然后进行编译mvn install -P libxgboost,java -DskipTests 2、报错信息&#xff1a; 3、解决方法 A、在jvm-packages包下找到xgboost4j中找到pom.xml&#xff0c;如图&#xff1a; B、修改python的额目录或者脚本&#xff1a; C、继续执…