AMF(Action Message Format)是Flash与服务端通信的一种常见的二进制编码模式,其传输效率高,可以在HTTP层面上传输。现在很多Flash WebGame都采用这样的消息格式。
AMF协议是基于Http协议的.
它的内容处理过程大致是这样:
1.从客户端获取Http请求(Request)流.
2.对流进行解串行化(Deserialize),得到服务器端程序能够识别的数据,并建立一个响应(Response)消息
3.Debug开始
4. 对流进行各种处理(记录、许可、服务)得到返回值
5.对响应流进行串行化
6.发送Http响应给客户端标准文档:
该类型Tag又通常被称为Metadata Tag,会放一些关于FLV视频和音频的参数信息,如duration、width、height等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。(该tag信息一般需要跟播放器约定好名称与数值关系,如果没有约定好,播放器会直接丢弃)
其中与其相关的工具就是:yamdi
yamdi为flv文件增加了很多metadata信息,比如创建者、是否有关键帧、是否有视频、是否有音频,视频高度和宽度等等。而yamdi加入的meta数据中,最有效的要数关键帧。被注入了关键帧的flv可以实现像土豆网、优酷网等大型视频网站一样的“拖进度”,提前拖到缓冲还未加载到的位置开始播放。
一般来说,该Tag Data结构包含两个AMF包。AMF(Action Message Format)是Adobe设计的一种通用数据封装格式,在Adobe的很多产品中应用,简单来说,AMF将不同类型的数据用统一的格式来描述。第一个AMF包封装字符串类型数据,用来装入一个“onMetaData”标志,这个标志与Adobe的一些API调用有,在此不细述。第二个AMF包封装一个数组类型,这个数组中包含了音视频信息项的名称和值。具体说明如下,大家可以参照图片上的数据进行理解。
第一个AMF包:
第1个字节表示AMF包类型,一般总是0x02,表示字符串,其他值表示意义请查阅文档。
第2-3个字节为UI16类型值,表示字符串的长度,一般总是0x000A(“onMetaData”长度)。
后面字节为字符串数据,一般总为“onMetaData”。
第二个AMF包:
第1个字节表示AMF包类型,一般总是0x08,表示数组。
第2-5个字节为UI32类型值,表示数组元素的个数。
后面即为各数组元素的封装,数组元素为元素名称和值组成的对。表示方法如下:
第1-2个字节表示元素名称的长度,假设为L。
后面跟着为长度为L的字符串。
第L+3个字节表示元素值的类型。
后面跟着为对应值,占用字节数取决于值的类型
循环解析ScriptTagBody
1. 解析 SCRIPTDATAVALUE
1.1 解析 数据类型 type 占8位 表示后面的数据类型 (0,Number ;1,Boolean;2,String........8,ECMA array........)
1.2 解析 具体数据 不同数据类型 根据下表进行解析
Number,double (解析一个double数据)
Boolean,UI8(解析一个字节数据)
String,按照表SCRIPTDATASTRING解析
.........
ECMA array 按照表SCRIPTDATAECMAARRAY解析
1.2.1以SCRIPTDATASTRING为例解析:
StringLength 数据长度 占16位 表示该数据的长度
StringData 16位数据的ascii码
1.2.2以SCRIPTDATAECMAARRAY为例解析:
ECMAArrayLength 占32位 数组长度
Variables 每个数据 解析见表SCRIPTDATAOBJECTPROPERTY
1.2.2.1 表SCRIPTDATAOBJECTPROPERTY
PropertyName 数据名称 解析见表 SCRIPTDATASTRING 见上面1.2.1
PropertyData 数据值 解析见表 SCRIPTDATAVALUE 见 1.
List Terminator 解析见表SCRIPTDATAOBJECTEND (数组结束位,占3个字节 一定为 0x 00 00 09)
以下图选定区域的一个tag为例:
tag头信息:占11字节 12 00 01 74 00 00 00 00 00 00 00 脚本数据(0x 12 size = 0x00 01 74 )
数据类型:0x 02 表示String类型
StringLength 数据长度 占16位 值:0x 00 0A 长度10
StringData 值:0x 6F 6E 4D 65 74 61 44 61 74 61 : onMetaData
数据类型:0x 08 表示ECMA array数组类型
ECMAArrayLength 占32位 数组长度 当前值:0x 00 00 00 10 数组长度:16
1) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 08 长度8
StringData 值:0x 64 75 72 61 74 69 6F 6E : duration
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x:40 60 A8 F5 C2 8F 5C 29值:133.28
转换代码:
#include "stdio.h"
int main()
{
union DOUBLE
{
double number;
__int64 data;
};
DOUBLE num;
num.data = 0x4060A8F5C28F5C29;
printf("%lf\n",num.number);
getchar();
return 0;
}
2) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 05 长度5
StringData 值:0x 77 69 64 74 68: width
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 84 00 00 00 00 00 00值:640.00
3) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 06 长度6
StringData 值:0x 68 65 69 67 68 74: height
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 76 80 00 00 00 00 00 值:360.00
4) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0D 长度13
StringData 值:0x 76 69 64 65 6F 64 61 74 61 72 61 74 65 : videodaterate
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 71 A4 B4 00 00 00 00 值:282.29
5) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 09 长度9
StringData 值:0x 66 72 61 6D 65 72 61 74 65 : framerate
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 39 00 00 00 00 00 00 值:25.00
6) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0C 长度12
StringData 值:0x 76 69 64 65 6F 63 6F 64 65 63 69 64 :videocodecid
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 1C 00 00 00 00 00 00 值:7.00
7) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0D 长度13
StringData 值:0x 61 75 64 69 6F 64 61 74 61 72 61 74 65 :audiodaterate
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 5F 74 50 00 00 00 00 值:125.82
8) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0F 长度15
StringData 值:0x 61 75 64 69 6F 73 61 6D 70 6C 65 72 61 74 65 :audiosamplerate
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 E5 88 80 00 00 00 00 值:44100.00
9) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0F 长度15
StringData 值:0x 61 75 64 69 6F 73 61 6D 70 6C 65 73 69 7A 65 :audiosamplesize
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 30 00 00 00 00 00 00 值:16.00
10) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 06 长度6
StringData 值:0x 73 74 65 72 65 6F :stereo
PropertyData 数据
数据类型 type 占8位 值:0x 01 Boolean类型
数据:double 占8字节 值:0x 40 30 00 00 00 00 00 00 值:16.00
11) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0C 长度12
StringData 值:0x 61 75 64 69 6F 63 6F 64 65 63 69 64 :audiocodecid
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x 40 24 00 00 00 00 00 00 值:10.00
12) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0B 长度11
StringData 值:0x 6D 61 6A 6F 72 5F 62 72 61 6E 64 :major_brand
PropertyData 数据
数据类型 type 占8位 值:0x 02 表示String类型
StringLength 数据长度 占16位 值:0x 00 04 长度4
StringData 值:0x 69 73 6F 6D : isom
13) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 0D 长度13
StringData 值:0x 6D 69 6E 6F 72 5F 76 65 72 73 69 6F 6E :minor_version
PropertyData 数据
数据类型 type 占8位 值:0x 02 表示String类型
StringLength 数据长度 占16位 值:0x 00 03 长度3
StringData 值:0x 35 31 32 : 512
14) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 11 长度17
StringData 值:0x 63 6F 6D 70 61 74 69 62 6C 65 5F 62 72 61 6E 64 73 :compatible_brands
PropertyData 数据
数据类型 type 占8位 值:0x 02 表示String类型
StringLength 数据长度 占16位 值:0x 00 10 长度16
StringData 值:0x 69 73 6F 6D 69 73 6F 32 61 76 63 31 6D 70 34 31 : isomiso2avc1mp41
15) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 07 长度7
StringData 值:0x 65 6E 63 6F 64 65 72 :encoder
PropertyData 数据
数据类型 type 占8位 值:0x 02 表示String类型
StringLength 数据长度 占16位 值:0x 00 0D 长度13
StringData 值:0x 4C 61 76 66 35 36 2E 31 35 2E 31 30 32: Lavf56.15.102
15) PropertyName 数据名称
StringLength 数据长度 占16位 值:0x 00 08 长度8
StringData 值:0x 66 69 6C 65 73 69 7A 65 :filesize
PropertyData 数据
数据类型 type 占8位 值:0x 00 double类型
数据:double 占8字节 值:0x41 5B 2B 4B 80 00 00 00 值:7122222.0
List Terminator 解析见表SCRIPTDATAOBJECTEND (数组结束位,占3个字节 一定为 0x 00 00 09)