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}
例如完成握手后,Flash向FMS发送的第一个RTMP数据,内容如下:
上面一段数据由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://bbs.rosoo.net/thread-9388-1-1.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
};
(cjmxp) |