转载

FLV文件格式详解

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

FLV(Flash Video)是Adobe的一个免费开放的音视频格式,babala~~ 省略若干字的介绍,要看,到官网看吧,这里不赘述,我们主要来讨论下FLV文件格式的细节,在此之后,我们会进一步讨论下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文件中,使用的是大头序字节

感谢

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

参考

1. Adobe Video File Format specification V10

2. Video File Format Spcification V10.1

原文  http://blog.useasp.net/archive/2016/02/28/The-flv-video-file-format-specification-version-10-1.aspx
正文到此结束
Loading...