音视频学习(二十一)——rtmp收流(tcp方式)

news2024/11/26 11:48:50

前言

本文主要介绍rtmp协议收流流程,在linux上搭建rtmp服务器,通过自研的rtmp收流库发起取流请求,使用ffmpeg+qt实现视频流的解码与播放。

关于rtmp协议基础介绍可查看:https://blog.csdn.net/www_dong/article/details/131026072

环境搭建

nginx-rtmp-module下载

# 下载地址,下载zip包即可
https://github.com/arut/nginx-rtmp-module

nginx编译与安装

  1. 下载nginx
# 下载地址
http://nginx.org/en/download.html
  1. 解压,将nginx-rtmp-module拷贝至nginx-1.24.0目录,如下所示:

在这里插入图片描述

  1. 配置nginx编译环境
# 步骤1
yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel

# 步骤2
yum -y install libxml2 libxml2-dev
yum -y install libxslt-devel
  1. 生成Makefile文件
# 在/home/rtmp/nginx-1.24.0下执行如下命令
./configure --add-module=./nginx-rtmp-module-master --with-http_ssl_module --with-http_ssl_module --with-http_xslt_module --with-http_flv_module --with-debug --with-http_gzip_static_module
  1. 修改nginx.conf文件,进入conf/文件夹下,编译nginx.conf在末尾增加如下内容:
rtmp {
    server {
        listen 1935;               #监听端口,若被占用,可以更改
        chunk_size 4000;           #上传flv文件块儿的大小
        application live {         #创建一个叫live的应用
             live on;              #开启live的应用
             allow publish 192.168.191.100;#192.168.191.100为服务器ip 
             allow play all;
        }
    }
}
  1. 编译、安装
# 在/home/rtmp/nginx-1.24.0下执行如下命令
make
make install
  1. 启动nginx
# 测试配置文件
cd /usr/local/nginx
./sbin/nginx -t

# 有如下打印说明配置正常
[root@localhost nginx]# ./sbin/nginx  -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

# 启动nginx
./sbin/nginx

# 查看是否正常启动
ps -aux | grep nginx
  1. 网页访问,出现如下内容说明启动成功

在这里插入图片描述

ffmepg推流

  • 安装ffmepg,将视频文件拷贝至安装路径下,如图所示:

在这里插入图片描述

  • 执行如下命令
ffmpeg -re -stream_loop -1 -i test.h264 -c copy -f flv rtmp://192.168.191.100:1935/live/testrtmp

以上步骤执行完即完成rtmp服务器搭建。

设计

拉流流程

说明:客户端—自研的rtmp收流库,服务器—上述搭建的rtmp服务器

  • 客户端发送tcp握手请求,和服务器完成tcp握手和rtmp握手
  • 客户端发送命令消息中的“连接”(connect)到服务器,请求与一个服务应用实例建立连接;
  • 客户端发送网络连接命令的“创建流”(createStream)消息到服务端,以创建消息通信的逻辑通道。音频、视频和元数据的发布通过使用createStream命令创建的流通道执行。服务端发送createStream的“应答消息”(_result);
  • 客户端发送网络流命令中的“播放”(play)到服务端;
  • 服务端发送协议控制消息中的“设置块大小”(Set Chunk Size)到客户端设置chunk大小;
  • 服务器发送另一个协议控制消息(用户控制),指定事件“StreamIsRecorded”和该消息中的流ID。消息在前2字节中携带事件类型,在后4字节中携带流ID;
  • 服务端发送用户控制消息中的“流开始”(StreamBegin)消息到客户端,通知客户端流成功创建,可用于通信;
  • 如果客户端发送的播放命令成功,则服务器发送onStatus命令消息NetStream.Play.Start和NetStream.Play.Reset。仅当客户端发送的播放命令设置了重置标志时,服务器才会发送NetStream.Play.Reset。如果未找到要播放的流,服务器将发送onStatus消息NetStream.Play.StreamNotFound;
  • 服务端发送音视频数据到客户端;

代码设计

  1. 上层url解析
// rtmp://192.168.191.100:1935/live/testrtmp
// appName:"live"
// streamPath: "testrtmp"
// tcurl: "rtmp://192.168.191.100:1935/live"
int CRtmpTcpStreamReceiver::ParseUrl_(std::string& appName, std::string& streamPath, std::string& tcurl)
{
	if (m_rtmpUrl.empty())
		return -1;

	std::string url = m_rtmpUrl;
	std::string::size_type pos_0 = url.rfind("/");
	if (std::string::npos == pos_0)
		return -1;

	// "testrtmp"
	streamPath = url.substr(pos_0+1, url.length());
	// "rtmp://192.168.191.100:1935/live"
	tcurl = url.substr(0, pos_0);

	std::string tmpUrl = tcurl;
	std::string::size_type pos_1 = url.rfind("rtmp://");
	if (std::string::npos == pos_1)
		return -1;

	// ippUrl: "192.168.191.100:1935/live"
	std::string ippUrl = tmpUrl.substr(pos_1+7, tmpUrl.length());
	std::string::size_type pos_2 = ippUrl.rfind("/");
	if (std::string::npos == pos_2)
		return -1;

	// "live"
	appName = ippUrl.substr(pos_2+1, ippUrl.length());

	// "192.168.191.100:1935"
	std::string ipp = ippUrl.substr(0, pos_2);
	std::string::size_type pos_3 = ipp.rfind(":");
	if (std::string::npos == pos_3)
		return -1;

	m_rtmpIP = ipp.substr(0, pos_3);
	m_rtmpPort = atoi(ipp.substr(pos_3+1, ipp.length()).c_str());

	return 0;
}
  1. 开始tcp握手和rtmp握手
int CRtmpTcpStreamReceiver::InitRtmpSession_()
{
    // rtmp url解析
	std::string appName = "", streamPath = "", turl = "";
	if (0 != ParseUrl_(appName, streamPath, turl))
	{
		return -1;
	}

	do
	{
        // tcp连接
		m_tcpClient = std::make_shared<ZDTcpClient>(nullptr, this);
		if (!m_tcpClient.get()
			|| 0 != m_tcpClient->TcpCreate()
			|| 0 != m_tcpClient->TcpConnect(m_rtmpIP.c_str(), m_rtmpPort)
			|| 0 != m_tcpClient->TcpSetNoBlock(false)
			|| 0 != m_tcpClient->TcpRecvTimeout(5))
		{
			break;
		}

        // CRtmpCommand为librtmp库接口封装类
		m_command = std::make_shared<CRtmpCommand>(m_tcpClient, m_func, m_user);
		if (!m_command.get())
		{
			break;
		}

        // 创建接收实例
		if (0 != m_command->Create(appName, streamPath, turl)
			|| 0 != m_command->Start(1))
		{
			break;
		}

		return 0;
	} while (0);

	UnInitRtmpSession_();
	return -1;
}
  1. 启动线程接收数据
void CRtmpTcpStreamReceiver::RtmpWorker()
{
	std::shared_ptr<char> dataPacket(new char[RTMP_STREAM_DATA_SIZE], std::default_delete<char[]>());
	memset(dataPacket.get(), 0x00, RTMP_STREAM_DATA_SIZE);
	int recvLen = 0;

	while (m_running)
	{
        // tcp数据接收
		recvLen = m_tcpClient->TcpRecv(dataPacket.get(), RTMP_STREAM_DATA_SIZE);
		if (recvLen <= 0) 
		{
			continue;
		}

        // 塞数据
		if (0 != m_command->InputData(dataPacket.get(), recvLen))
		{
			break;
		}

		memset(dataPacket.get(), 0x00, RTMP_STREAM_DATA_SIZE);
	}
}

抓包

在这里插入图片描述

效果

在这里插入图片描述

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

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

相关文章

sqlserver dba日常操作

查询慢sql的方法 1.whoisactive 安装方法 http://whoisactive.com/downloads/下载地址 将下载好的zip包放到sqlserver服务器中 文件-打开-文件-下载好的zip包-在查询窗口点击执行 新建一个查询窗口&#xff0c;输入sp_whoisactive&#xff0c;获取当前运行的所有sql语句 使用…

windows 安装jenkins

下载jenkins 官方下载地址&#xff1a;Jenkins 的安装和设置 清华源下载地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/jenkins/windows-stable/ 最新支持java8的版本时2.346.1版本&#xff0c;在清华源中找不到&#xff0c;在官网中没找到windows的下载历史&#xff…

ELK(九)—logstash

目录 简介安装部署测试 配置详解编写配置文件连接elasticsearch将数据推送到elasticsearch中。 简介 Logstash 是一个开源的服务器端数据处理管道&#xff0c;由 Elastic 公司维护和开发。它被设计用于从不同来源收集、处理和转发数据&#xff0c;以供 Elasticsearch 进行存储…

Mysql主从复制,读写分离,分表分库策略与实践

本文转自互联网&#xff0c;本文部分内容来源于网络&#xff0c;为了把本文主题讲得清晰透彻&#xff0c;也整合了很多我认为不错的技术博客内容&#xff0c;引用其中了一些比较好的博客文章&#xff0c;如有侵权&#xff0c;请联系作者。 该系列博文会告诉你如何从入门到进阶&…

docker在线安装minio

1、下载最新minio docker pull minio/minio 2、在宿主机创建 /usr/local/data/miniodocker/config 和 /usr/local/data/miniodocker/data,执行docker命令 docker run -p 9000:9000 -p 9090:9090 --name minio -d --restartalways -e MINIO_ACCESS_KEYminio -e MINIO_SECRET_K…

miRMaker

Introduction 除了miRNA表达数据&#xff0c;各种miRNA相关的知识也强有力地支持了对miRNA功能相互作用的理解。 那些具有许多共同调控靶基因或疾病的miRNAs可能具有相似的功能 一些方法通过考虑实验验证的miRNA-靶标关系来评估miRNA相互作用&#xff0c;评估miRNA功能相互作…

KUKA机器人Loop循环的具体使用方法示例

KUKA机器人Loop循环的具体使用方法示例 如下图所示&#xff0c;新建一个示例程序&#xff0c; 如下图所示&#xff0c;添加一些动作指令&#xff0c; 如下图所示&#xff0c;如果想要机器人在第5行和第9行之间循环执行程序&#xff0c;则可以在第5行添加指令loop&#xff0…

Linux 特殊符号

目录 1. # 注释 2. &#xff1b;命令分隔符 3. .. 上级目录 4. . 当前目录 5. " " 换行&#xff0c;解析变量 6. 换行&#xff0c;不解析变量 7. \ 和 / 8. &#xff01;历史命令调用&#xff0c;取反 9. * 通配符 10. $ 调用变量 11. | 管道 12. || …

AWS-WAF-CDN基于速率rate的永久黑名单方案(基于lambda实现)

参考方案&#xff08;有坑&#xff09;&#xff0c; 所以产生了这篇博客&#xff1a; 点击跳转 1. 部署waf &#xff08;有则跳过&#xff09; 必须存在一个rate速率规则&#xff0c;后面的方案堆栈要用 新建rate速率规则 关联cdn资源 2.部署堆栈 (美国东部 (弗吉尼亚北部 …

安卓小练习-校园闲置交易APP(SQLite+SimpleCursorAdapter适配器)

环境&#xff1a; SDK&#xff1a;34 JDK&#xff1a;20.0.2 编写工具&#xff1a;Android Studio 2022.3.1 整体效果&#xff08;视频演示&#xff09;&#xff1a; 小练习-闲置社区APP演示视频-CSDN直播 部分效果截图&#xff1a; 整体工作流程&#xff1a; 1.用户登录&…

【基础篇】1.2 认识STM32(二)

3.3 VREF/VREF-引脚 VREF和VREF-是STM32中用于提供参考电压的引脚。如下图&#xff1a; VREF引脚可以连接一个单独的外部参考电压&#xff0c;范围在2.0V&#xff5e;VDDA&#xff0c;但不能超过VDDA&#xff0c;否则就超过了模拟器件的最大供电电压。在100引脚的封装中&#…

数据可视化---双Y轴折线图比较

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)十五:基础数据模块相关功能实现

一、本章内容 本章使用已实现的公共组件实现系统管理中的基础数据中的验证码管理、消息管理等功能。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 3.1 B站视频地址: 基于VUE3+Layui从头搭建通用后台管理系统合集-验证码功能实现 3.2 西瓜…

视频推拉流EasyDSS互联网直播/点播平台构建户外无人机航拍直播解决方案

一、背景分析 近几年&#xff0c;国内无人机市场随着航拍等业务走进大众&#xff0c;出现爆发式增长。无人机除了在民用方面的应用越来越多&#xff0c;在其他领域也已经开始广泛应用&#xff0c;比如公共安全、应急搜救、农林、环保、交通 、通信、气象、影视航拍等。无人机使…

Leetcode—746.使用最小花费爬楼梯【简单】

2023每日刷题&#xff08;六十一&#xff09; Leetcode—746.使用最小花费爬楼梯 算法思想 参考灵神 实现代码 class Solution { public:int minCostClimbingStairs(vector<int>& cost) {int n cost.size();vector<int> f(n 1);for(int i 2; i < n;…

DY某音视频评论区采集 评论数据抓取

某音用户评论和ID的采集方法主要使用burpsuite火狐浏览器抓包分析请求接口 火狐浏览器设置走代理模式&#xff1a;IP地址为本机127.0.0.1 端口8080 \/&#xff1a;jeomoo168 burpsuite->代理->HTTP历史记录那可以看到请求接口https://www.douyin.com/aweme/v1/web/com…

JDK bug:ciObjectFactory::create_new_metadata

文章目录 1、问题2.详细日志3.JDK&#xff1a;bug最终bug链接&#xff1a; 京东遇到过类似bug各位大佬如果有更详细的解答可以留言。 1、问题 Problematic frame: V [libjvm.so0x438067] ciObjectFactory::create_new_metadata(Metadata*)0x327 关键字还是ciObjectFactory::cr…

Ubuntu 18.04配置NFS服务器以及配置时遇到NFS问题

1.安装相关软件 sudo apt-get install nfs-kernel-server sudo apt-get install nfs-common 2.配置共享目录 2.1修改exports文件 sudo vi /etc/exports在最后添加如下并保存退出 /home/xiaowu/nfs 192.168.31*(rw,sync,no_root_squash,no_subtree_check) /home/xiaowu/nfs…

【论文阅读笔记】Pre-trained Universal Medical Image Transformer

Luo L, Chen X, Tang B, et al. Pre-trained Universal Medical Image Transformer[J]. arXiv preprint arXiv:2312.07630, 2023.【代码开源】 【论文概述】 本文介绍了一种名为“预训练通用医学图像变换器&#xff08;Pre-trained Universal Medical Image Transformer&…

nodejs+vue+微信小程序+python+PHP国漫推荐系统-计算机毕业设计推荐

使得本系统的设计实现具有可使用的价。做出一个实用性好的国漫推荐系统&#xff0c;使其能满足用户的需求&#xff0c;并可以让用户更方便快捷地国漫推荐。这个系统的设计主要包括系统页面的设计和方便用户互动的后端数据库&#xff0c;在开发后需要良好的数据处理能力、友好的…