H264 + AAC封裝FLV

H264 + AAC封裝FLV

FLV格式解析

FLV文件格式

FLV包含一個File Header以及File Body組成,其中File Body由無數個tag組成,結構如圖
在這裏插入圖片描述

FLV Header

FLV Header 由9個字節組成結構如下:

在這裏插入圖片描述

  • 第1-3字節:1-3字節爲文件標識,標識"FLV"0x46 0x4C 0x56
  • 第4字節:第4個字節位版本,總爲1
  • 第5字節:第5個字節的前5位保留,必須爲0,第6位標識是否有音頻,第7位保留爲0,第8位標識是否有視頻
  • 第6-9字節:第6-9個字節爲UI32類型的值,表示從File Header開始到File Body開始的字節數,版本1中總爲9

對應數據結構如下:

	
    
struct FlVHeader 
{
    unsigned char tag_f;
    unsigned char tag_l;
    unsigned char tag_v;
    unsigned char version;
    unsigned char streamInfo;
    unsigned char DataOffset[4];

    FlVHeader()
    {
        tag_f       = 'F';
        tag_l       = 'L';
        tag_v       = 'V';
        version     = 0x01;
        streamInfo  = 0x05; //有音頻也有視頻

        memset(DataOffset, 0, 4);
        DataOffset[3] = 0x09;
    }
};

FLV Body

Tag Header

FLV tag 包含Tag 頭(Tag Header)以及Tag 數據(Tag Body)兩個部分,Tag Header由11個字節組成結構如圖:

在這裏插入圖片描述

  • type : 音頻(0x08)、視頻(0x09)和script data(0x12)
  • tag size : 3個字節標識該tag data部分size
  • time : 3個字節標識時間戳字段(毫秒)
  • timeEx : 如果時間戳超過3個字節標識的範圍,可以用timeEX標識時間戳的高位

Audio Tag Data

音頻Tag Data 第一個字節標識音頻數據的格式,之後就是編碼完成之後的AAC音頻數據,每個AAC音頻數據採樣數爲1024:

  • 第1個字節的前4位的數值表示了音頻數據格式
  • 第1個字節的第5-6位的數值表示採樣率
  • 第1個字節的第7位表示採樣精度
  • 第1個字節的第8位表示音頻類型

生成音頻格式函數如下:



uint8_t createFLVTagAudioInfo(int audioCodec, int sampleRate, int channels, int sampleSize)
{
    uint8_t soundRate = 0;
    if (sampleRate <= 8 * 1000)
    	soundRate = FLV_SAMPLERATE_SPECIAL;
    else if (sampleRate > 8 * 1000 && sampleRate <= 20 * 1000)
    	soundRate = FLV_SAMPLERATE_11025HZ;
    else if (sampleRate > 20 * 1000 && sampleRate <= 30 * 1000)
    	soundRate = FLV_SAMPLERATE_22050HZ;
    else if (sampleRate > 30 * 1000)
   		soundRate = FLV_SAMPLERATE_44100HZ;

    uint8_t soundType = (1 == channels) ? 0 : 1;
    uint8_t soundBitsPerSample;
    
    if(sampleSize == 8)
    	soundBitsPerSample = FLV_SAMPLESSIZE_8BIT;
    else if(sampleSize == 16)
    	soundBitsPerSample = FLV_SAMPLESSIZE_16BIT;
    else if(sampleSize == 24)
    	soundBitsPerSample = FLV_SAMPLESSIZE_24BIT;
    
    uint8_t audioInfo = (audioCodec << FLV_AUDIO_CODECID_OFFSET) | (soundRate << FLV_AUDIO_SAMPLERATE_OFFSET) \
			| (soundBitsPerSample << FLV_AUDIO_SAMPLESSIZE_OFFSET) | soundType;

    return audioInfo;
}

Video Tag Data

和音頻數據類似,也是第一個字節標識視頻編碼信息,第二個字節開始爲視頻數據:

  • 第1個字節的前4位的數值標識AVC幀類型
  • 第1個字節的後4位的數值表示視頻編碼類型id

數據打包

寫FLV文件的時候先寫入FLV Header,然後寫入Script Tag(可以不用寫),之後交叉寫入VideoTag以及AudioTag,寫入Video Tag以及Audio Tag的時機在於判斷每個Tag的時間戳大小,優先寫入時間戳小的Tag。

源代碼詳見:https://github.com/HejiangK/lib_flv_mux

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章