FLV文件格式详解

在集体挺进HTML5的时代,来讨论相关的话题似乎有点过时,但现如今还是有很多的视频网站采用的是Flash播放器,播放的文件也依然还有很多是FLV格式,而且仅从一个文件格式的角度去了解和分析FLV应该也还说的过去的。

FLV(Flash Video)是Adobe的一个免费开放的音视频格式,babala~~ 省略若干字的介绍,要看,到官网看吧,这里不赘述,我们主要来讨论下FLV文件格式的细节,在此之后,我们会进一步讨论下的加密解密相关内容。

整体上,FLV分为HeaderBody两大块。

Header: 记录FLV的类型,版本,当前文件类型等信息,这些信息可以让我们对当前FLV文件有个概括的了解。

Body: FLV的Body是Flv的数据区域,这些是FLV的具体内容,因为FLV中的内容有多种,并可同时存在,因此,Body也不是一整块的数据,而是由更细分的块来组成,这个细分的块叫Tag。

这就是整个FLV的大概结构,下面我们进入到比特/字节数据的世界,看看FLV的内部世界。

 

HEADER

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字节意义如下:

  1. 第1-3字节:文件标志,FLV的文件标志为固定的“FLV",字节(0x46, 0x4C,0x56),见上面的字节序和字符序两行;
  2. 第4字节:当前文件版本,固定为1(0x01)
  3. 第5字节:此字节当前用到的只有第6,8两个bit位,分别标志当前文件是否存在音频,视频。参见上面bit序,即是第5字节的内容;
  4. 第6-9字节:此4字节共同组成一个无符号32位整数(使用大头序),表示文件从FLV Header开始到Flv Body的字节数,当前版本固定为9(0x00,0x00,0x00,0x09)

Header之后,即是FLV的Body了,Body定义了整个FLV的数据内容,他的结构又是如何的呢,让我们看下:

 

BODY

Body是由Tag Size(4字节)和Tag组成,其结构如下:

-------------------------
|  Previous Tag Size    |
-------------------------
|          Tag          |
-------------------------
|  Previous Tag Size    |
-------------------------
|          Tag          |
-------------------------
|  Previous Tag Size    |
-------------------------
|          Tag          |
-------------------------
|  Previous Tag Size    |
-------------------------

 

Previous Tag Size

这个比较好理解,就是前一个Tag的大小,这里同样存的是无符号32位整型数值。因为第一个Previous Tag Size是紧接着FLV Header的,因此,其值也是固定为0(0x00,0x00,0x00,0x00)。

 

TAG

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 HeaderTag Data两部分,他们的结构如下:

-------------------------
|       Tag Header      |
-------------------------
|       Tag  Data       |
-------------------------



                -------------------------
                |       Tag Header      |
                -------------------------
                 /                    \
--------------------------------------------------------
| 08 | 00 | 00 | 18 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
--------------------------------------------------------

Tag Header由11字节组成:

  1. 第1字节:标志当前Tag的类型,音频(0x08),视频(0x09),Script Data(0x12),除此之外,其他值非法;
  2. 第2-4字节:表示一个无符号24位整型数值,表示当前Tag Data的大小;
  3. 第5-7字节:无符号24位整型数值(UI24),当前Tag的时间戳(单位为ms),第一个Tag的时间戳总为0;
  4. 第8字节:为时间戳的扩展字节,当前24位不够用时,该字节作为最高位,将时间戳扩展为32位无符号整数(UI32)
  5. 第9-11字节:UI24类型,表示Stream ID,总是0

 

Tag Data

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个字节)来表示类型,可用的类型如下:

  • 0 = Number
  • 1 = Boolean
  • 2 = String
  • 3 = Object
  • 4 = MovieClip (reserved, not supported)
  • 5 = Null
  • 6 = Undefined
  • 7 = Reference
  • 8 = ECMA array
  • 9 = Object end marker
  • 10 = Strict array
  • 11 = Date
  • 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文件中,使用的是大头序字节

 

感谢

由于本人对于零基础,对于FLV更是门外汉,特别感谢Merry引荐的Colin让我在Flv文件的研究少走很多弯路(包含Specification文档),并在短时间内出色的完成了工作中对FLV文件的析构任务。

 

参考

1. Adobe Video File Format specification V10

2. Video File Format Spcification V10.1

 

Sunday, February 28, 2016 | 其他技术

文章评论

No comments posted yet.

发表评论

Please add 4 and 4 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,属于互联网行业分类中的杂牌军。