简介
rtmp协议在传输script数据onMetaData时使用AMF(Action Message Format)格式封装。
AMF_TYPE对应的编号:
- 0 : AMF_NUMBER
- 1 : AMF_BOOLEAN,
- 2 : AMF_STRING,
- 3 : AMF_OBJECT,
- 4 : AMF_MOVIECLIP,
- 5 : AMF_NULL,
- 6 : AMF_UNDEFINED,
- 7 : AMF_REFERENCE,
- 8 : AMF_ECMA_ARRAY,
- 9 : AMF_OBJECT_END,
- 10 : AMF_STRICT_ARRAY,
- 11 : AMF_DATE,
- 12 : AMF_LONG_STRING,
- 13 : AMF_UNSUPPORTED,
- 14 : AMF_RECORDSET,
- 15 : AMF_XML_DOCUMENT,
- 16 : AMF_TYPED_OBJECT,
- 17 : AMF_AVMPLUS_OBJECT,
结构分析
[AMF_TYPE]+[data length]+[data]
1)字符串
AMF_STRING和AMF_LONG_STRING都是存字符串,AMF_STRING的字符串的长度占2个byte,不能超过65536-1,AMF_LONG_STRING的长度占4个byte。以AMF_STRING为例:
第一个byte是2,接着是2个byte的[data length]表示字符串的长度,接着是字符串的内容。
2)数字
AMF_NUMBER,第一个byte是0,接着是4个byte的数字内容。
3)bool值
AMF_BOOLEAN,第一个byte是1,接着是1个byte的bool值。
4)数组
开头用AMF_ECMA_ARRAY表示,结尾用AMF_OBJECT_END表示,中间写入数组的内容。
AMF_ECMA_ARRAY开头:第一个byte是8,接着是4个byte的[array length]表示数组的成员数。
AMF_OBJECT_END结尾:2个byte的数据全是0,接着一个byte是9。
AMF_ECMA_ARRAY的数组内容里是先插入一个字符串数据的name,然后再插入一个具体类似数据的value。
如下面所示的抓包内容就是:
- 插入一个name字符串’title’
- 插入字符串’ipc’,
- 插入一个name字符串’width’
- 插入数字640,
- …
抓包示例
以下是wireshark抓包的结构:
RTMP Header
01.. .... = Format: 1
..00 0011 = Chunk Stream ID: 3
Timestamp delta: 0
Timestamp: 0 (calculated)
Body size: 219
Type ID: AMF0 Data (0x12)
RTMP Body
String 'onMetaData'
ECMA array (10 items)
AMF0 type: ECMA array (0x08)
Array length: 10
Property 'title' String 'ipc'
Property 'width' Number 640
Property 'height' Number 480
Property 'framerate' Number 25
Property 'videocodecid' Number 7
Property 'audiocodecid' Number 8
Property 'audiodatarate' Number 64
Property 'audiosamplerate' Number 8000
Property 'audiosamplesize' Number 16
Property 'stereo' Boolean true
End Of Object Marker