FEATURED · 精选文章

为什么几乎只能用flv的媒体封装格式进行RTMP推流?

发布时间 / 2026/8/12 9:54:35
来源 / 创域科博编辑部
栏目 / 资讯中心
为什么几乎只能用flv的媒体封装格式进行RTMP推流? 目录一、先理清两层东西RTMP 是协议FLV 是容器二、为什么 RTMP 选 FLV 而不是 MP4 / TS1. 历史绑定Adobe 全家桶闭环2. FLV 是为真流式生的MP4 是为存储生的3. FLV Tag 粒度 一帧一包正好映射 RTMP Message4. Codec 描述信息有标准落点三、RTMP 传 FLV 的实际封装链推流端视角四、RTMP 只支持 FLV 的准确边界五、一句话总结觉得有用就请您帮忙点赞转发收藏吧您的鼓励是我创作的动力多谢看官。由于能力水平有限文中的错误或不严谨的地方在所难免还请批评指正。RTMP 协议本身虽未明文禁止其他封装但其音视频通道Message Type 8/9的payload 格式直接复用 FLV Tag 定义——Video Message 里塞的就是 FLV VideoTagHeaderFrameTypeCodecIDAVCPacketTypeCTS加 NALUAudio Message 同理塞 FLV AudioTagHeader 加 AAC frame。这是 Adobe 当年为 Flash 生态定的闭环推流端、CDN、播放器全按RTMPFLV流实现MP4 要等 moov 头、TS 要 PCR 同步都不适配边产边推、收即解的低延迟模型。若不用 FLV 封装裸 H264/AAC 缺少帧类型、SPS/PPS 承载位置、CTS 偏移等必填元数据整条 FFmpeg/SRS/nginx-rtmp/OBS 工具链全部无法识别。因此工程上 RTMP 推流几乎只能用 FLV本质是协议与容器历史绑定生态锁死而非协议强制。一、先理清两层东西RTMP 是协议FLV 是容器RTMPReal-Time Messaging ProtocolAdobe 出的应用层协议跑在 TCP/1935 上负责建连、收发 Message、做 Chunk 分片、传指令play/publish 等。FLVFlash VideoAdobe 出的流式容器文件格式定义 Audio Tag / Video Tag / Script Tag 怎么排。两者分属不同规范但数值上刻意对齐RTMP Message Type8 AudioFLV TagType8 AUDIODATARTMP Message Type9 VideoFLV TagType9 VIDEODATARTMP Message Type18 AMF MetadataFLV TagType18 ScriptData也就是说RTMP 的音频/视频 Messagepayload 里放的就是一个 FLV Tag 的 TagHeader TagData不含 FLV 文件级的 FLVHeader 和 PreviousTagSize。服务端收 RTMP 顺手写盘成.flv就是把 Message 直接拼回去。二、为什么 RTMP 选 FLV 而不是 MP4 / TS1. 历史绑定Adobe 全家桶闭环RTMP 和 FLV 都是 Adobe 为 Flash Player 设计的浏览器里 Flash 解码器原生吃 FLV推流端FMLE/OBS/FFmpeg-f flv输出 FLV Tag服务端nginx-rtmp/SRS内部队列存的就是 FLV Tag下发用 RTMP 或 HTTP-FLV播放端同一个解析器复用换 MP4 就得带moov头、走box树、做 seek 索引——直播根本没有完整文件moov 永远凑不出来。2. FLV 是为真流式生的MP4 是为存储生的维度FLVMP4TS启动数据9B Header 首个 Tag 即可播必须拿到 moov几 KB~MB188B 包但无 FLV 那种单 Tag 直塞是否要完整文件否追加写是moov 通常在尾否单帧封装开销TagHeader 11Bbox 嵌套较重188B 固定广播向音视频交织Tag 级交错track 分离PCR 同步复杂直播适配⭐⭐⭐⭐⭐❌⭐⭐⭐广电用FLV 没有 PCR、没有 timescale、没有 stbl 索引收到第一个 Video Tag带 SPS/PPS 的 AVC sequence header就能开播这对 1~3s 低延迟直播是刚需。3. FLV Tag 粒度 一帧一包正好映射 RTMP Message一个 FLV Video Tag ≈ 一帧或一组 NALU 11B 头 CompositionTimeRTMP 把这一帧作为一个 Video Messagetype9​ 发出去Message 太大再按chunk_size默认 128B切成 Chunk 走 TCP裸 H264 NALU 没有 FrameType关键帧/非关键帧、没有 CodecID、没有 AVC packet type、没有 CTS 偏移字段RTMP 接收端根本不知道怎么送解码器。这些字段恰好就是 FLV VideoTagHeader 定义的。4. Codec 描述信息有标准落点FLV规定H264 首包叫AVCDecoderConfigurationRecord存 SPS/PPSAAC 首包叫AudioSpecificConfig存采样率/声道/Profile之后才是 Raw NALU / Raw AAC frameRTMP 自己不在协议里定义码流内部格式只说type9 的 payload 请参考 FLV spec解析。这就把 codec 协商问题甩给 FLV 容器解决协议层不用改。三、RTMP 传 FLV 的实际封装链推流端视角以 FFmpegffmpeg -i x.mp4 -c copy -f flv rtmp://...为例解 MP4 得到 H264 NALU AAC frame封装层按 FLV规范先发一个 Video TagFrameType1, CodecID7, AVCPacketType0sequence header SPS/PPS再每个视频帧一个 Video TagAVCPacketType1 NALU CTS音频同理AAC PacketType0 发 ASC之后 Raw AAC把每个 FLV Tag 的TagHeader(11B)TagData作为 RTMP Message PayloadRTMP 协议头填msg type9timestampptsstream id1Message 按 chunk_size 切 ChunkTCP 发出服务端 SRS/nginx-rtmp 收到后转 RTMP 拉流原样组 Message 下发转 HTTP-FLV拼 FLVHeader Tag 流转 HLS内部 demux FLV Tag → 切 TS录播直接写.flv文件加 FLVHeader 和 PreviousTagSize四、RTMP 只支持 FLV 的准确边界严格说✅ RTMP标准音视频通道type 8/9/18​ 的 payload 格式 FLV Tag 内部定义所以生态里等于只认 FLV❌ RTMP 协议本身没说你不能把 MP4 box 当二进制塞进 type15 命令消息但没人这么干播放器不认❌ 不是 RTMP 不能传别的东西而是不套 FLV Tag 的媒体流整个 Flash/FFmpeg/SRS 工具链全部断掉现代演进RTMP 增强规范比如 Enhanced RTMP已经扩了 H265/AV1 的 FLV CodecID本质还是扩 FLV Tag 定义不是抛开 FLV五、一句话总结RTMP 选 FLV 不是偶然Adobe 同时握着协议和容器FLV Tag 的 11B 头 单帧粒度 无全局索引 毫秒时间戳完美匹配 RTMPTCP 长连、Message→Chunk、边产边推、收到即解的实时模型MP4 要 moov、TS 要 PCR 广播同步都不如 FLV 顺手。于是 RTMP 的音频/视频 Message Payload 直接复用 FLV Tag 定义工程界就简化成了RTMP 只传 FLV。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻