推流过程
1 握手过程
-
建立tcp连接,发送 C0, C1 消息
C0:1字节,整数,请求使用的RTMP版本(基本就是版本3)
C1:1536字节,时间戳(4字节) + 全零(4字节) + 随机数(1528字节),基本没什么用,按要求生成就行
发送 C0, C1
-
- 等待 S0, S1 消息
服务端生成并返回 S0, S1 消息,规则与 C1, S1 相同
- 等待 S0, S1 消息
(备注:截图中,全零4字节并没有按要求设置,因为这个无关紧要,基本不会检查这个要求)
-
发送 C2 消息
C2: 1536字节,S1的时间戳(4字节) + 接收时间戳(4字节) + S1的随机数
发送 C2
-
- 等待 S2 消息
生成规则与 C2 相同
收到 S2
(备注:截图中,其实S0S1S2是同时收到的,服务端收到C1后,直接发送S0S1S2,这是最简单直接的方式)
- 等待 S2 消息
- 握手完成
服务端也是类似的流程
(refs: https://rtmp.veriskope.com/docs/spec/#525handshake-diagram)
- 握手完成
2. 发送推流相关命令
- connect('live')
连接到 live 这个 app(此处假设推流地址为 rtmp://127.0.0.1/live/stream)。
命令使用 MessagePacket 的方式发送,MessagePacket 会拆分为若干个 ChunkPacket 发送,当接收方收到 MessageHeader 里面给出的 MessageLength 大小的数据后,就可以拼装一个完整的 MessagePacket。
ChunkPacket
MessageHeader
- connect('live')
命令数据格式:
BasicHeader(1/2/3B) + MessageHeader(0/3/7/11B) + Ts(0/4B) +
AMF0/AMF3
BasicHeader:
Fmt(2bits) + ChunkStreamID(6bits)
Fmt决定 MessageHeader 使用 0/3/7/11 中的一种格式
Fmt: 0 使用11字节格式
Fmt: 1 使用7字节格式,以此类推
AMF命令格式:
命令名称(String) + 事务ID(Number) + 参数(Object)
AMF0格式:数据类型(1B) + 数据
(amf0 refs: https://rtmp.veriskope.com/pdf/amf0-file-format-specification.pdf)
(amf3 refs: https://rtmp.veriskope.com/pdf/amf3-file-format-spec.pdf)
(注:截图中,transactionID:1 中,第一个字节(0x00)表示这个是 amf0 number,后面的字节(0x3ff0...)是浮点数1的内存数据)
- createStream()
创建流
- createStream()
- publish('stream')
发布 stream 流
- publish('stream')
- 命令交互完成,准备发送数据
(refs: https://rtmp.veriskope.com/docs/spec/#731-publish-recorded-video)
- 命令交互完成,准备发送数据
3. 发送数据
数据也是跟命令一样使用 MessagePacket ChunkPacket 的方式发送。MessageHeader 里设置 MessageTypeID 为 9 则表示这个是视频数据。
其他 MessageTypeID :
0x01 = Set Packet Size Message.
0x02 = Abort.
0x03 = Acknowledge.
0x04 = Control Message.
0x05 = Server Bandwidth
0x06 = Client Bandwidth.
0x07 = Virtual Control.
0x08 = Audio Packet.
0x09 = Video Packet.
0x0F = Data Extended.
0x10 = Container Extended.
0x11 = Command Extended (An AMF3 type command).
0x12 = Data (Invoke (onMetaData info is sent as such)).
0x13 = Container.
0x14 = Command (An AMF0 type command).
0x15 = UDP
0x16 = Aggregate
0x17 = Present
数据格式:
BasicHeader + MessageHeader + VIDEODATA/AUDIODATA
在RTMP里面,音视频数据使用 flv10.1里面定义的VIDEODATA/AUDIODATA格式
VIDEODATA格式:
FrameType(4bits) + CodecID(4bits) + AVCPacketType(1B) + CTS(3B) + Data(seq/AVCNaluData)
FrameType: key(1), inter(2) 等
CodecID: avc(7) 等
AVCPacketType: seq header(0), nalu(1), end(2)
(refs: https://rtmp.veriskope.com/pdf/video_file_format_spec_v10_1.pdf - page78 )
AUDIODATA格式:
SoundFormat(4bits) + SoundRate(2bits) + SoundSize(1bit) + SoundType(1bit) + AACPacketType(1B) + Data(seq/AACData)
SoundFormat: MP3(2), AAC(10), SPEEX(11) 等
SoundRate: 5.5kHz(0), 11kHz(1), 22kHz(2), 44kHz(3)
SoundSize: 8位(0), 16位(1)
SoundType: MONO(0), STEREO(1)
AACPacketType: seq header(0), raw(1)
(refs: https://rtmp.veriskope.com/pdf/video_file_format_spec_v10_1.pdf - page76 )
4. 停止推流
断开 tcp 连接,服务端判定为停止推流
播放过程与推流类似
相关资料
https://blog.csdn.net/u013637931/article/details/108318996 - RTMP协议文档中文
https://rtmp.veriskope.com/docs/spec/ - RTMP协议文档英文
https://community.adobe.com/t5/media-server-discussions/fms-is-there-some-secret-reference-i-don-t-know-about/m-p/4273450 - 关于 releaseStream/FCPublish
https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol - wikipedia rtmp protocol