QT实现RTMP推流H264文件客户端

QT实现RTMP推流H264文件客户端
1.项目使用流程
打开SRS服务器,需要安装的话看 3.环境布置
打开 \RTMPClient\build\Desktop_Qt_6_9_1_MinGW_64_bit-Debug\debug\RtmpClient.exe
用ffmpeg命令行,ffplay rtmp://127.0.0.1:1935/live/stream1,就可看到画面

1.项目目的
不依赖SRS等库,实现一个rtmp推流客户端,
功能是将本地h264视频文件推流给SRS服务器,能用VLC或ffmpeg打开对应rtmp流地址播放
旨在了解学习rtmp协议

2.项目流程
推流客户端-->SRS服务器-->拉流服务器
推流客户端 --本次需要实现的程序,将h264文件数据通过rtmp协议推流到SRS服务器
SRS服务器 --作为枢纽,接收推流数据进行分发
拉流服务器 --ffmpeg/VLC,用于打开rtmp流地址进行播放

3.环境布置
3.1SRS服务器,需要先安装SRS服务器
如用Windows-x86_64系统可用,提供的SRS-Windows-x86_64-6.0-d6-setup.exe进行安装,其他系统需自行再找教程安装
安装完成后在 /SRS 路径下,用命令行objs\srs.exe -c conf\srs.conf启动SRS服务器,默认地址127.0.0.1:1935
3.2之后可用ffmpeg推流,如用命令行
ffmpeg -re -i test15.h264 -c:v libx264 -preset fast -crf 23 -c:a aac -f flv rtmp://127.0.0.1:1935/live/stream1
3.3用VLC打开目标rtmp地址(3.2中的rtmp://127.0.0.1:1935/live/stream1),正常就可播放
(如果想看h264文件的结构,可以打开H264 NALU分析器网址(https://nalu.qer.im/),拖入文件可看)

4.推流客户端程序的项目结构
rtmpClient --负责rtmp的连接建立与视频数据发送
H264Parser --负责读取H264文件,拆分成单独Nalu数据,解析SPS数据得到视频参数
Amf0Helper. --Amf0编解码函数
bs.h --读取哥伦布编码数据的函数,用于解析SPS数据

5.推流过程与学习点
整个过程概括:与服务器rtmp握手 --> rtmp控制交互 --> 开始推流

5.1.与服务器rtmp握手
客户端tcp连接服务器后发送,Handshake C0+C1
服务器返回消息,Handshake S0+S1+S2
客户端发送,Handshake C2
(到这里rtmp握手完成)

5.2.rtmp控制交互
客户端端发送,Set Chunk Size 60000
(这里需要学习rtmp的控制消息怎么发,比如,一个RTMP消息为一个Chunk,Chunk有RTMP Header和RTMP Body组成,RTMP Header是怎么组成的等)
客户端发送,connect('live')
(这里需要学习rtmp的RTMP Body的数据是怎么添加的,比如AMF0字符串类型标记为0x02,对象的标识符对象为0x03等)

服务器发来,Set Chunk Size 60000
(注意这里的Set Chunk Size与客户端发送的作用不同,
//客户端->服务器,通过发送Set Chunk Size消息,设置自己向服务器发送 Chunk 时的最大块大小
//服务器->客户端,通过发送Set Chunk Size消息,设置自己向客户端发送 Chunk 时的最大块大小

服务器发来,_result('NetConnection.Connect.Success')
(表示 connect('live') 成功)
客户端发送,createStream()
服务端发送,_result()
(需确认与_result() RTMP Body中的事务id与 createStream() RTMP Body中的事务id一致,再解析出_result() RTMP Body中的streamid,这个streamid用于后面的推流)
客户端发送,publish('stream1')
(请求开始推流)
服务器发来,onStatus('NetStream.Publish.Start')
(表示可以开始推流)

5.3.开始推流
客户端发送,@setDataFrame()
(这里是设置视频元数据,主要是一些配置,如分辨率、帧率、H264档次、H264等级等;这些数据大多由SPS解析得到,
SPS解析指数哥伦布编码可以看提供的文档"H.264标准-中文版.pdf"中的 7.3.2.1 序列参数集RBSP 语法,H264Parser::parse_h264_sps中的实现完全按文档规定实现)
客户端发送,Video Data
(先发送SPS+PPS数据,给服务器初始化解码器,注意fmt、CSID的设置,如CSID行业约定视频流用0x06等)
客户端发送,Video Data
(发送的第一帧关键帧,这里发送SPS/PPS数据后)
客户端发送,Video Data
(发送的非关键帧,这里进行了RTMP Header部分复用,需要学习fmt的不同值对应不同RTMP Header的规定)

整个流程概括完成,以上流程可以用WireShark抓包,看到对应流程

6.其他学习的点
6.1 SRS服务器的日志是 \SRS\objs\srs.log,需要注意不要在打开日志的情况下,去启动客户端推流,会连接断开
6.2 SRS服务器日志的部分识别,
48B video sh, codec(7, profile=High, level=3.2, 1366x768, 0kbps, 0.0fps, 0.0s)
//表示解码器初始化完成

CircuitBreaker: cpu=85.13%,34MB, break=1,0,0, cond=85.13%
//CircuitBreaker是 SRS 的过载保护机制:当 CPU 使用率超过阈值(默认通常 80%-90%),会触发 “熔断”,限制或停止处理新请求 / 流数据,避免服务器溃;
//需要注意不要无限制快速发送视频数据到SRS服务器,可以改成定时间隔发送

-> HLS time=64417387ms, sno=3, ts=stream1-2.ts, dur=12144ms, dva=0p
//表明有在正常生成HLS 切片,至于dva=0p可以忽略不管

6.3 大分辨下的分片操作
当客户端发送Video Data,其中的RTMP Body大于客户端Set Chunk Size的60000时,需要进行分片再发送
分片发送例子如,可以修改本项目程序打开test16_1080p.h264文件

posted @ 2025-11-30 10:09  lizhizizi  阅读(1)  评论(0)    收藏  举报