FLV视频和音频解析学习(一)

1. FLV文件格式

       FLV (Flash Vedio ) 是一种视频流媒体格式,FLV是被众多新一代视频分享网站所采用,是目前增长最快、最为广泛的视频传播格式。是在sorenson公司的压缩算法的基础上开发出来的。FLV格式不仅可以轻松的导入Flash中,速度极快,并且能起到保护版权的作用,并且可以不通过本地的微软或者REAL播放器播放视频。

2. FLV文件介绍

  FLV是一个二进制文件,由文件头(FLV header)和很多tag组成。tag又可以分成三类:audio,video,script,分别代表音频流,视频流,脚本流(关键字或者文件信息之类)。

  FLV文件=FLV头文件+ tag1+tag内容1 + tag2+tag内容2 + ...+... + tagN+tag内容N

2.1 FLV Header

Signature

UI8

Signature byte always 'F' (0x46)

Signature

UI8

Signature byte always 'L' (0x4C)

Signature

UI8

Signature byte always 'V' (0x56)

Version

UI8

File version (for example, 0x01 for FLV version 1)

TypeFlagsReserved

UB [5]

Shall be 0

TypeFlagsAudio

UB [1]

1 = Audio tags are present

TypeFlagsReserved

UB [1]

Shall be 0

TypeFlagsVideo

UB [1]

1 = Video tags are present

DataOffset

UI32

The length of this header in bytes

Signature: FLV 文件的前3个字节为固定的F’‘L’‘V’,用来标识这个文件是flv格式的.在做格式探测的时候,

如果发现前3个字节为“FLV”,就认为它是flv文件

Version: 4个字节表示flv版本号

Flags: 5个字节中的第0位和第2,分别表示 video audio 存在的情况.(1表示存在,0表示不存在)

DataOffset : 最后4个字节表示FLV header 长度

2.2 FLV Body

Field

Type

Comment

PreviousTagSize0

UI32

Always 0

Tag1

FLVTAG

First tag

PreviousTagSize1

UI32

Size of previous tag, including its header, in bytes. For FLV version1,

this value is 11 plus the DataSize of the previous tag.

Tag2

FLVTAG

Second tag

...

...

...

PreviousTagSizeN-1

UI32

Size of second-to-last tag, including its header, in bytes.

TagN

FLVTAG

Last tag

PreviousTagSizeN

UI32

Size of last tag, including its header, in bytes

 

FLV header之后,就是 FLV File Body。

FLV File Body是由一连串的back-pointers + tags构成.back-pointers就是4个字节数据,表示前一个tagsize。

3. Tag 标签

  FLV文件中的数据都是由一个个TAG组成,TAG里面的数据可能是videoaudioscripts。

3.1 FLV Tag

Field

Type

Comment

Reserved

UB [2]

Reserved for FMS, should be 0

Filter

UB [1]

Indicates if packets are filtered.
0 = No pre-processing required.
1 = Pre-processing (such as decryption) of the packet is
required before it can be rendered.
Shall be 0 in unencrypted files, and 1 for encrypted tags.
See Annex F. FLV Encryption for the use of filters.

TagType

UB [5]

Type of contents in this tag. The following types are
defined:
8 = audio
9 = video
18 = script data

DataSize

UI24

Length of the message. Number of bytes after StreamID to
end of tag (Equal to length of the tag – 11)

Timestamp

UI24

Time in milliseconds at which the data in this tag applies.
This value is relative to the first tag in the FLV file, which
always has a timestamp of 0.

TimestampExtended

UI8

Extension of the Timestamp field to form a SI32 value. This
field represents the upper 8 bits, while the previous
Timestamp field represents the lower 24 bits of the time in
milliseconds.

StreamID

UI24

Always 0.

AudioTagHeader

IF TagType == 8
AudioTagHeader

 

VideoTagHeader

IF TagType == 9
VideoTagHeader

 

EncryptionHeader

IF Filter == 1
EncryptionTagHeader

 

FilterParams

IF Filter == 1
FilterParams

 

Data

IF TagType == 8
AUDIODATA
IF TagType == 9
VIDEODATA
IF TagType == 18
SCRIPTDATA

Data specific for each media type.

 

TagType: TAG中第1个字节中的前5位表示这个TAG中包含数据的类型,8 = audio,9 = video,18 = script data

DataSize:StreamID之后的数据长度

TimestampTimestampExtended组成了这个TAG包数据的PTS信息,记得刚开始做FVL demux的时候,并没有考虑TimestampExtended的值,直接就把Timestamp默认为是PTS,后来发生的现 象就是画面有跳帧的现象,后来才仔细看了一下文档发现真正数据的PTSPTS= Timestamp | TimestampExtended<<24。

StreamID之后的数据就是每种格式的情况不一样了,接下来对格式进行详细的介绍。

3.1.1 Script Tag

  如果TAG包中的TagType==18时,就表示这个TAGSCRIPT。

  SCRIPTDATA 结构十分复杂,定义了很多格式类型,每个类型对应一种结构

Field

Type

Comment

Type

UI8

Type of the ScriptDataValue.
The following types are defined:
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

ScriptDataValue

IF Type == 0
DOUBLE
IF Type == 1
UI8
IF Type == 2
SCRIPTDATASTRING
IF Type == 3
SCRIPTDATAOBJECT
IF Type == 7
UI16
IF Type == 8
SCRIPTDATAECMAARRAY
IF Type == 10
SCRIPTDATASTRICTARRAY
IF Type == 11
SCRIPTDATADATE
IF Type == 12
SCRIPTDATALONGSTRING

Script data value.
The Boolean value is (ScriptDataValue ≠ 0).

类型在FLV的官方文档中都有详细介绍.

OnMetadata

onMetaData SCRIPTDATA中对我们来说十分重要的信息,结构如下表:

Property Name

Type

Comment

audiocodecid

Number

Audio codec ID used in the file (see E.4.2.1 for available SoundFormat values)

audiodatarate

Number

Audio bit rate in kilobits per second

audiodelay

Number

Delay introduced by the audio codec in seconds

audiosamplerate

Number

Frequency at which the audio stream is replayed

audiosamplesize

Number

Resolution of a single audio sample

canSeekToEnd

Boolean

Indicating the last video frame is a key frame

creationdate

String

Creation date and time

duration

Number

Total duration of the file in seconds

filesize

Number

Total size of the file in bytes

framerate

Number

Number of frames per second

height

Number

Height of the video in pixels

stereo

Boolean

Indicating stereo audio

videocodecid

Number

Video codec ID used in the file (see E.4.3.1 for available CodecID values)

videodatarate

Number

Video bit rate in kilobits per second

width

Number

Width of the video in pixels

这里面的durationfilesize、视频的widthheight等这些信息对我们来说很有用.

 

该类型Tag又通常被称为Metadata Tag,会放一些关于FLV视频和音频的参数信息,如durationwidthheight等。通常该类型Tag会跟在File Header后面作为第一个Tag出现,而且只有一个。

一般来说,该Tag Data结构包含两个AMF包。AMFAction 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个字节表示元素值的类型。

       后面跟着为对应值,占用字节数取决于值的类型。

keyframes

  当时在做flv demux的时候,发现官方的文档中并没有对keyframes index做描述,但是flv的这种结构每个tag又不像TS有同步头,如果没有keyframes index 的话,seek及快进快退的效果会非常差,因为需要一个tag一个tag的顺序读取。后来通过网络查一些资料,发现了一个keyframes的信息藏在SCRIPTDATA中。

  keyframes几乎是一个非官方的标准,也就是民间标准.在网上已经很难看到flv文件格式,但是metadata里面不包含 keyframes项目的视频 . 两个常用的操作metadata的工具是flvtool2FLVMDI,都是把keyframes作为一个默认的元信息项目.FLVMDI的主页(http://www.buraks.com/flvmdi/)上有描述:

  keyframes: (Object) This object is added only if you specify the /k switch. 'keyframes' is known to FLVMDI and if /k switch is not specified, 'keyframes' object will be deleted.
'keyframes' object has 2 arrays: 'filepositions' and 'times'. Both arrays have the same number of elements, which is equal to the number of key frames in the FLV. Values in times array are in 'seconds'. Each correspond to the timestamp of the n'th key frame. Values in filepositions array are in 'bytes'. Each correspond to the fileposition of the nth key frame video tag (which starts with byte tag type 9).

  也就是说keyframes中包含着2个内容 'filepositions' and 'times'分别指的是关键帧的文件位置和关键帧的PTS.通过keyframes可以建立起自己的Index,然后再seek和快进快退的操作中,快速有效的跳转到你想要找的关键帧的位置进行处理。 


参考内容:

http://blog.csdn.net/leixiaohua1020/article/details/17934487



猜你喜欢

转载自blog.csdn.net/sunshine_505/article/details/80882279