rtmp数据封装二-AMF

简介

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