RTMP协议详解

RTMP协议详解本篇博客主要讲解 RTMP 协议重点 包括握手 连接 消息类别以及解码后各类型帧的缓存帧数设置等内容

大家好,欢迎来到IT知识分享网。

本篇博客主要讲解RTMP协议重点,包括握手、连接、消息类别以及解码后各类型帧的缓存帧数设置等内容。


本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习,梳理总结后写下文章,对音视频相关内容感兴趣的读者,可以点击观看课程网址:零声教育


1. RTMP

传输基本流程:

在这里插入图片描述

2. RTMP协议

首先进行tcp三次握手,通过TCP三次握手,可实现RTMP客户端与RTMP服务器的指定端口(默认端口为1935)建立一个可靠的网络连接。
在这里插入图片描述

2.1握手
RTMP握手分为简单握手复杂握手
实际实现中为了在保证握⼿的身份验证功能的基础上尽量减少通信的次数,⼀般的发送顺序如下所示,可以通过wireshark抓ffmpeg推流包进⾏验证:
| client | Server |
|---C0+C1---> |
|<--S0+S1+S2-- |
|----C2----> |
简单握手:
在这里插入图片描述
简单握手:








  • C1和S1,4个字节表示时间,4个字节0,从第9个字节开始为随机数。
  • S2是C1的复制,C2是S1的复制
  • C0和S0都有8个字节,代表协议版本号,C0(客户端版本)、S0(服务器版本),目前版本为3。

复杂握手:
复杂握手将简单握手中1528比特的随机数部分平分为两部分。
1.764比特的public key(公共密匙)
2.764比特的digest(32字节的密文)
复杂握手的Version部分不为0,服务器可以由此判断握手类型。
2.2 连接
不同的Application Instance可根据功能等进行划分,例如,直播->live,点播回放->vod。
在这里插入图片描述
2.3 创建逻辑通道(流)
creatStream命令用于创建逻辑通道,用来传输视频、音频和metadata。
服务器的响应报文中会返回Stream ID,标识改Stream。
2.4 play
客户端发送play命令播放指定流。
想要立即播放,需要先清空play队列中的其他流,并将reset置为true。
2.5 删除流deleteStream
删除指定Stream ID的流,服务器就不用对这条命令发送响应报文
2.6 RTMP层次关键结构
在这里插入图片描述
对于FLV的tag而言,对应RTMP中每个message。
在这里插入图片描述
2.7 消息分类
消息主要分为三类: 协议控制消息、数据消息、命令消息等。




















  1. 协议控制消息
    Message Type ID = 1 2 3 5 6和Message Type ID = 4两大类,主要用于协议内的控制
  2. 数据消息
    Message Type ID = 8 9 18
    8: Audio 音频数据
    9: Video 视频数据
    18: Metadata 包括音视频编码、视频宽高等信息



  3. 命令消息
    Command Message ID = 20 17
    此类型消息主要有NetConnection和NetStream两个类。
    在这里插入图片描述


2.8 RTMP实质
•发送端
首先将数据加工成消息(中间物),然后再将消息分割成
hunk(加上Chunk Header),然后将Chunk通过网络发送出去。
•接收端
接收端将接收到的Chunk组装成消息。




2.9 RTMP Chunk Header
RTMP Chunk Header包含Basic HeaderMessage Header和Extended Timestamp三种,其长度不是固定的,分为:12 Bytes、8 Bytes、4 Bytes、1 Byte 四种,由RTMP Chunk Header2位决定。

前2 Bits Header Length 说明
00 12 bytes MetaData流刚开始的绝对时间戳
视频帧流刚开始的绝对时间戳
音频流刚开始的绝对时间戳
connect控制消息


01 8 bytes 常见类型
10 4 bytes 比较少见
11 1 bytes 偶尔会出现 频率远远低于8 Bytes

RTMP Basic Header 一般为1字节。

  • 一般情况下, msg stream id是不会变的,所以针对视频或音频, 除了第一个RTMP Chunk Header是12Bytes的,后续即可采用8Bytes的。
  • 如果消息的长度(message length)和类型(msg type id,如视频为9或音频为8)又相同,即可将这两部分也省去, RTMP Chunk Header采用4Bytes类型的。
  • 如果当前Chunk与之前的Chunk相比, msg stream id相同, msg typeid相同, message length相同,而且都属于同一个消息(由同一个Message切割成),这类Chunk的时间戳(timestamp)也是相同的,故后续的也可以省去,RTMP Chunk Header采用1 Byte类型的。

2.10 时间戳:

RTMP时间戳为相对于某个时间点的相对值,单位为毫秒(ms)

  • 时间戳的长度为32bit,不考虑回滚的话,最大可表示49天17小时2分钟47.296秒
  • Timestamp delta 单位也是毫秒,为相对于前一个时间戳的一个无符号整数;可能为24bit或32bit。
  • RTMP Message的时间戳 4个字节
  • 大端存储

rtmp流的chunk视频流(或音频流)除第一个视频时间戳为绝对时间戳外,后续的时间戳均为timestamp delta,即当前时间戳与上一个时间戳的差值。比如帧率为25帧/秒的视频流, timestamp delta基本上都为40ms。
在这里插入图片描述
一般chunk的时间戳timestamp3字节,当时间戳值超过0xFFFFFF时,启用Extend Timestamp(4字节)

3.音视频解码后帧队列

#define VIDEO_PICTURE_QUEUE_SIZE 3 // 图像帧缓存数量 #define SUBPICTURE_QUEUE_SIZE 16 // 字幕帧缓存数量 #define SAMPLE_QUEUE_SIZE 9 // 采样帧缓存数量 #define FRAME_QUEUE_SIZE FFMAX(SAMPLE_QUEUE_SIZE, FFMAX(VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE)) 

补充:

在这里插入图片描述

2.推流没有问题时,如果拉流不能正常播放:

  1. 没有声音: dump rtmp拉流后的数据是否可以正常播放
  2. 声音异常:是否有解码错误报告,重采样前的pcm数据是否正常
  3. 没有图像: dump rtmp拉流后的数据是否可以正常播放
  4. 画面异常:是否有解码错误报告, scale前的数据是否正常

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/125211.html

(0)
上一篇 2025-09-29 15:33
下一篇 2025-09-29 15:45

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信