FLV文件分析
来源:博客园时间:2023-04-26 22:22:41

很久没看,做下关于FLV文件格式知识点回顾!

一、简单介绍

FLV(Flash Video)是Adobe公司推出的一种媒体封装格式。一个FLV文件,每个Tag类型都属于一个流。也就是说一个FLV文件最多只有一路音频流、一个路视频流,不能定义单个类型的多个独立流在一个文件中。 FLV数据以大端序存储,解析时需要注意。比如:0x12C,那么存储时就是0x01 0x2C。FLV封装格式由一个FLV Header和FLV Body组成,其中FLV Body由很多个Tag组成。Tag一般可以分为三种类型:脚本数据类型、音频数据类型、视频数据类型。 一个标准的FLV文件结构如下图所示:

二、FLV文件头


(资料图片)

FLV Header官方协议文档定义如下:

针对FLV Header相关字段,解释下其中的含义:

46 4c 56 01 05 20 20 20 09    //就代表该FLV文件包含音频、视频 

二、FLV文件Body

FLV Body 官方协议文档定义如下:

针对FLV Body相关字段,解释下其中的含义:

2.1 FLV Tag

每一个tag其实是由两部分组成,Tagheader(11 Byte)+Tagdata(实际数据域)。Tag Header中存放着TagType、DataSize等字段信息。而Tagdata部分就是实际数据域信息,后面会分别讲述数据域(Tag data)。其中FLVtag官方文档定义如下:

针对FLV Tag相关字段,解释下其中含义:

2.2 Tagdata

2.2.1 Audio data tags(音频数据tag)  

AUDIODATA官方协议文档定义如下:

针对AUDIODATA相关字段,解释下其中的含义:

AACAUDIODATA官方协议定义如下:

其中如果AACPacketType==0时,AudioSpecificConfig结构在ISO 14496-3文档中有定义该结构,部分结

构如下图:

AudioSpecificConfig() {        audioObjectType = GetAudioObjectType();        samplingFrequencyIndex; // 4 bslbf        if (samplingFrequencyIndex == 0xf) {                samplingFrequency; // 24 uimsbf        }        channelConfiguration; // 4 bslbf        sbrPresentFlag = -1;        psPresentFlag = -1;        if (audioObjectType == 5 || audioObjectType == 29) {                // ...        }        else {                extensionAudioObjectType = 0;        }        switch (audioObjectType) {        case 1: case 2: case 3: case 4: //...                GASpecificConfig();                break:        case ...:                //...        }        if (extensionAudioObjectType != 5 && bits_to_decode() >= 16) {                //...        }GetAudioObjectType() {        audioObjectType; // 5 uimsbf        if (audioObjectType == 31) {                audioObjectType = 32 + audioObjectTypeExt; // 6 uimsbf        }        return audioObjectType;}

2.2.2 Video data tags(视频数据Tag)

VIDEODATA官方协议文档定义如下:

针对VIDEODATA相关字段,解释下其中的含义:

AVCVIDEOPACKET官方协议定义如下:

其中如果是AVCPacketType==0时,即AVCsequenceheader,AVCDecoderConfigurationRecord在

ISO14496-15中定义如下:

aligned(8) class AVCDecoderConfigurationRecord {        unsigned int(8) configurationVersion = 1;        unsigned int(8) AVCProfileIndication;        unsigned int(8) profile_compatibility;        unsigned int(8) AVCLevelIndication;        bit(6) reserved = "111111"b;        unsigned int(2) lengthSizeMinusOne;        bit(3) reserved = "111"b;        unsigned int(5) numOfSequenceParameterSets;        for (i = 0; i < numOfSequenceParameterSets; i++) {                unsigned int(16) sequenceParameterSetLength ;                bit(8*sequenceParameterSetLength) sequenceParameterSetNALUnit;        }        unsigned int(8) numOfPictureParameterSets;        for (i = 0; i < numOfPictureParameterSets; i++) {                unsigned int(16) pictureParameterSetLength;                bit(8*pictureParameterSetLength) pictureParameterSetNALUnit;        }        if (profile_idc == 100 || profile_idc == 110 ||            profile_idc == 122 || profile_idc == 144)        {                bit(6) reserved = "111111"b;                unsigned int(2) chroma_format;                bit(5) reserved = "11111"b;                unsigned int(3) bit_depth_luma_minus8;                bit(5) reserved = "11111"b;                unsigned int(3) bit_depth_chroma_minus8;                unsigned int(8) numOfSequenceParameterSetExt;                for (i = 0; i < numOfSequenceParameterSetExt; i++) {                        unsigned int(16) sequenceParameterSetExtLength;                        bit(8*sequenceParameterSetExtLength) sequenceParameterSetExtNALUnit;                }        }}

如果是H265,HEVCDecoderConfigurationRecord定义如下:

aligned(8) class HEVCDecoderConfigurationRecord {        unsigned int(8) configurationVersion = 1;        unsigned int(2) general_profile_space;        unsigned int(1) general_tier_flag;        unsigned int(5) general_profile_idc;        unsigned int(32) general_profile_compatibility_flags;        unsigned int(48) general_constraint_indicator_flags;        unsigned int(8) general_level_idc;        bit(4) reserved = ‘1111’b;        unsigned int(12) min_spatial_segmentation_idc;        bit(6) reserved = ‘111111’b;        unsigned int(2) parallelismType;        bit(6) reserved = ‘111111’b;        unsigned int(2) chromaFormat;        bit(5) reserved = ‘11111’b;        unsigned int(3) bitDepthLumaMinus8;        bit(5) reserved = ‘11111’b;        unsigned int(3) bitDepthChromaMinus8;        bit(16) avgFrameRate;        bit(2) constantFrameRate;        bit(3) numTemporalLayers;        bit(1) temporalIdNested;        unsigned int(2) lengthSizeMinusOne;        unsigned int(8) numOfArrays;        for (j=0; j < numOfArrays; j++) {                bit(1) array_completeness;                unsigned int(1) reserved = 0;                unsigned int(6) NAL_unit_type;                unsigned int(16) numNalus;                for (i=0; i< numNalus; i++) {                        unsigned int(16) nalUnitLength;                        bit(8*nalUnitLength) nalUnit;                }        }}

关键词: