RTMP低延迟推流

devtools/2024/9/23 4:32:32/

人总是需要压力才能进步, 最近有个项目, 需要我在RK3568上, 推流到公网, 最大程度的降低延迟.
废话不多说, 先直接看效果:
在这里插入图片描述
数据经过WiFi发送到Inenter的SRS服务器, 再通过网页拉流的.

因为是打金任务, 所以逼了自己一把, 把RTMP推流好好捋一遍.
先说说任务目标, 首先是MPP编码, 把mpp的github库下载下来, 研究mpi_enc_test这个例程, 基本就能实现, 从摄像头/dev/video0获取yuv数据, 编码为h264, 保存为文件.

最终值得注意是两点:

  1. log看不到, mpp的log都保存到了/var/log/messages中.

在这里插入图片描述

  1. 输入参数, 因为人家的test demo, 包装得非常好, 编码的参数需要用参数输入, 而你必须设置一些编码参数, 我想到一个非常偷懒的做法:

在这里插入图片描述
伪装, 哈哈
这里面几个比较重要的参数,
-w -h分辨率之类,
-n 表示连续获取数据帧, 不显示数量
-t 就是h264比那吗
-g 是关键帧间隔
-rc 是码流控制, 1代表固定码流, 可根据需要修改, 在固定码流模式下, 可以设置码率

下图的bps就是码率, 直接写死, 要提高码率, 可以修改这里
在这里插入图片描述
3. 在整个编码一开始, 会有一个生成SPS/PPS帧的过程, 原本的代码是直接写入到h264裸文件中. 我看了下面雷神的做法, 先缓存了下来, 跟第一个I帧一起发送.

接下来就是RTMP推流国过程了.

整个过程的前提是, 我之前在腾讯, 花5分钟(开通)+30分钟(折腾防火墙发现是梯子的问题), 搞了个SRS的服务器, 这个服务能接收N种推流方式:
在这里插入图片描述
这里面我最熟悉的就是RTMP了.
其实我最迷信的就是直接TCP转发…但是播放端没有研究, 而我之前试过, 先在板子这端用RTSP, 然后用ZLMedia的pusher, 或者叫Muxer, 把RTSP转到RTMP上去:

https://blog.csdn.net/zunly/article/details/138510170?spm=1001.2014.3001.5502

我偶然发现, 通过网页看到的流, 延迟非常小, 说明这个路应该是ok的, 但是经过RTSP, 再转推, 实在太2, 于是乎经过了几天的折腾, 下面是一点发现:

先说说目前的目标, 就是把mpp编码完的h264数据帧, 一帧一帧的通过RTMP推到Internet上的SRS上去.

首先我能想到的, 就是这么普及的应用, 应该是有库的吧, 搜了一圈, 发现有几个选择:
传说的librtmp, 如果直接在github搜索, librtmp, 过滤掉iOS, 安卓平台, 就会看到雷神(致敬RIP)之前的仓库:

https://github.com/leixiaohua1020/simplest_librtmp_example.git

他的做法是使用一个叫librtmp的库, 但是这个库没有源码, 只有编译好的lib文件跟dll文件, 这没法移植啊…

github上, SRS librtmp的仓库, 留了一个留言:

在这里插入图片描述
两个连接都已经失效.

我又研究了ZLMedia的RTMP部分, 发现一时之间很难看懂…

接下来是ffmpeg, ffmpeg最早进入视野是因为我一开始就想研究webRTC的推流, 据说那玩意儿贼快, 于是看到了一个国内的现状, 很多开发者, 开发出一个框架, 像变现, 方法成了, 什么知识星球, 什么CSDN收费下载…唉…当然作为一个自由主义知识分子, 信仰的是Milton Friedman, Ronald H. Coase, 我举双手赞同知识付费…
最后因为没有钱, 我放弃了WHIP就是webRTC推流的方法…默默留下了贫穷的眼泪.

偶然的机会, 我发现了另一个雷神的仓库:
https://github.com/leixiaohua1020/simplest_ffmpeg_streamer

差点跟前面那个搞混了, 这个仓库就是一个既可以推mp4也可以推flv, 也可以推裸流的宝藏代码, 也是雷神在8年前遗珠…
这个方案用的是ffmpeg的库, ffmpeg老早就集成了这些了…ffmpeg牛逼!!!
我先是在Unbantu上面, 把代码在x86/x64环境跑起来(居然真的能跑通, 推流也是能看到画面的).
然后通过WireShark抓包, 看看到底除了了裸流的数据, ffmpeg 还发了些啥:

在wireshark中, 我发现了几个问题, 一个是对应代码的, RTMP的初始化连接过程, 是非常必要的, 这个过程相当于告诉RTMP的服务器, 你要推流的视频的一些信息, 例如宽高, 帧率之类.
在这里插入图片描述
而这些信息, 其实是ffmpeg通过读取你要发送的h264/flv文件来获取的, 就是这个write_head的过程
在这里插入图片描述

实际的每一个数据帧的发送, 根据打印结果发现, 如下图, 如果我推流的是一个h264的文件, 每次发送的packet, 其实就是通过ffmpeg的 av_read_frame方法, 跟NAL的分割字符(00 00 00 01或者00 00 01), 读取的一帧数据

在这里插入图片描述
read之后, 打印pkt, 长度跟数据内容, 用winhex打开比较

在这里插入图片描述
发现, 每个包, 就是一帧
在这里插入图片描述
那么思路就这样串起来了.

首先, 通过编码, 把摄像头数据, 保存为一个h264的文件, 这个文件当中, 最少有1个SPS, PPS, 跟一个关键帧, 作为一个初始化ffmepg AVPacket对象的工具, 同时也供RTMP的连接初始化使用, 接下来, 再使用实时编码出来的h264帧, 不断填充AVPacket对象的data 跟len这两个参数, 再通过ffmpeg的av_interleaved_write_frame 方法, 就可以把数据源源不断的推到RTMP上去了.

代码暂时不开源, 因为是个打金的项目, 如果上面的文章您还有任何疑问, 欢迎发私信讨论, 感谢大家.


http://www.ppmy.cn/devtools/42225.html

相关文章

如何加密电脑文件夹?重要文件夹怎么加密?

文件夹可以帮助我们管理电脑数据,而文件夹并不具有安全保护功能,很容易导致数据泄露。因此,我们需要加密保护电脑文件夹。那么,如何加密电脑文件夹呢?下面我们就来了解一下。 EFS加密 EFS加密是Windows提供的数据加密…

万亿国债即将发行,普通人能分一杯羹吗?信任为何提前亮起红灯?

财政部最新公告揭示:《2024年国债发行计划》正式出炉,涵盖一系列长期至超长期限的国债,涵盖20年、30年及50年期限。这一消息瞬间点燃了市场的讨论热情,激发了民众对于国家债务投资的兴趣与疑虑。 一、超长国债,你准备好…

python怎么安装matplotlib

1、登陆官方网址“https://pypi.org/project/matplotlib/#description”,下载安装包。 2、选择合适的安装包,下载下来。 3、将安装包放置到python交互命令窗口的当前目录下。 4、打开windows的命令行窗口,通过"pip install"这个命令…

php = 和 |= 是什么意思

在 PHP 中,& 和 | 是复合赋值运算符(也称为“位赋值运算符”),它们分别用于位与(AND)和位或(OR)操作,并将结果赋值回原变量。 &(位与赋值运算符&…

13 华三三层链路聚和

13 华三三层链路聚和 AI 解析 华三三层静态路由是指在华三交换机上配置的一种路由方式。它通过在交换机上手动配置路由表,将不同网络之间的数据进行转发。 华三三层静态路由的配置步骤如下: 1. 配置交换机接口的IP地址:在交换机上选择要配…

光伏无人机巡检都有哪些功能?

随着光伏产业的快速发展,光伏电站的巡检工作变得越来越重要。然而,传统的人工巡检方式面临着效率低下、安全隐患大等问题。为了应对这些挑战,光伏无人机巡检应运而生,以其独特的优势在光伏巡检领域发挥着越来越重要的作用。本文将…

有意思的数组

var nums [1,2,3,6] const nums1 [6, 8, 7, 10, 9];/* 数组合并————push */ var n nums.push(...nums1); // 将列表 nums1 拼接到 nums 之后 n //n会是nums的长度 > 9 nums //也push了 > (9) [1, 2, 3, 6, 6, 8, 7, 10, 9]/* 数组合并————concat*/ var arr0…

ArcGIS arcpy代码工具——关于标识码的那些事(查找最大标识码、唯一性检查、重排序、空值赋值)

系列文章目录 ArcGIS arcpy代码工具——批量对MXD文件的页面布局设置修改 ArcGIS arcpy代码工具——数据驱动工具批量导出MXD文档并同步导出图片 ArcGIS arcpy代码工具——将要素属性表字段及要素截图插入word模板 ArcGIS arcpy代码工具——定制属性表字段输出表格 ArcGIS arc…