每条信息在传输前都先被分割为若干数据块,这些数据块被称为分块(chunk).
块大小128Byte-65536Byte
大分块cpu负载降低,在低带宽环境传输会延迟;小分块延迟低,但cpu消耗大,不利于高码率传输
格式
分块基本头(chunk basic header)+ 分块消息头(chunk message header) + 拓展时间戳(extended timestamp) + 分块数据(chunk data==Message Payload)
分块头(分块基本头+分块消息头+拓展时间戳):属于 传输层 结构,包含 fmt
(复用类型)和 Chunk Stream ID
(物理通道标识),用于分块传输。
Chunk Data(Message Payload):属于 应用层 消息(Message)的负载(Payload)的分段数据. 定义消息的完整元数据(如时间戳、长度、类型、流ID)。
Chunk Size:每个 Chunk Data 的最大长度(默认128字节),可通过控制消息动态调整。
分块传输规则
-
消息拆分:
- 若消息负载(Message Payload)长度超过 Chunk Size,消息将被拆分为多个块(Chunk)。
- 示例:消息长度=300字节,Chunk Size=128 → 拆分为3块(128+128+44)。
-
分块类型:
- 首块(Type 0/1):携带完整的元数据(Message Header),后续块复用元数据(Type 2/3)。
- 后续块(Type 3):仅包含 Chunk Data,无额外头部(复用前序块的元数据)。
-
重组逻辑:
- 接收端根据 传输层
Chunk Stream ID
和应用层Stream ID
重组完整消息。 - 按顺序拼接所有 Chunk Data,恢复原始消息负载。
- 接收端根据 传输层
分块基本头(chunk basic header)
Chunk Basic Header = fmt + Chunk Stream ID
fmt(Format Type): 占用 高2位(bit 7-6),表示后续 Message Header 的类型(Type 0~3)
块流ID(Chunk Stream ID):取值范围[3,65599]
Chunk Basic Header 长度可以是 1、2 或 3 字节,具体由首字节后6位决定:
| 第1字节 |
|fmt(2位)|streamId(6位),取值[1-62]|
| 第1字节 | 第2字节 |
|fmt(2位)|(6位),取值[0]|streamId=第2字节整型+64,取值[64,319]|
| 第1字节 | 第2字节 | 第3字节 |
|fmt(2位)|(6位),取值[63]| streamId=(第2和第3字节组成的16位整型) + 64,取值[320,65599]|
块流ID范围 | Basic Header长度 | 编码方式 |
---|---|---|
2–63 | 1字节 | 直接存储块流ID |
64–319 | 2字节 | 首字节后6位为0,第二字节为ID-64 |
320–65599 | 3字节 | 首字节后6位为1,后两字节为ID-64 |
分块消息头(chunk message header)
类型取决于Chunk Basic Header的fmt
fmt 值 | 类型 | 长度(字节) | 适用场景 |
---|---|---|---|
0b00 | Type 0 | 11 | 新消息的第一个块(完整元数据) |
0b01 | Type 1 | 7 | 同一流的新消息(省略流ID) |
0b10 | Type 2 | 3 | 同一消息的后续块(仅时间戳增量) |
0b11 | Type 3 | 0 | 完全复用前一个块的元数据 |
Type 0(11字节)
用于新消息的第一个块,一般在分块流的开端或者时间戳回跳(如向后拖动播放)的位置,携带完整元数据:
| 字段 | 字节数 | 说明 |
|--------------------|--------|----------------------------------------------------------------------|
| Timestamp | 3 | 消息的绝对时间戳(单位:毫秒)。若 ≥ 0xFFFFFF,则固定为0xFFFFFF,需扩展为4字节(见后) |
| Message Length | 3 | 消息的总长度(单位:字节) |
| Message Type ID | 1 | 消息类型(如 8=音频,9=视频,18=AMF命令等) |
| Stream ID | 4 | 消息所属流的ID(小端序存储) |
Type 1(7字节)
用于同一流(Stream ID相同)的新消息,省略 Stream ID,表示当前分块与前序分块属于一个信息流(相同
Stream ID)
:
| 字段 | 字节数 | 说明 |
|--------------------|--------|----------------------------------------------------------------------|
| Timestamp Delta | 3 | 相对于前一个消息的时间戳增量:表示当前分块的时间戳与前序分块的时间戳的差值 |
| Message Length | 3 | 消息的总长度 |
| Message Type ID | 1 | 消息类型 |
Type 2(3字节)
用于同一消息的后续块(分块传输时),仅携带时间戳增量,表示当前分块的时间戳和前序分块的时间戳的差值,与前序分块下相同stream id, 且其中信息均为固定长度:
| 字段 | 字节数 | 说明 |
|--------------------|--------|----------------------------------------------------------------------|
| Timestamp Delta | 3 | 时间戳增量(相对于前一个块) |
Type 3(0字节)
完全复用前一个块的元数据,不携带任何字段(适用于连续分块传输)。
当一条信息被拆分为多个分块传输时,后续分块均使用此种分块
Extended Timestamp(扩展时间戳)
当 Type 0/1/2 的 Timestamp 或 Timestamp Delta 值 ≥ 0xFFFFFF(即3字节最大值)时:
- Type 0/1/2 中的 Timestamp 或 Timestamp Delta 固定为 0xFFFFFF。
- 在 Message Header 后添加 4字节的扩展时间戳字段,存储完整的32位时间戳(大端序)。
Basic Header: 0x40 (fmt=0b01, Chunk Stream ID=0)
Message Header:
Timestamp Delta: FF FF FF → 原始值 ≥ 0xFFFFFF,需扩展
Message Length: 00 00 80 → 总长度 0x8000 = 32768字节
Message Type: 09 → 视频数据
Extended Timestamp: 00 01 00 00 → 扩展时间戳 0x01000000 = 16777216ms
Payload: 消息体