一路走来,只有C++和香烟最实在!

Just Dive Into!

C++博客 首页 新随笔 联系 聚合 管理
  11 Posts :: 0 Stories :: 29 Comments :: 0 Trackbacks

Chunk Msg Header

Chunk Msg Header的长度是可变的,Chunk Msg Header可变的原因是为了压缩传输的字节数,把一些相同类型的chunkhead去掉一些字节,换句话说就是四种类型的包头都可以通过一定的规则还原成11个字节,这个压缩和还原在RTMP协议中称之为复用/解复用。

那我们以11个字节的完整包头来解释Chunk Msg Header,如图所示

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+                    timestamp          +            message length         + message type  id +                message stream id     +

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Timestamp3bytes

对于type 0chunk,绝对时间戳在这里表示,如果时间戳值大于等于0xffffff16777215),该值必须是0xffffff,且时间戳扩展字段必须发送,其他情况没有要求。

message length:3bytes

Message的长度,注意这里的长度并不是跟随chunk head其后的chunk data(Payload)的长度,而是前文提到的一条信令或者一帧视频数据或音频数据的长度。前文提到过信令或者媒体数据都称之为Message,一条Message可以分为一条或者多条chunk。

message type  id:1byte

Message的类型ID,具体的值将在后文专门来讨论。

message stream id:4bytes

message stream id的字节序是小端序,这个字段是为了解复用而设计的,RTMP文档上说的相当的模糊,

 

message stream ID可以使任意值,不同的消息流复用成相同的chunk stream,基于它们的ID能够解复用。于chunk stream 是相关的,这个字段是一个不透明的值没有整明白什么意思,我的理解就是用来标识和服务器连接的flash端的序号。

长度是7 byteschunk head,该类型不包含stream ID,该chunkstreamID和前一个chunkstream ID是相同的,变长的消息,例如视频流格式,在第一个新的chunk以后使用这种类型,注意其中时间戳部分是相对时间,为何上一个绝对时间之间的差值 如图所示:

++++++++++++++++++++++++++++++++++++++++++++++++++++++

+         timestamp    delta      +            message length         + message type  id +             

++++++++++++++++++++++++++++++++++++++++++++++++++++++

        3 bytes的chunk head,该类型既不包含stream ID 也不包含消息长度,这种类型用于stream ID和前一个chunk相同,且有固定长度的信息,例如音频流格式,在第一个新的chunk以后使用该类型。如图所示:

                           ++++++++++++++++++++

                           +         timestamp    delta      +         

                           ++++++++++++++++++++


        0 bytes的chunk head,这种类型的chunk从前一个chunk得到值信息,当一个单个消息拆成多个chunk时,这些chunk除了第一个以外,其他的都应该使用这种类型,

chunk的长度:

chunk的长度初始长度固定为128个字节,但是这个值并不是不可变的,在客户端和服务端建立连接以后,客户端和服务端都可以通过发送信令的方式来通知对端修改chunk的长度,理论上来说可以修改chunk的最长长度为65536。这里chunk的长度是指chunk的数据部分的长度,即chunk data(payload)的长度,如果一条Message的数据长度超过了chunk的长度,就必须把Message分割成多条chunk,即如果一条视频类型Message长度为2000个byte,chunk长度为1500,则该Message将会分割成两条chunk,第一条的chunk data长度为1500,第二条的chunk data长度为500。当然这两条chunk的chunk head肯定是不同的,其中第二条chunk的chunk head就是0字节的。


 

posted on 2009-12-30 00:15 Richard Liu 阅读(12434) 评论(14)  编辑 收藏 引用

Feedback

# re: RTMP协议详解(三) 2010-03-03 16:39 roger
good!期待第四期  回复  更多评论
  

# re: RTMP协议详解(三)[未登录] 2010-03-10 00:05 peter
请问你的服务器和 rtmpd 有什么不同啊?  回复  更多评论
  

# re: RTMP协议详解(三) 2010-03-10 20:09 Richard Liu
@peter
rtmpd是我实现时主要参考的代码,不过rtmpd的功能更多,我只是实现了一部分的功能,主要是和公司的的业务相结合的一部分,关注的是直播的那一块的应用  回复  更多评论
  

# re: RTMP协议详解(三) 2010-03-10 20:10 Richard Liu
@roger
第四期估计等闲的时候再出了哦  回复  更多评论
  

# re: RTMP协议详解(三) 2010-07-03 10:18 shelley
"Timestamp:3bytes
对于type 0的chunk,绝对时间戳在这里表示,如果时间戳值大于等于0xffffff(16777215),该值必须是0xffffff,且时间戳扩展字段必须发送,其他情况没有要求。"

请问如果时间戳值大于等于0xffffff(16777215),扩展时间戳字节怎么排放呢?

我实现的RTMP时间戳一大于0xffffff, flash player 就断开连接了。假如时间戳为0x12345678,那3字节时间戳:0xff 0xff 0xff, 4字节扩展时间戳:0x12 0x34 0x 56 0x78,其它字段没变化。

在时间戳值大于等于0xffffff(16777215)的情况下,还有什么需要修改的么?  回复  更多评论
  

# re: RTMP协议详解(三) 2010-07-21 15:47 小武
高人, 指点下当发送VIDEO DATA 的时候,数据包是怎么封装的吧。
报文的头部我大概知道,但是数据部分怎么封装呢?比如我直接读取一个.H264的文件。如何封装?QQ23520813.可详谈。   回复  更多评论
  

# re: RTMP协议详解(三) 2010-08-20 21:25 Richard Liu
@shelley
@shelley
参考一下RTMP的我协议如果大于0xfffffff直接把在0xffffff后面加上差值就可以,四个字节,比如说0xffffff+2后面四个字节就是2撒  回复  更多评论
  

# re: RTMP协议详解(三) 2010-08-20 21:29 Richard Liu
@小武
一个H。264的数据包封装的时候 首先一定要确保客户端收到的第一个视频数据包是H。264的序列头,其他的好像没有什么要求吧,其他的就一帧一帧的数据发就可以了,还有就是要分辨H。264每一帧的文件是什么帧,I帧和中间帧的包头不一样的,参考一下FLV的文件格式就可以了  回复  更多评论
  

# re: RTMP协议详解(三) 2010-09-19 17:59 codebumb
请教一下,对于audio数据包应该怎么发呢?audio的一些编码参数什么怎么告诉client呢?是通过metadata吗?我下了一份rtmp的官方文档,好像对这块只是简略的提到一点。  回复  更多评论
  

# re: RTMP协议详解(三) 2011-08-29 16:12 lujiaming_brm
您好,请问一个地方。
我修改了rtmpdump中的rtmpsrv程序。
发现使用一个Red5的客户端可以播放FLV文件。
但是如果开第二个Red5的客户端就无法播放FLV文件。
但是网络抓包存在,
而且第二个Red5的客户端也会收到OnMetaData的。
就是播放不了后续的音视频流。

另外我发现Red5的客户端在播放的时候,会出现这个错误:
Asynchronous code error - ReferenceError: Error #1069
这个要如何避免???
  回复  更多评论
  

# re: RTMP协议详解(三) 2011-08-29 17:11 vliuchao
建议你使用rtmpd这个服务器,也是开源的, rtmpsrv我没用过,你说的那种情况我猜测是由于rtmpsrv对streamID的管理或者socket的管理有问题,
Asynchronous code error - ReferenceError: Error #1069
这个我也不是很清楚,你说的red5的客户端我用过其实就是一个输出调试信息的flash控件,这个错误可能是rtmpsrv实现rtmp协议有些消息没有响应吧@lujiaming_brm
  回复  更多评论
  

# re: RTMP协议详解(三) 2011-08-30 11:34 lujiaming_brm
@vliuchao
谢谢您的回复。
那请问一下,除了red5的客户端,您平时都是使用什么客户端工具测试的呢??能否推荐一个呢??

我下载了那个rtmpd的代码,make之后,使用red5的客户端连接之后,发现rtmpd直接关闭了连接了。

11:28:27:875 - Using Adobe Windows Flash Player 10,3,183,5
11:28:38:656 - Connecting to rtmp://192.168.6.75/oflaDemo
11:28:38:656 - NetConnection.Connect.Closed

但是我阅读代码发现,main函数中的循环,就是简单的read_client之后,write_client。而且write_chunk也写得十分简单。甚至根本就没有对于视频流0x9和音频流0x8的处理。
难道是您修改了rtmpd的代码,加入了对于视频流0x9和音频流0x8的处理么。

另外,如果可以通过QQ帮助我一下,
我的邮箱是lujiaming_brm@163.com。如果可以,能否把您的QQ号发给我。
谢谢了。  回复  更多评论
  

# re: RTMP协议详解(三) 2011-11-11 09:06 fanxin
@lujiaming_brm
有没有rtmpd源码。fpeter@126.com
thanks!  回复  更多评论
  

# re: RTMP协议详解(三) 2013-11-25 13:25 艺搜天下
总结得相当不错,支持下。
by www.elesos.com 站长  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理