在集体挺进HTML5的时代,来讨论Adobe Flash相关的话题似乎有点过时,但现如今还是有很多的视频网站采用的是Flash播放器,播放的文件也依然还有很多是FLV格式,而且仅从一个文件格式的角度去了解和分析FLV应该也还说的过去的。
FLV(Flash Video)是Adobe的一个免费开放的音视频格式,babala~~ 省略若干字的介绍,要看,到官网看吧,这里不赘述,我们主要来讨论下FLV文件格式的细节,在此之后,我们会进一步讨论下FLV的加密解密相关内容。
整体上,FLV分为 Header
和 Body
两大块。
Header: 记录FLV的类型,版本,当前文件类型等信息,这些信息可以让我们对当前FLV文件有个概括的了解。
Body: FLV的Body是Flv的数据区域,这些是FLV的具体内容,因为FLV中的内容有多种,并可同时存在,因此,Body也不是一整块的数据,而是由更细分的块来组成,这个细分的块叫Tag。
这就是整个FLV的大概结构,下面我们进入到比特/字节数据的世界,看看FLV的内部世界。
Flv 文件的Header总共由9个字节组成,他们构成如下:
---------------------------------------------- 字节序 | 46 | 4c | 56 | 01 | 05 | 00 | 00 | 00 | 09 | ---------------------------------------------- 字符序 F L V 1 / / 9 --------------------------------- bit序 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | --------------------------------- 1/0 1/0 音频位 视频位
附注说明:字节序表示文件中的存放的字节流顺序,字符序是按照字节序展示出可见的字符数据,bit序此处为第5字节的bit位值.
FLV 文件Header的9字节意义如下:
Header之后,即是FLV的Body了,Body定义了整个FLV的数据内容,他的结构又是如何的呢,让我们看下:
Body是由 Tag Size
(4字节)和 Tag
组成,其结构如下:
------------------------- | Previous Tag Size | ------------------------- | Tag | ------------------------- | Previous Tag Size | ------------------------- | Tag | ------------------------- | Previous Tag Size | ------------------------- | Tag | ------------------------- | Previous Tag Size | -------------------------
这个比较好理解,就是前一个Tag的大小,这里同样存的是无符号32位整型数值。因为第一个Previous Tag Size是紧接着FLV Header的,因此,其值也是固定为0(0x00,0x00,0x00,0x00)。
FLV中的TAG不止一种,当前版本共有3种类型组成:音频(audio),视频(video),脚本数据(script data),这三种类型会在Tag内进行标志区分。其中:Audio Tag是音频数据,Video Tag是视频数据,Script Data存放的是关于FLV视频和音频的一些参数信息(亦称为Metadata Tag),通常该Tag会在FLV File Header后面作为第一个Tag出现,并且一个文件仅有一个Script Data Tag。
为了在Tag内存放不同的数据,并且能够方便区分,每个Tag被定义除了 Tag Header
和 Tag Data
两部分,他们的结构如下:
------------------------- | Tag Header | ------------------------- | Tag Data | ------------------------- ------------------------- | Tag Header | ------------------------- / / -------------------------------------------------------- | 08 | 00 | 00 | 18 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | --------------------------------------------------------
Tag Header由11字节组成:
Tag Data由Tag Header标志后,就被分成音频,视频,Script Data三类,分别如下:
1. Audio Tag Data
Audio Tag Data开始的第一个字节包含了音频数据的参数信息,第二个字节开始为音频流数据:
第1字节:
UB[4],前4位标识音频数据的格式,如:0x2表示的是MP3数据,当前合法的数值为0,1,2,3,4,5,6,7,8,9,10,11,14,15(7,8,14,15保留为内部使用)
UB[2],第5,6位bit表示采样率(AAC,总是3)
UB[1],采样精度, 0为8bits, 1为16bits
UB[1],音频类型,mono=0, stereo=1
2. Video Tag Data
和音频一样,其第一个字节包含的是视频参数信息,第二字节开始为视频流数据。
第1字节:
UB[4],前4位标识帧类型。1: keyframe (for AVC, a seekable frame); 2: inter frame (for AVC, a nonseekable frame); 3: disposable inter frame (H.263 only); 4: generated keyframe (reserved for server use only); 5: video info/command frame
UB[4],后4位标识视频编码。1: JPEG (currently unused) ;2: Sorenson H.263; 3: Screen video; 4: On2 VP6; 5: On2 VP6 with alpha channel; 6: Screen video version 2; 7: AVC
第二字节开始的数据有以下规律:
If CodecID == 2 H263VIDEOPACKET If CodecID == 3 SCREENVIDEOPACKET If CodecID == 4 VP6FLVVIDEOPACKET If CodecID == 5 VP6FLVALPHAVIDEOPACKET If CodecID == 6 SCREENV2VIDEOPACKET if CodecID == 7 AVCVIDEOPACKET
3. Script Tag Data
这个Tag Data里面在未加密的时候,是ScriptTagBody类型,里面的SCRIPTDATA编码为AMF(Action Message Format)。ScriptTagBody由Name和Value两个字段组成(类型均为SCRIPTDATAVALUE)。
---------------------------------- | Name (SCRIPTDATAVALUE) | ---------------------------------- | Value (SCRIPTDATAVALUE) | ----------------------------------
SCRIPTDATAVALUE类型比较多,它使用UI8(1个字节)来表示类型,可用的类型如下:
4 = MovieClip (reserved, not supported)
9 = Object end marker
10 = Strict array
12 = Long string
每种类型有对应的定义,这个比较多,不加详述,可以参看官方文档。
这里需要特别提出的一个是 onMetaData
,在SCRIPTDATA Tag中,它名称即为 onMetaData
,它提供一系列可用于AS编程的变量(通过 NetStream.onMetaData
属性获取)。由于每种软件创建的FLV文件,均可有不同的变量,无法一一列出,但一般包含:FLV的音频,视频还有文件相关的基本信息,如:文件大小,时长,视频宽高等。
onMetaData的一般结构如下:
------------------------------------- | Name (SCRIPTDATAVALUE) | ------------------------------------- / / ------------------------------------------------------------------ | 02 | 00 | 0a | 6f | 6e | 4d | 65 | 74 | 61 | 44 | 61 | 74 | 61 | ------------------------------------------------------------------
后面的Value由于每个软件产生的不同,但类型是0x08,ECMA ARRAY。大概结构如下:
---------------------------------- | ECMAArray Length(UI32) | ---------------------------------- | Variables Array[] | ---------------------------------- | SCRIPTDATAOBJECTEND | ----------------------------------
其中Variables Array为SCRIPTDATAOBJECTPROPERTY类型数组,最后用3字节的SCRIPTDATAOBJECTEND结束VALUE值。这个值固定为:0x00,0x00,0x09
到此,FLV的基本文件格式就讲解完成了,基于这个结构作为基石,我们可以对FLV进行校验,解析数据,当然,还有加密/解密。
注意:: FLV文件中,使用的是大头序字节
由于本人对于AS3零基础,对于FLV更是门外汉,特别感谢Merry引荐的Colin让我在Flv文件的研究少走很多弯路(包含Specification文档),并在短时间内出色的完成了工作中对FLV文件的析构任务。
1. Adobe Video File Format specification V10
2. Video File Format Spcification V10.1