1. Android 直播推流简介:
2. 带你吃透RTMP:
附:RTMP 协议整理成脑图,⽐较清晰,包括rtmp 消息类型,rtmp 分块chunking,rtmp分块例⼦。免费脑图⼯具 格式, 1. rtmp 消息类型
Paste_Image.png
2. rtmp 消息分块
Paste_Image.png
1. 简介
RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的⼀种应⽤层的协议,⽤来解决多媒体数据传输流的多路复⽤(Multiplexing)和分包(packetizing)的问题。随 着VR技术的发展,视频直播等领域逐渐活跃起来,RTMP作为业内⼴泛使⽤的协议也重新被相关开发者重视起来。本⽂主要分享对RTMP的⼀些简介和实际开发中遇到的⼀些状况。
RTMP协议基本特点:
· 基于TCP协议的应⽤层协议
应力应变曲线
· 默认通信端⼝1935
RTMP URL格式:
rtmp://ip:[port]/appName/streamName
例如: rtmp://192.168.178.218:1935/live/devzhaoyou
2. RTMP 握⼿
RTMP 握⼿分为简单握⼿和复杂握⼿,现在Adobe公司使⽤RTMP协议的产品⽤复杂握⼿的较多,不做介绍。
握⼿包格式:
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
| version |
+-+-+-+-+-+-+-+-+
C0 and S0 bits
C0和S0:1个字节,包含了RTMP版本, 当前RTMP协议的版本为 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| zero (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random bytes |原罪感
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
axara
| random bytes |
| (cont) |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
C1 and S1 bits
C1和S1:4字节时间戳,4字节的0,1528字节的随机数
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| time2 (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random echo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random echo |
| (cont) |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
C2 and S2 bits
C2和S2:4字节时间戳,4字节从对端读到的时间戳,1528字节随机数RTMP握⼿基本过程:
+-------------+ +-------------+
| Client | TCP/IP Network | Server |
+-------------+ | +-------------+
| | |
Uninitialized | Uninitialized
| C0 | |
|------------------->| C0 |
| |-------------------->|
| C1 | |
|------------------->| S0 |
| |<--------------------|
| | S1 |
Version sent |<--------------------|
| S0 | |
|<-------------------| |
| S1 | |
|<-------------------| Version sent
| | C1 |
| |-------------------->|
| C2 | |
|------------------->| S2 |
| |<--------------------|
Ack sent | Ack Sent
| S2 | |
|<-------------------| |
| | C2 |
| |-------------------->|
Handshake Done | Handshake Done
| | |
Pictorial Representation of Handshake
握⼿开始于客户端发送C0、C1块。服务器收到C0或C1后发送S0和S1。 当客户端收齐S0和S1后,开始发送C2。当服务器收齐C0和C1后,开始发送S2。
当客户端和服务器分别收到S2和C2后,握⼿完成。
注意事项: 在实际⼯程应⽤中,⼀般是客户端先将C0, C1块同时发出,服务器在收到C1 之后同时将S0, S1, S2发给客户端。S2的内容就是收到的C1块的内容。之后客户端收到S1块,并原样返回给服务器,简单握⼿完成。按照RTMP协议个要求,客户端需要校验C1块的内容
和S2块的内容是否相同,相同的话才彻底完成握⼿过程,实际编写程序⽤⼀般都不去做校验。
RTMP握⼿的这个过程就是完成了两件事:
校验客户端和服务器端RTMP协议版本号
是发了⼀堆随机数据,校验⽹络状况。
3. RTMP 消息东盟论坛
RTMP消息格式:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Message Type | Payload length |
| (1 byte) | (3 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp |
| (4 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Stream ID |
| (3 bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Message Header
· 1字节消息类型
· 3字节负载消息长度
· 4字节时间戳
· 3字节 Stream ID,区分消息流
注意事项: 实际RTMP通信中并未按照上述格式去发送RTMP消息,⽽是将RTMP 消息分块发送,之后将介绍RTMP消息分块。
3.1. RTMP 消息分块(chunking)
⽽对于基于TCP的RTMP协议⽽⾔,协议显得特别繁琐,但是有没有更好的替代⽅案。同时创建RTMP消息分块是⽐较复杂的地⽅,涉及到了AFM(也是Adobe家的东西)格式数据的数据。
RTMP消息块格式:
+--------------+----------------+--------------------+--------------+
| Basic Header | Message Header | Extended Timestamp | Chunk Data |
+--------------+----------------+--------------------+--------------+
| |
|<------------------- Chunk Header ----------------->|
Chunk Format
RTMP消息块构成:
· Basic Header
· Message Header
· Extended Timestamp
· Chunk Data
Chunk Basic header格式有3种:
格式1:
0 1 2 3 4 5 6 7
中国新诗派
+-+-+-+-+-+-+-+-+
|fmt| cs id |
+-+-+-+-+-+-+-+-+
Chunk basic header 1
格式2:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt| 0 | cs id - 64 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk basic header 2
格式3:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|fmt| 1 | cs id - 64 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk basic header 3
嘌呤代谢紊乱注意事项:
fmt: ⽤于指定Chunk Header ⾥⾯ Message Header的类型,后⾯会介绍到
cs id: 是chunk stream id的缩写,同⼀个RTMP消息拆成的 chunk 块拥有相同的 cs id, ⽤于区分chunk所属的RTMP消息, chunk basic header 的类型cs id占⽤的字节数来确定
Message Header格式:
Message Header的类型通过上⽂chunk basic header中的fmt指定,共4种:
格式0:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp | message length|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message length (cont) |message type id| msg stream id |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| message stream id (cont) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Message Header - Type 0
Message Header占⽤11个字节, 在chunk stream的开始的第⼀个chunk的时候必须采⽤这种格式。
· timestamp:3个字节,因此它最多能表⽰到16777215=0xFFFFFF=2^24-1, 当它的值超过这个最⼤值时,这三个字节都置为1,实际
的timestamp会转存到Extended Timestamp字段中,接受端在判断timestamp字段24个位都为1时就会去Extended timestamp中解析实际的时间戳。
· message length:3个字节,表⽰实际发送的消息的数据如⾳频帧、视频帧等数据的长度,单位是字节。注意这⾥是Message的长度,也就是chunk属于的Message的总数据长度,⽽不是chunk本⾝Data的数据的长度。
· message type id:1个字节,表⽰实际发送的数据的类型,如8代表⾳频数据、9代表视频数据。
·
msg stream id:4个字节,表⽰该chunk所在的流的ID,和Basic Header的CSID⼀样,它采⽤⼩端存储的⽅式
格式1: