前文《为什么要设计chunk分片》 讲解了 切片 chunk 的好处,所以 对于 RTMP 协议来说,他的 传输单元是 chunk。一个 RTMP 包就是一个 chunk。所以 chunk 的格式,也就是 RTMP 报文的格式。

chunk 的格式如下:

可以看到 Chunk Header 由 3 部分组成。

  1. Basic Header
  2. Message Header
  3. Extended Timestamp

先来 讲解 Basic Header 的格式,Basic Header 由 fmt + chunk stream id 组成,fmt (也叫 chunk type)固定是 2 位。但是 cs id 可以是 6位,也可以是 14 位,也可以是 22 位。

所以 Basic Header 可以是 1个 字节,也可以是2个字节或者 3个字节,这里不太好懂他的变长是如何实现的。我详细讲一下。

Basic Header 占一个字节的情况如下:

从上图可以看到 前面 2位 是 fmt ,这个字段主要用在后面,暂时不讲。然后还剩 6 位空间没用,所以 cs id 的范围应该是 0 ~ (2^6 - 1) ,也就是 0 ~ 63 。但是因为要实现变长数据,所以不能 直接是用 0~ 63,要预留 一些值作为标记。0~2 就是标记,也就是说 这 6位的数据不能是 0 到2。

所以 Basic Header 是 1个字节的情况下,3 ~ 63 才是 cs id 的取值范围。

接下来讲解 0 ~ 2 是怎么处理的。

1,第一个字节的后6位 如果是 000000,说明后面还有一个字节,就读取后面的一个字节,一个字节最多是 2^8 = 256 ,那是不是说,2字节的 情况下 cs id 的范围 是 0 ~ (2^8 - 1) ,也就是 0 ~ 255。不是,不能这样算,因为是之前一个字节不够用 才扩展到2个字节,所第二个字节的起始值是64,不是从0开始,所以 cs id 的范围 是 64 ~ 255 + 64。

所以 Basic Header 是 2个字节情况下,cs id 的范围是 64 ~319, cs id 不会是 64 以下的值,因为那是一个字节的情况。

2,第一个字节的后6位 如果是 000001,代表后面还有2个字节,两个字节能表示 0 ~ 65535,但是起始值是64,所以 cs id 的范围 是 64 ~ 65535 + 64。

所以 Basic Header 是 3个字节情况下,cs id 的范围是 64 ~ 65599,同时 cs id 不会是 319 以下的值,因为那是两个字节的情况。

纠正:3个字节情况下 cs id 可能是 319 以下的值,只是RTMP 标准说尽量用更少的字节。319以下的值也可以用3字节表示,只不过没必要。

3,第一个字节的后6位 如果是 000002,代表这个RTMP 包是一个 Protocol Control Messages。


接下来分析 Message Header,由于 Message Header 受到 Basic Header 的 fmt 字段影响,fmt 占 2位,所以 有 4 种 Message Header 。

Message Header 看标准文档跟 这篇文章 《rtmp协议详解》 就行,讲得很详细。


Chunk header 已经讲解完毕,还有两个 重点 没有讲解。

1,chunk stream id 是什么东西?

chunk stream id 缩写是 cs id,也就是 RTMP 包开头的 1~3个字节那个地方的数据。这个 cs id 是 chunk 流ID,每个 TCP 链接 可以有多个 cs id。 cs id 要结合 message stream id 来理解。

2,message stream id 是什么东西。

message stream id 就是消息的流ID,例如 音频流的 message stream id 是 1,视频流的 message stream id 是 2。

但是 视频流,音频流 对应的 cs id 可以是同一个。这就叫多路复用。多个流复用一个流通道。


接下来讲解,几种常用的 RTMP 包,括号() 里面的值是 message header 里面的 type id 。

1,Set Chunk Size (1):通知对面 自己会按照 这个 大小来切分数据。

2,Abort Message (2):中断,很少使用。

3,Window Acknowledgement Size (5):告诉发送方,我接受到这么多的数据之后就会发 Acknowledgement (3) 的RTMP包。

4,Acknowledgement (3) :确认已经收到多少数据。

实际 Window Acknowledgement Size 跟 Acknowledgement 非常鸡肋,因为 TCP 本身有滑动窗口跟ACK。所以一般 Window Acknowledgement Size 会设置得非常大。

5,Set Peer Bandwidth (6):客户端或服务端发送该消息来限制对端的输出带宽, 标准文档里面没有讲得很清楚,这个是限制带宽是怎么实现了,网上搜了,大多数也是英文的直接翻译,也没讲得特别清楚,这个逻辑要在源码里面找,先埋个坑,后续填。


RTMP 里面 经常见到的一种包 是 Action Message Format (AMF)。看名字就知道,这是一个 action 包。这种 RTMP 包的 message header 里面的 type id 是 0x14

例如,connect 就是一个 AMF 包,如下:

releaseStream ,FCPublish ,createStream_result 等等也是一个 AMF 包,他们 message header 里面的 type id 都是 0x14。

这种 AMF 包里面有一个 字符串,表示要执行哪些 action (动作)。


上面的RTMP chunk 格式,是 RTMP 协议栈内部的东西,对我们调用层来说是透明的,也就是说他内部切成多少chunk,message header 是怎样的,我们调用层不需要特别关注。

调用层真正丢向 RTMP 协议栈的数据格式是 RTMP Message Format。

重点: RTMP Chunk Format 是协议栈内部的,RTMP Message Format 是调用层自己的。

RTMP Message Format 的头部格式如下:

头部后面就是实际的音频或者视频数据,Payload length 就是调用层发出去的包的总大小。这里第一个字节是 Message Type,在RTMP 协议栈内部会 转换成 Chunk 格式里面的 Message Header 里面的 type id。

补充: 实际上这个 RTMP Message Format 实际实现中并不存在,例如 librtmp 项目里,并没有提供一个接口 传递上面这种 RTMP Message Format 格式的buff。是直接到 Chunk Format 这一层。


调用层还有一个 User Control Messages 格式,对应的 chunk 格式就是 chunk 格式里面的 6位 cs id 等于 000010,也就是 等于2,然后 message header 的 type id 等于 4。

他标准文档 写的这些 User Control Messages 格式 跟 RTMP Message Format 实际上在实现的时候都是没有的,都是直接转成 chunk 格式发送。这个层是个虚拟层。


后续的 请看 标准文档,标准文档第 22 页开始,都是 在讲 message header 里面的 type id 的有多少种情况。


重点补充:

createStream 命令是向服务器请求 一个 Stream ID。应该是。

AMF 包 会有一个 trans id 事务ID,然后服务器会返回一个 _result 带着客户端的 trans id ,表示执行成功或失败。

AMF 大部分都是远程过程调用。

还有一些 play, pause 也是 AMF 包,type id 是14。


相关阅读:

  1. 《rtmp协议详解》
  2. 《手撕Rtmp协议细节(6)》
  3. 《RTMP 协议学习(上): 协议规范》

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。

RTMP协议分析-chunk格式相关推荐

  1. RTMP 协议MP4(f4v)格式视频VOD点播实现过程

    RTMP 协议MP4(f4v)格式视频VOD点播实现过程 大致过程如下(未考虑Seek.客户端SetBufferLength指令等): 1. flash player发送play点播指令 2. 服务器 ...

  2. rtmp协议分析(三次握手)

    RTMP详细分析(Message 消息,Chunk分块) librtmp分析(发送数据包处理) librtmp分析(接收数据包处理) RTMP协议是Real Time Message Protocol ...

  3. 音视频 RTMP协议分析

    理解字节序 大小端模式 理解字节序 Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端:Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的 ...

  4. RTMP协议分析及推流过程

    简介: 1.RTMP(实时消息传输协议)是Adobe 公司开发的一个基于TCP的应用层协议. 2.RTMP协议中基本的数据单元称为消息(Message). 3.当RTMP协议在互联网中传输数据的时候, ...

  5. 【RTMP协议分析与抓包实测】

    传输协议 RTMP基本通讯 RTMP基于TCP之上传输 TCP三次握手,相关文章链接,TCP三次握手流程 进行握手 c:s 发送c0+c1 c:s 发送c2 s:c 发送s0+s1+s2 建立RTMP ...

  6. (转)rtmp协议简单解析以及用其发送h264的flv文件

    Adobe公司太坑人了,官方文档公布的信息根本就不全,如果只按照他上面的写的话,是没法用的.按照文档上面的流程,server和client连接之后首先要进行握手,握手成功之后进行一些交互,其实就是交互 ...

  7. 【Android RTMP】RTMP 数据格式 ( FLV 视频格式分析 | 文件头 Header 分析 | 标签 Tag 分析 | 视频标签 Tag 数据分析 )

    文章目录 安卓直播推流专栏博客总结 一. RTMP 格式解析 二. 文件头 Header 分析 三. 标签 Tag 分析 四. 视频标签 Tag 数据分析 安卓直播推流专栏博客总结 Android R ...

  8. 流媒体传输 - RTMP 协议报文分析

    握手之后,连接开始对一个或多个 chunk stream 进行合并.创建的每个块都有一个唯一 id 对其进行关联,这个 id 叫做 chunk stream id.这些块通过网络进行传输.传递时,每个 ...

  9. RTMP协议详解及实例分析

    1.简介 RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiple ...

  10. RTMP协议中的Chunk Stream ID (CID)的作用

    一.协议分层 RTMP包是以Message的结构封装的,结构如下所示: 1)Message Type ID在1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需 ...

最新文章

  1. The HipHop Virtual Machine
  2. sqlserver sql行专列_sqlserver----记录转载(行转列)、列转行、pivot、unpivot
  3. (chap4 IP协议) IP协议
  4. C++ hamming distance汉明距离算法(附完整源码)
  5. 建立Vue脚手架的必要性
  6. gdb 收到SIGPIPE信号
  7. 【算法】剑指 Offer 50. 第一个只出现一次的字符
  8. java gc 例子_Java GC.drawImage方法代码示例
  9. 吴恩达深度学习1.3笔记_Neural Networks and Deep Learning_浅层神经网络
  10. AnyChat视频直播系统全面分析
  11. Andrew ng清华报告听后感
  12. 曼昆经济学原理_第五版[1].txt.doc
  13. idea解決tomcat乱码问题
  14. android微信红包提醒,微信红包提醒怎么设置 微信红包提醒设置教程
  15. 软考_信息系统项目管理师_信息系统项目管理基础
  16. matlab制作水印,怎么在含有水印的图像中提取出水印
  17. CAA-几何图形集下直接添加参数
  18. #今日论文推荐# 中国矿大团队,开发集成多尺度深度学习模型,用于 RNA 甲基化位点预测
  19. 虚幻引擎中的节流与防抖
  20. 双软企业税收优惠政策

热门文章

  1. 计算机刷bios版本,详细教你电脑刷bios
  2. Ansible 运维自动化 ( 配置管理工具 )
  3. 仓库管理系统论文+源程序+执行程序,
  4. ppt保存为高分辨率图片(ppt2016)
  5. 天猫要做“大”,京东怕不怕?
  6. 月薪30K+的电子工程师应具备什么?
  7. C语言if else语句详解
  8. BlockUI对话框
  9. win7右键计算机死机,Win7桌面点击右键死机的解决方法
  10. FileUpload1.PostedFile.FileName未找到文件或者上传失败