Flv封装格式

本文深入介绍了FLV(Flash Video)格式的基本概念、整体结构及其组成部分,包括文件头、Tag序列等,并详细解析了音频和视频Tag的具体结构。

FLV(Flash Video)是Adobe公司设计开发的一种流行的流媒体格式,由于其视频文件体积轻巧、封装简单等特点,使其很适合在互联网上进行应用。此外,FLV可以使用Flash Player进行播放,而Flash Player插件已经安装在绝大部分浏览器上,这使得通过网页播放FLV视频十分容易。FLV封装格式的文件后缀通常为“.flv”。

FLV整体结构

整体来看,FLV包括文件头(File Header)和文件体(File Body)两部分,其中文件体由一系列的Tag组成。因此一个FLV文件结构如下图所示:

其中,每个Tag前面包含一个Previous Tag Size字段,表示前面一个Tag的大小。Tag的类型可以是视频、音频和Script,每个Tag有且只能是三种类型中的一种。FLV的详细结构如下所示:

Flv File Header

FieldTypeComment
SignatureUI8Signature byte always 'F' (0x46)
SignatureUI8Signature byte always 'L' (0x4C)
SignatureUI8Signature byte always 'V' (0x56)
VersionUI8File version (for example, 0x01 for FLV version 1)
TypeFlagsReservedUB[5]0
TypeFlagsAudioUB[1]1 : Audio Tags are present
TypeFlagsReservedUB[1]0
TypeFlagsVideoUB[1]1 : Video Tags are present
DataOffsetUI32The length of this flv file header in bytes
  • Signature:FLV文件的前3个字节固定为FLV,用来标识当前文件是flv格式。若发现前3个字节为“FLV”,就认为它是flv文件。
  • Version:第4个字节表示flv版本号,目前固定为1。
  • Flags:第5个字节中的第0位和第2位(从低位数),分别表示是否存在视频和音频Tag。(1表示存在,0表示不存在)
  • DataOffset:最后4个字节表示FLV File Header的长度,目前固定为00 00 00 09

所以一般情况下,同时包含音频和视频的Flv File Header的16进制(大端模式)为46 4C 56 01 05 00 00 00 09

Flv Tag

Flv的主体是Tag序列,Flv Tag的前11字节是固定的Tag Header,详细结构如下所示:

FieldTypeComment
ReservedUB[2]Reserved for FMS, should be 0
FilterUB[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.
TagTypeUB[5]Tag Type , 8 : audio , 9 : video , 18 : script data
DataSizeUI24Length of the Tag Body.
Number of bytes after StreamID to end of Tag (length of tag – 11)
TimestampUI24Time 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.
TimestampExtendedUI8Extension 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.
StreamIDUI24Always 0
XXTagHeaderAudioTagHeader (TagType == 8)
VideoTagHeader (TagType == 9)
音频Header or 视频Header
DataAudioData(TagType == 8)
VideoData(TagType == 9)
ScriptData(TagType == 18)
Data specific for each media type
  • TagType: Flv Tag第1个字节的低5位表示该Tag的类型,audio:8, video:9, Script:18。
  • DataSize: StreamID之后的数据长度.
  • Timestamp和TimestampExtended组成了这个TAG包数据的PTS信息,真正数据的PTS = Timestamp | TimestampExtended << 24.
  • 从开始到StreamID为止正好是11字节,后面的数据结构则取决于TagType,下面我们一个个的介绍。

Flv Script Tag

Flv File Header之后紧跟的第一个Tag一般是Script Tag,有且只有一个。该类型Tag又通常被称为Metadata Tag,存储一些关于Flv音频和视频的元数据信息,如:duration、width、height等,其结构如下所示:

第一个AMF包:

第1个字节表示AMF类型,一般总是0x02,表示字符串。第2-3个字节为UI16类型值,标识字符串的长度,一般总是0x000A(onMetaData长度)。后续字节则为具体字符串,一般总为“onMetaData”(6F 6E 4D 65 74 61 44 61 74 61)。

第二个AMF包:

第1个字节表示AMF类型,一般总是0x08,表示数组。第2-5个字节为UI32类型值,表示数组元素的个数。后面即为各数组元素的封装,数组元素为名称和值组成的Key-Value。常见的数组元素如下所示:

KeyTypeValue
durationNumber时长
filesizeNumber文件大小
widthNumber视频帧宽度
heightNumber视频帧高度
videodatarateNumber视频码率
framerateNumber视频帧率
videocodecidNumber视频编码方式,如:Avc、Hevc
audiocodecidNumber音频编码方式
audiodatarateNumber音频码率
audiosamplerateNumber音频采样率
audiosamplesizeNumber音频采样位数
audiochannelsNumber音频单通道 or 双通道
stereoBoolean是否为立体声,1:立体声(双声道)

有一点特别重要:Script Tag的两个AMF数据是紧跟在Script Tag11字节的Tag Header后面的。

Flv Audio Tag

参考之前Flv Tag的结构,若TagType等于8,则表示当前是音频Tag,StreamID之后的数据就是AudioTagHeader,AudioTagHeader结构如下:

FieldTypeComment
SoundFormatUB[4]Format of SoundData. The following values are defined:
0 : Linear PCM, platform endian
1 : ADPCM
2 : MP3
3 : Linear PCM, little endian
4 : Nellymoser 16 kHz mono
5 : Nellymoser 8 kHz mono
6 : Nellymoser
7 : G.711 A-law logarithmic PCM
8 : G.711 mu-law logarithmic PCM
9 : reserved
10 : AAC
11 : Speex
14 : MP3 8 kHz
15 : Device-specific sound
Formats 7, 8, 14 and 15 are reserved.
AAC is supported in Flash Player 9.0 and higher.
Speex is supported in Flash Player 10 and higher.
SoundRateUB[2]Sampling rate. The following values are defined:
0 : 5.5 kHz
1 : 11 kHz
2 : 22 kHz
3 : 44 kHz
SoundSizeUB[1]Size of each audio sample. This parameter only pertains to uncompressed formats.
0 : 8-bit samples
1 : 16-bit samples
SoundTypeUB[1]Mono or stereo sound
0 : Mono sound
1 : Stereo sound
AACPacketTypeUI8 (if SoundFormat == 10)What the following values are ?
0 : AAC sequence header
1 : AAC raw

AudioTagHeader的第1个字节,也就是紧跟在StreamID后面的1个字节包含着音频类型、采样率、采样位数、声道等基本信息。 AudioTagHeader之后就是AudioData数据了。但是这里有个特例,如果音频格式(SoundFormat)是10(AAC),AudioTagHeader中会多出1字节的AACPacketType结构,这个字段表示AACAudioData的类型:

  • 0 : AAC sequence header
  • 1 : AAC raw

如果AACPacketType等于0,那么紧跟在AudioTagHeader后面的Data就是AAC sequence header,AAC sequence header包含了AudioSpecificConfig,AudioSpecificConfig包含着一些更加详细的音频信息。 一般情况下,AAC sequence header只会出现1次,而且是第一个Audio Tag。为什么需要这种Tag,因为如果是AAC音频,需要在每帧AAC ES流前面添加7字节的ADST头,这是解码器通用的格式,就是要把AAC的纯ES流打包成ADST格式的AAC文件,解码器才能正常播放。在打包ADST的时候,需要samplingFrequencyIndex信息,而samplingFrequencyIndex最准确的信息就在AudioSpecificConfig中,所以就需要对AudioSpecificConfig进行解析得到samplingFrequencyIndex。

如果AACPacketType等于1,那么紧跟在AudioTagHeader后面的Data就是AAC raw,即音频ES流。

有一点特别重要:Audio Tag的数据是紧跟在Audio Tag11字节的Tag Header后面的。

Flv Video Tag

参考之前Flv Tag的结构,若TagType等于9,则表示当前是视频Tag,StreamID之后的数据就是VideoTagHeader,VideoTagHeader结构如下:

FieldTypeComment
Frame TypeUB[4]Type of video frame. The following values are defined:
1 : key frame (for AVC, a seekable frame)
2 : inter frame (for AVC, a non-seekable frame)
3 : disposable inter frame (H.263 only)
4 : generated key frame (reserved for server use only)
5 : video info/command frame
CodecIDUB[4]Codec Identifier. The following values are defined:
2 : Sorenson H.263
3 : Screen video
4 : On2 VP6
5 : On2 VP6 with alpha channel
6 : Screen video version 2
7 : AVC
AVCPacketTypeUI8(if CodecID == 7)The following values are defined:
0 : AVC sequence header
1 : AVC NALU
2 : AVC end of sequence (lower level NALU sequence ender is not required or supported)
CompositionTimeSI24(if CodecID == 7)IF AVCPacketType == 1
Composition time offset
else
0

VideoTagHeader的第1个字节,也就是紧跟在StreamID后面的1个字节包含着视频帧类型及视频编码信息。 VideoTagHeader之后就是VideoData数据了,当然就像音频AAC一样,这里也有特例:如果视频格式是AVC(H.264),VideoTagHeader中会多出4个字节信息:AVCPacketType和CompositionTime。其中,AVCPacketType表示AVCVideoData的类型:

  • 0 : AVCDecoderConfigurationRecord(AVC sequence header)
  • 1 : One or more NALUs (Full frames are required)
  • 2 : AVC end of sequence

如果AVCPacketType等于0,那么紧跟在VideoTagHeader后面的Data就是AVCDecoderConfigurationRecord,它包含着解码H264至关重要的sps和pps信息,再给AVC解码器送数据流之前一定要把sps和pps信息送出,否则解码器就不能正常解码。AVCDecoderConfigurationRecord在FLV文件中一般情况也只出现1次,也就是第一个Video Tag。

如果AVCPacketType等于1,那么紧跟在VideoTagHeader后面的Data就是NALU了(可能包含多个NALU),NALU存储的是Slice,多个Slice构成一帧图像,一个Video Tag必须至少包含一个完整的帧图像。

有一点特别重要:Video Tag的数据是紧跟在Video Tag11字节的Tag Header后面的。

参考文档

  1. FLV文件格式详解
  2. 视音频编解码学习工程:FLV封装格式分析器
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值