一、引言
在《音视频入门基础:FLV专题(9)——Script Tag简介》中对FLV文件的Script Tag进行了简介。下面用一个具体的例子来对Script Tag进行分析。
二、Script Tag的Tag header实例分析
用notepad++打开《音视频入门基础:FLV专题(2)——使用FFmpeg命令生成flv文件》中生成的FLV文件,下图红框中的就是第一个Tag的Tag header。可以看到Tag header为0x12 0x00 0x01 0x73 0x00 0x00 0x00 0x00 0x00 0x00 0x00。关于Tag header定义可以参考:《音视频入门基础:FLV专题(7)——Tag header简介》:
红框中的Tag header的第1个字节为0x12,即0b00010010。所以Filter的值为0,表示该Tag未加密。TagType为0x12,表示该Tag为脚本Tag(Script Tag)。
红框中第2到第4个字节为0x00 0x01 0x73,即十进制的371。所以整个Tag data的长度为371字节,由于该Tag为Script Tag,它的Tag data就是SCRIPTDATA。而从《音视频入门基础:FLV专题(9)——Script Tag简介》中可以知道,未加密的情况下,Script Tag的Tag header之后就是SCRIPTDATA。SCRIPTDATA的首地址为0x18,所以SCRIPTDATA最后一个字节的地址 = 0x18 + 0x000173(十进制的371) - 1 = 0x18A。所以下图红框中的就是该Script Tag的SCRIPTDATA,即该Script Tag的ScriptTagBody:
三、Script Tag的ScriptTagBody实例分析
(一)ScriptTagBody的Name属性
从《音视频入门基础:FLV专题(9)——Script Tag简介》中可以知道,ScriptTagBody = Name + Value;
ScriptTagBody的Name = 1字节的值为2的Type + 2字节的StringLength + 可变长的StringData。
所以下图红框中的“0x02”为Name的Type,表示ScriptDataValue的类型为String(字符串):
所以下图红框中的“0x00 0x0A”为Name的StringLength,表示要存贮的字符串的长度为0x000A个字节,也就是十进制的10个字节:
所以下图红框中的“onMetaData”,总共10个字节为Name的StringData,表示该Tag是一个名称为“onMetadata”的Script Tag:
(二)ScriptTagBody的Value属性
从《音视频入门基础:FLV专题(9)——Script Tag简介》中可以知道,
ScriptTagBody的Value = 1字节的值为8的Type + 4字节的ECMAArrayLength + Variables数组 + 3字节的终止符(值固定为0,0,9)。
所以下图红框中的“8”为Value的Type,表示ScriptDataValue的类型为ECMA数组:
下图红框中的“0x00 0x00 0x00 0x10”为Value的ECMAArrayLength ,表示ECMA数组中的元素个数为0x10个,也就是16个:
下图红框中的“0x00 0x00 0x09”为Value的3字节的终止符:
下图红框中的为Value的Variables数组。 从《音视频入门基础:FLV专题(9)——Script Tag简介》中可以知道,名称为“onMetadata”的Script Tag中,其Variables数组中的每个元素都分别为一个元数据属性,用来存贮当前文件的一些基本信息,比如视频和音频的编解码器ID、视频的分辨率、文件大小、文件总时长、创建日期等:
四、onMetaData的Variables数组实例分析
从《音视频入门基础:FLV专题(9)——Script Tag简介》中可以知道,Variables属性是一个数组。
Variables数组中某个元素 = PropertyName + PropertyData;
Variables数组中某个元素的PropertyName = 2字节的StringLength + 可变长的StringData;
Variables数组中某个元素的PropertyData = 1字节的值为0到12的Type + ScriptDataValue;
下图红框中的“0x00 0x08”为Variables数组中第一个元素的PropertyName中的StringLength,表示该元素要存贮的字符串的长度为0x0008个字节,也就是十进制的8个字节:
所以下图红框中的“duration”,总共8个字节为PropertyName的StringData,表示该元数据属性存贮的是该FLV文件的总时长,以秒为单位:
下图红框中的“0x00”为Variables数组中第一个元素的PropertyData中的Type,值为0表示ScriptDataValue为DOUBLE类型:
根据《swf-file-format-spec.pdf》第16页,DOUBLE类型为双精度(64位)兼容IEEE标准754。64位表示存贮DOUBLE类型数据需要占用8个字节:
所以下图红框中的“0x40 0x29 0xCC 0xCC 0xCC 0xCC 0xCC 0xCC”为该DOUBLE类型数据:
由 浮点数-Float-Double转二进制 - ToolTT在线工具箱 中的IEEE 754标准浮点计算器,可以算出来“0x40 0x29 0xCC 0xCC 0xCC 0xCC 0xCC 0xCC”对应的十进制浮点数为12.9。所以Variables数组中duration元数据属性的值为12.9,表示该FLV文件的总时长为12.9秒:
Variables数组中的其它元数据属性读取方式跟duration差不多,以此类推。
五、用flvAnalyser工具分析Script Tag
用flvAnalyser工具可以直接显示Script Tag的SCRIPTDATA:
下图红框中的为ScriptTagBody的Name:
下图红框中的为ScriptTagBody的Value的ECMAArrayLength,表示ECMA数组中的元素个数为16个:
下图红框中的为ScriptTagBody的Value的Variables数组,可以看到正好有16个元素:
下图红框中的为ScriptTagBody的Value的3字节的终止符: