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

前言

本文主要介绍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.mzph.cn/news/231736.shtml

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

相关文章

【机器学习】卷积神经网络(CNN)的特征数计算

文章目录 基本步骤示例图解过程 基本步骤 在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;计算最后的特征数通常涉及到以下步骤&#xff1a; 确定输入尺寸&#xff1a; 首先&#xff0c;你需要知道输入数据的尺寸。对于图像数据&#xff0c;这通常是 (batch_size, c…

Webpack安装及使用

win系统 全局安装Webpack及使用 前提&#xff1a;使用Webpack必须安装node环境&#xff0c;建议使用nvm管理node版本。 1&#xff1a;查看自己电脑是否安装了node 2&#xff1a;npm install webpack版本号 -g 3&#xff1a;npm install webpack-cli -g -g:表示全局安装 4&…

龙芯loongarch64服务器编译安装gcc-8.3.0

前言 当前电脑的gcc版本为8.3.0,但是在编译其他依赖包的时候,出现各种奇怪的问题,会莫名其妙的中断编译。本地文章讲解如何自编译安装gcc,替换系统自带的gcc。 环境准备 下载页面:龙芯开源社区网站 - LoongArch GCC 8.3 交叉工具链 - 源码下载源码包名称如:loongson-gnu…

2023-12-18 最大二叉树、合并二叉树、二叉搜索树中的搜索、验证二叉搜索树

654. 最大二叉树 核心&#xff1a;记住递归三部曲&#xff0c;一般传入的参数的都是题目给好的了&#xff01;把构造树类似于前序遍历一样就可&#xff01;就是注意单层递归的逻辑&#xff01; # Definition for a binary tree node. # class TreeNode: # def __init__(se…

强化产品联动:网关V7独家解决方案的三重优势

客户背景 某央企单位汇聚了众多业内优秀的工程师和科研人员&#xff0c;拥有先进的研发设施和丰富的研发经验&#xff0c;专注于为全球汽车行业提供创新和实用的解决方案。其研发成果不仅在国内市场上得到了广泛应用&#xff0c;也在国际市场上赢得了广泛的认可和赞誉。 客户需…

jconsole与jvisualvm

jconsole 环境变量配置好后 直接输入在cmd 输入jconsole 即可 jvisualvm cmd 输入jvisualvm jvisualvm 能干什么 监控内存泄露&#xff0c;跟踪垃圾回收&#xff0c;执行时内存、cpu 分析&#xff0c;线程分析… 运行&#xff1a;正在运行的 休眠&#xff1a;sleep 等待…

接口测试的工具(3)----postman+node.js+newman

1.安装newman&#xff1a;输入命令之后 一定注意 什么都不要操作 静静的等待结束就行了。 2.安装失败的对此尝试不行 在用下面的方法 解压一下就行了 3.验证是否成功 多次尝试是可以在线安装成功的

Unity中Shader URP最简Shader框架(ShaderGraph 转 URP Shader)

文章目录 前言一、 我们先了解一下 Shader Graph 怎么操作1、了解一下 Shader Graph 的面板信息2、修改Shader路径3、鼠标中键 或 Alt 鼠标左键 移动画布4、鼠标右键 打开创建节点菜单5、把ShaderGraph节点转化为 Shader 代码6、可以看出 URP 和 BuildIn RP 大体框架一致 二、…

隐私计算介绍

这里只对隐私计算做一些概念性的浅显介绍&#xff0c;作为入门了解即可 目录 隐私计算概述隐私计算概念隐私计算背景国外各个国家和地区纷纷出台了围绕数据使用和保护的公共政策国内近年来也出台了数据安全、隐私和使用相关的政策法规 隐私计算技术发展 隐私计算技术安全多方计…

C# WPF上位机开发(usb设备访问)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 目前很多嵌入式设备都支持usb访问&#xff0c;特别是很多mcu都支持高速usb访问。和232、485下个比较&#xff0c;usb的访问速度和它们基本不在一个…

unittest自动化测试框架讲解以及实战

为什么要学习unittest 按照测试阶段来划分&#xff0c;可以将测试分为单元测试、集成测试、系统测试和验收测试。单元测试是指对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作&#xff0c;通常指函数或者类&#xff0c;一般是开发完成的。 单元…

工业数据的特殊性和安全防护体系探索思考

随着工业互联网的发展&#xff0c;工业企业在生产运营管理过程中会产生各式各样数据&#xff0c;主要有研发设计数据、用户数据、生产运营数据、物流供应链数据等等&#xff0c;这样就形成了工业大数据&#xff0c;这些数据需要依赖企业的网络环境和应用系统进行内外部流通才能…

【Python】—— NumPy基础及取值操作

NumPy基础及取值操作 第1关&#xff1a;ndarray对象第2关&#xff1a;形状操作第3关&#xff1a;基础操作第4关&#xff1a;随机数生成第5关&#xff1a;索引与切片 第1关&#xff1a;ndarray对象 任务描述 本关任务&#xff1a;根据本关所学知识&#xff0c;补全代码编辑器中…

react基于antd二次封装spin组件

目录 react基于antd二次封装spin组件组件使用组件效果 react基于antd二次封装spin组件 组件 import { Spin } from antd; import propTypes from "prop-types"; import React from react; import styleId from "styled-components"; // 使用 父div必须加…

【爬虫课堂】如何高效使用短效代理IP进行网络爬虫

目录 一、前言 二、代理IP的基本知识 三、短效代理IP的优势 四、高效使用短效代理IP的技巧 1. 多源获取代理IP 2. 质量筛选代理IP 3. 使用代理池 4. 定时更换代理IP 5. 失败重试机制 6. 监控和自动化 五、示例代码 六、结语 一、前言 网络爬虫是一种自动化程序&am…

MongoDB中的关系

本文主要介绍MongoDB中的关系。 目录 MongoDB的关系嵌入关系引用关系 MongoDB的关系 MongoDB是一个非关系型数据库&#xff0c;它使用了键值对的方式来存储数据。因此&#xff0c;MongoDB没有像传统关系型数据库中那样的表、行和列的概念。相反&#xff0c;MongoDB中的关系是通…

LLM之RAG实战(五)| 高级RAG 01:使用小块检索,小块所属的大块喂给LLM,可以提高RAG性能

RAG&#xff08;Retrieval Augmented Generation&#xff0c;检索增强生成&#xff09;系统从给定的知识库中检索相关信息&#xff0c;从而使其能够生成事实信息、上下文相关信息和特定领域的信息。然而&#xff0c;在有效检索相关信息和生成高质量响应方面&#xff0c;RAG面临…

【网络安全】-Linux操作系统—CentOS安装、配置

文章目录 准备工作下载CentOS创建启动盘确保硬件兼容 安装CentOS启动安装程序分区硬盘网络和主机名设置开始安装完成安装 初次登录和配置更新系统安装额外的软件仓库安装网络工具配置防火墙设置SELinux安装文本编辑器配置SSH服务 总结 CentOS是一个基于Red Hat Enterprise Linu…

美颜SDK是什么?视频美颜SDK在直播平台中的集成与接入教程详解

当下&#xff0c;主播们追求更加自然、精致的外观&#xff0c;而观众也期待在屏幕前欣赏到更为清晰、美丽的画面。为了满足这一需求&#xff0c;美颜SDK应运而生&#xff0c;成为直播平台的重要利器之一。 一、什么是美颜SDK&#xff1f; 通过美颜SDK&#xff0c;开发者可以…

Kotlin Multiplatform的现状—2023年网络研讨会

Kotlin Multiplatform的现状—2023年网络研讨会 在2023年&#xff0c;Kotlin Multiplatform因其开发、当前状态和未来潜力而受到了相当大的关注。随着越来越多的开发者对采用KMP进行跨平台解决方案表示兴趣&#xff0c;JetBrains在11月下旬推出了一系列网络研讨会作为回应。首…