RTMP协议简介

RTMP协议简介RTMP 协议 nbsp RTMP 协议封包由一个包头和一个包体组成 包头可以是 4 种长度的任意一种 12 8 4 nbsp 1byte s 完整的 RTMP 包头应该是 12bytes 包含了时间戳 AMFSize AMFType StreamID 信息 nbsp 8 字节的包头只纪录了时间戳 AMFSize AMFType 其他字节的包头纪录信息依次类推 nbsp 包体最大长度默认为 128 字节 通过 chunkSiz

RTMP协议

 

RTMP协议封包由一个包头和一个包体组成,包头可以是4种长度的任意一种:12, 8, 4,  1 byte(s).完整的RTMP包头应该是12bytes,包含了时间戳,AMFSize,AMFType,StreamID信息, 8字节的包头只纪录了时间戳,AMFSize,AMFType,其他字节的包头纪录信息依次类推 。包体最大长度默认为128字节,通过chunkSize可改变包体最大长度,通常当一段AFM数据超过128字节后,超过128的部分就放到了其他的RTMP封包中,包头为一个字节.
完整的12字节RTMP包头每个字节的含义:



用途 大小(Byte) 含义
Head_Type 1 包头
TiMMER 3 时间戳
AMFSize 3 数据大小
AMFType 1 数据类型
StreamID 4 流ID

一、Head_Type
第一个字节 Head_Type的前两个Bit决定了包头的长度.它可以用掩码0xC0进行”与”计算: 
Head_Type的前两个Bit和长度对应关系:

Bits Header Length
00 12 bytes
01 8 bytes
10 4 bytes
11 1 byte

Head_Type的后面6个Bit和StreamID决定了ChannelID。 

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

例如在rtmp包里面经常看到的0xC2, 就表示一字节的包头,channel=2.

二、TiMMER
TiMMER占3个字节纪录的是时间戳,
音视频流的时间戳是统一排的。可分为绝对时间戳和相对时间戳。
fms对于同一个流,发布的时间戳和接受的时间戳是有区别的
publish时间戳,采用相对时间戳,时间戳值等于当前媒体包的绝对时间戳与上个媒体包的绝对时间戳之间的差距,也就是说音视频时间戳在一个时间轴上面.单位毫秒。
play时间戳,相对时间戳,时间戳值等于当前媒体包的绝对时间戳与上个同类型媒体包的绝对时间戳之间的差距, 也就是说音视频时间戳分别为单独的时间轴,单位毫秒。
flv格式文件时间戳,绝对时间戳,时间戳长度3个字节。超过0xFFFFFF后时间戳值等于TimeStamp & 0xFFFFFF。
flv格式文件影片总时间长度保存在onMetaData的duration属性里面,长度为8个字节,是一个翻转的double类型




三、AMFSize
AMFSize占三个字节,这个长度是AMF长度,
可超过RTMP包的最大长度128字节。如果超过了128字节,那么由多个后续RTMP封包组合,每个后续RTMP封包的头只占一个字节。 一般就是以0xC?开头。

四、AMFType


AMFType占1个字节是包的类型

0×01 Chunk Size changes the chunk size for packets
0×02 Unknown  
0×03 Bytes Read send every x bytes read by both sides
0×04 Ping ping is a stream control message, has subtypes
0×05 Server BW the servers downstream bw
0×06 Client BW the clients upstream bw
0×07 Unknown  
0×08 Audio Data packet containing audio
0×09 Video Data packet containing video data
0x0A-0x0E Unknown  
0x0F FLEX_STREAM_SEND TYPE_FLEX_STREAM_SEND
0x10 FLEX_SHARED_OBJECT TYPE_FLEX_SHARED_OBJECT
0x11 FLEX_MESSAGE TYPE_FLEX_MESSAGE
0×12 Notify an invoke which does not expect a reply
0×13 Shared Object has subtypes
0×14 Invoke like remoting call, used for stream actions too.
0×16 StreamData 这是FMS3出来后新增的数据类型,这种类型数据中包含AudioData和VideoData,就是把多个音视频包按照时间顺序打成一个包

五、StreamID
StreamID是音视频流的ID,
如果AMFType!=0x08 或!=0x09那么 StreamID为0。
ChannelID 和StreamID之间的计算公式: 这边需要补充,之前写的有问题。

StreamID=(ChannelID-4)/5+1 stream取整数。参考red5
例如当ChannelID为2、3、4时StreamID都为1 当ChannelID为9的时候StreamID为2

六、封包分析
例如有一个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字节头(第一字节开头2个bit为00),channelid=3(第一字节后6bit为3
000000(2-4字节)表示Timmer=0
000102(5-7字节)表示AMFSize=18
14表示AMFType=Invoke 方法调用
 00 00 00 00 表示StreamID = 0
//到此,12字节RTMP头结束







 
下面的是AMF数据分析,具体的AMF0数据格式请参考
http://www.cnweblog.com/fly2700/archive/2008/04/09/281432.html
02表示String
0007表示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数据开始
















































AMF0数据类型

Rtmp包默认的最大长度为128字节,(或通过chunksize改变rtmp包最大长度), 当AMF数据超过128Byte的时候就可能有多个rtmp包组成,如果需要解码的rtmp包太长则被TCP协议分割成多个TCP包.那么解码的时候需要先将包含rtmp包的tcp封包合并, 再把合并的数据解码,解码后可得到amf格式的数据,将这些AMF数据取出来就可以对AMF数据解码了.服务器和Flash客户端之间的命令都是用AMF格式的数据在传送,例如connect() publish()等命令和服务器as脚本里面自己定义的一些方法. 常用的数据类型整理如下: 



类型说明(ObjType) 数据 dataSize
CORE_String 0x02 2字节 (2字节的数据纪录了String的实际长度)
CORE_Object 0x03 0字节(开始嵌套0x00000009表示嵌套结束)
NULL 0x05 0字节 空字节无意义
CORE_NUMBER 0x00 8字节
CORE_Map 0x08 4字节(开始嵌套)
CORE_BOOLEAN 0x01 1字节

  AMF0数据的嵌套关系如下:
Object={ObjType + ObjValue}
ObjType={CORE_BOOLEAN、CORE_NUMBER、CORE_STRING、CORE_DATE、CORE_ARRAY、CORE_MAP、CORE_OBJECT}
CORE_BOOLEAN={Value(1 Byte)}
CORE_NUMBER={Value(8 Byte)}
CORE_String={StringLen(2 Byte) + StringValue(StringLen Byte)}
CORE_DATE={value(10 Byte)}
CORE_Array={ArrayLen(4 Byte) + Object}
CORE_Map={MapNum(4 Byte) + CORE_Object}
CORE_Object={CORE_String + Object}

上面一段数据由2个RTMP包组成,2个RTMP包头分别用蓝色表示,第一个蓝色的是12字节的包头,后面一个蓝色的C3是一个字节的包头,绿色部分是AMF数据,红色的是AMF数据类型,整个RTMP解码过程如下
[2008-06-18 16:59:20] DecodeInvoke:
[2008-06-18 16:59:20] InvokeName:String:connect
[2008-06-18 16:59:20] InvokeID:Double:0
[2008-06-18 16:59:20] Map:MapNum:0
[2008-06-18 16:59:20] Params:{

[2008-06-18 16:59:20] Key:String:objectEncoding
[2008-06-18 16:59:20] Value:Double:0
[2008-06-18 16:59:20] Key:String:app
[2008-06-18 16:59:20] Value:String:mediaserver
[2008-06-18 16:59:20] Key:String:fpda
[2008-06-18 16:59:20] Value:Bool:0
[2008-06-18 16:59:20] Key:String:tcUrl
[2008-06-18 16:59:20] Value:String:rtmp://127.0.0.1/mediaserver
[2008-06-18 16:59:20] Key:String:audioCodecs
[2008-06-18 16:59:20] Value:Double:615
[2008-06-18 16:59:20] Key:String:videoCodecs
[2008-06-18 16:59:20] Value:Double:76
[2008-06-18 16:59:20] }End Params
[2008-06-18 16:59:20] InvokeParams:String:PUBLISHER
[2008-06-18 16:59:20] InvokeParams:String:streamRecode






























 
详细的数据类型,参考Red5
FMS3中为了实现H.264数据的直播而增加了一个数据类型,这个类型的值为0x16,这个类型不在下表中,如果需要请参看 http://www.cnweblog.com/fly2700/archive/2009/02/06/297957.html
enum AMF
{
    /
     * Boolean value marker constant
     */
    TYPE_BOOLEAN = 0x01, 
    /
     * String marker constant
     */
 TYPE_STRING = 0x02,
    /
     * Object marker constant
     */
    TYPE_OBJECT = 0x03,
    /
     * Movieclip marker constant
     */
    TYPE_MOVIECLIP = 0x04 ,
    /
     * Null marker constant
     */
 TYPE_NULL = 0x05,
    /
     * Undefined marker constant
     */
 TYPE_UNDEFINED = 0x06,
    /
     * Object reference marker constant
     */
 TYPE_REFERENCE = 0x07,
    /
     * Mixed array marker constant
     */
 TYPE_MIXED_ARRAY = 0x08,
    /
     * End of object marker constant
     */
 TYPE_END_OF_OBJECT = 0x09,
    /
     * Array marker constant
     */
 TYPE_ARRAY = 0x0A,
    /
     * Date marker constant
     */
 TYPE_DATE = 0x0B,
    /
     * Long string marker constant
     */
 TYPE_LONG_STRING = 0x0C,
    /
     * Unsupported type marker constant
     */
 TYPE_UNSUPPORTED = 0x0D,
    /
     * Recordset marker constant
     */
 TYPE_RECORDSET = 0x0E,
    /
     * XML marker constant
     */
 TYPE_XML = 0x0F,
    /
     * Class marker constant
     */
 TYPE_CLASS_OBJECT = 0x10,
    /
     * Object marker constant (for AMF3)
     */
 TYPE_AMF3_OBJECT = 0x11,
    /
     * true marker constant
     */
 VALUE_TRUE = 0x01,
    /
     * false marker constant
     */
 VALUE_FALSE = 0x00
};














































































































关于rtmp封包中数据类型为0x16的封包
使用rtmp协议从FMS3中拉音视频数据的时候,会收到AMFType=0x16的封包,这种包在FMS2中从没有出现过.
rtmp包头的第8个字节就是AMFType,也就是数据类型。例如AMFType=0x08表示音频包,AMFType=0x04表示Ping包等等。FMS3中为了实现H.264数据的直播而增加了一个数据类型,这个类型的值为0x16。AMFType=0x16的包中既包含了音频帧也包含了视频帧。其中音频帧和视频帧是一种新的格式存放的,类似FLV文件存储格式,每个音视频包作为一个Tag,许多的Tag组成了这个AMFType=0x16的数据类型,Tag的格式如下:
用途 大小(Byte) 数据含义 
StreamType 1 流的种类(0x08=音频,0x09=视频) 
MediaSize  3 媒体数据区域大小  
TiMMER 3 绝对时间戳,单位毫秒 
Reserve 4 保留,值为0 
MediaData MediaSize 媒体数据,音频或视频 
TagLen 4 帧的大小,值为媒体数据区域大小+参数长度(MediaSize+1+3+3+4)










版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/220759.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午7:43
下一篇 2026年3月17日 下午7:43


相关推荐

  • DLL注入explorer.exe进程[通俗易懂]

    DLL注入explorer.exe进程[通俗易懂]**DLL注入explorer.exe进程**  最近一直在学习dll注入远程进程的相关知识,于是有了这篇文章。通过注入的方式会运行程序,在资源管理器中是看不到,相关的进程的,这为程序的隐藏提供了极大的便利。一、新建dll动态链接库,然后在dllmain.cpp文件中的“caseDLL_PROCESS_ATTACH:”下输入当你dll被进程加载时要执行的代码。这里我们用“Messag…

    2022年5月17日
    51
  • django框架菜鸟教程_django框架菜鸟教程

    django框架菜鸟教程_django框架菜鸟教程Django一、介绍1、简介是用python语言写的开源web开发框架,并遵循MVC设计。Django的主要目的是简便、快速的开发数据库驱动的网站。2、特点1)重量级框架2)MVT模式MVC其核心思想是分工、解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。…

    2025年10月8日
    4
  • Fiori介绍_fil简介

    Fiori介绍_fil简介为什么写这篇文章Fiori作为SAP最新以及将来的趋势平台,目前发展的非常快,作为一个FIORI技术的关注者,也一直想写点东西来介绍一下.前几天公司组织了一次Fiori的讲座,我作为主讲也参考SAP的介绍制作了一份PPT,在博客也分享出来,大家拿去用吧.SAP前端方案一句话:尽量简单,尽量根据个人的需求而定制.SAPFIORI简介FIORI是什么新的面孔面向所有用户跨平台FIORI应用

    2025年8月8日
    7
  • android中app的更新案例

    android中app的更新案例http://blog.csdn.net/android_tutor/article/details/7015986

    2022年6月25日
    30
  • 图片批量重命名的2种好方法有哪些_怎么给手机图片重命名

    图片批量重命名的2种好方法有哪些_怎么给手机图片重命名第一种,使用CTRL+A(全选)快捷键或者按CTRL键使用鼠标选中部分图片按F2(重命名快捷键)或者鼠标右键→重命名重命名只有一个图片出现编辑框,编辑完成回车就可以了。第二种,使用pptX文档更改。格式为(image1.jpeg,image2.jpeg,image3.jpeg……)新建ppt文档点击插入→图片pptX!pptX!pptX!我试了ppt文档压缩后不能打开找到图片所在的路径,全选图片后点击打开,保存文档…

    2025年9月15日
    9
  • 科大讯飞推出星火代码画布 一句话即可直接生成交互网页

    科大讯飞推出星火代码画布 一句话即可直接生成交互网页

    2026年3月14日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号