Rtmp协议简单分析(一)——协议数据

        首先说下rtmp协议包的格式。握手之后,rtmp传输一个数据默认的长度是128bytes,这128bytes不包括包头的长度,只是数据的长度,文档上面没有说明,很憋了我一段时间,数据超过这个长度之后就要分块,超过128bytes的数据放到下一个块中,以此类推。块大小是可配置的,最大块是65535字节,最小块是128字节。块越大CPU使用率越低,但是也导致大的写入,在低带宽下产生其他内容的延迟。
        Rtmp协议是包头加包体(数据)组成,包头可以是4种长度的任意一种:12、8、4、1等byte(s)。包头包含了Head_Type、时间戳、amf size、amf type、streamID。完整的RTMP包头有12字节,由下面5个部分组成:
用途大小(Byte)含义
Head_Type1包头
TIMER3时间戳
AMFSize3数据大小
AMFType1数据类型
StreamID4流ID

        Head_Type占用RTMP包的第一个字节,这个字节里面记录了包的类型和包的ChannelID。Head_Type字节的前两个Bits决定了包头的长度。

BitsHeader Length
0012 bytes
018 bytes
104 bytes
111 byte

        一个视频流的第一个包必须是12bytes,也就是00,要告诉对方这个流的信息。Head_Type的后面6个Bits记录着ChannelID,其为一下内容:

02Ping 和ByteRead通道
03Invoke通道 我们的connect() publish()和自字写的NetConnection.Call() 数据都是在这个通道的
04Audio和Vidio通道
05 06 07服务器保留,经观察FMS2用这些Channel也用来发送音频或视频数据

      比如传一个视频流,第一个块的head type就是00 00 00 04(0x04)。实测fms用4或者5在传影视频。官方文档上面说head_type可能会不止一个byte,但实际情况用一个byte也够了。
        TiMMER - 时间戳
音视频的播放同步是由时间戳来控制的,单位是毫秒。如果时间戳大于或等于16777215(16进制0x00ffffff),该值必须为16777215,并且扩展时间戳必须出现,4bytes的扩展时间戳出现在包头之后包体之前。这个时间戳一般去flv文件里面每个tag里面的时间戳。
        AMFSize - 数据大小
AMFSize占三个字节,这个长度是AMF长度,其实就是本次数据的长度。
        AMFType - 数据类型
AMFType是RTMP包里面的数据的类型,占用1个字节。例如音频包的类型为8,视频包的类型为9。下面列出的是常用的数据类型:

0×01Chunk Sizechanges the chunk size for packets
0×02Unknown 
0×03Bytes Readsend every x bytes read by both sides
0×04Pingping is a stream control message, has subtypes
0×05Server BWthe servers downstream bw
0×06Client BWthe clients upstream bw
0×07Unknown 
0×08Audio Datapacket containing audio
0×09Video Datapacket containing video data
0x0A-0x0EUnknown 
0x0FFLEX_STREAM_SENDTYPE_FLEX_STREAM_SEND
0x10FLEX_SHARED_OBJECTTYPE_FLEX_SHARED_OBJECT
0x11FLEX_MESSAGE TYPE_FLEX_MESSAGE 
0×12Notifyan invoke which does not expect a reply
0×13Shared Objecthas subtypes
0×14Invokelike remoting call, used for stream actions too.
0×16StreamData这是FMS3出来后新增的数据类型,这种类型数据中包含AudioData和VideoData

        StreamID - 流ID
占用RTMP包头的最后4个字节,是一个big-endian的int型数据,每个消息所关联的ID,用于区分其所在的消息流。
前面说包头有几种长度,第一个长度是12bytes,包含了全部的头信息,第一个数据流也就是流的开始必须是这个长度。
第二种8bytes的包,没有了streamID,发这种包,对方就默认此streamID和上次相同,一个视频数据在第一个流之后都可以使这种格式,比如一个1M的视频,第一次发128bytes用12bytes的包,之后每次发的数据都应该用8bytes的包。当然如果每次都用12bytes也没有问题。
第三种为4bytes,只有head_type和时间戳,缺少的对方认为与之前的一样,实际应用中很难出现。
第四中就只有head_type一个byte。如果一次数据超过了长度(默认是128bytes),就要分块,第一个块是12bytes或者8bytes的,之后的块就是1byte。因为分的N块,每一块的信息都是一样的,所以只需要告诉对方此次包的长度就行了。
        例子:
例如有一个RTMP封包的数据03 00 00 00 00 01 02 14 00 00 00 00 02 00 07 63 6F 6E 6E 65 63 74 00 3F F0 00 00 00 00 00 00 08,数据依次解析的含义 
03    表示12字节头,channelid=3
00 00 00    表示时间戳 Timer=0
00 01 02    表示AMFSize=18
14    表示AMFType=Invoke 方法调用
00 00 00 00 表示StreamID = 0                   //到此,12字节RTMP头结束下面的是AMF数据分析 
02    表示String
00 07    表示String长度7
63 6F 6E 6E 65 63 74    是String的Ascall值"connect"
00    表示Double
3F F0 00 00 00 00 00 00    表示double的0.0 
08    表示Map数据开始


官方文档上面的例子:
展示一个简单的音频消息流。这个例子显示了信息的冗余。
 Message Stream IDMessage Type IDTimeLength
Msg # 1  12345  8 100032
Msg # 2  12345  8 102032
Msg # 3  12345  8 104032
Msg # 4  12345  8 106032

下表显示了这个流产生的块。从消息3开始,数据传输开始优化。在消息3之后,每个消息只有一个字节的开销。

 Chunk Stream IDChunk TypeHeader DataNo.of Bytes After HeaderTotal No.ofBytes in the Chunk
Chunk#130delta: 1000length: 32type: 8stream ID:1234(11bytes)3244
Chunk#23220 (3 bytes)3236
Chunk#333none(0 bytes)3233
Chunk#433none(0 bytes)3233

演示一个消息由于太长,而被分割成128字节的块。

 Message Stream IDMessage TYpe IDTimeLength
Msg # 1123469 (video)1000307

下面是产生的块。

 Chunk Stream IDChunk TypeHeader DataNo. of Bytes after HeaderTotal No. of bytes in  the chunk
Chunk#140delta: 1000length: 307type: 9streamID: 12346(11 bytes)128140 
Chunk#243none (0 bytes)128  129
Chunk#343none (0 bytes)5152

数据传输的限定大小默认是128bytes,可以通过控制消息来改变,RTMP的约定是当Chunk流ID为2,消息流ID为0的时候,被认为是控制消息。


参考资料:
1、rtmp协议简单解析以及用其发送h264的flv文件


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值