0. 前言
FLV 是 flash video 的縮寫,是 Adobe Flash payler 支持的一種流媒體播放格式。flv文件格式的官方文檔 Adobe Flash Video File Format Specification Version 10.1 的附錄E里。
flv文件格式由flv header和許多tag組成,一個flv文件只有一個flv header,tag 類型分為音頻、視頻、腳本,共三種類型,tag 由 tag 頭和 tag 數據組成。
1. FLV Header
FLV header有 9 個字節,定義如下
字段 | 類型 | 描述 |
---|---|---|
Signature | UI8 | 總是'F', 0x46 |
Signature | UI8 | 總是'L', 0x4C |
Signature | UI8 | 總是'V', 0x56 |
version | UI8 | 文件版本號,總是1 |
保留字段 | UB5 | 0 |
TypeFlagsAudio | UB1 | 0-無音頻;1-有音頻 |
保留字段 | UB1 | 0 |
TypeFlagsVideo | UB1 | 0-無視頻;1-有視頻 |
DataOffset | UI32 | flv頭的長度,version=1時,總是9 |
2. FLV File Body
flv 文件體由許多tag挨個存儲組成,每個tag的前四個字節表示前一個tag的長度。
2.1 FLV tag 格式
tag 的格式如下
字段 | 類型 | 描述 |
---|---|---|
Reserved | UB2 | 保留字段,總是0 |
Filter | UB1 | 表示包是否被處理過,如加密處理,0-未加密,1-加密 |
TagType | UB5 | tag類型,8 - audio,9 - video, 18 - script data |
DataSize | UI24 | 消息的長度。從StreamID到標簽結束的字節數(等於tag的長度- 11) |
Timestamp | UI24 | 數據的時間戳,單位是ms |
TimestampExtended | UI8 | 擴展時間戳,這字節與前3字節組成SI32的時間戳,前三位是低24bit值 |
StreamID | UI24 | 總是0 |
AudioTagHeader | AudioTagHeader | 如果TagType==8,接着就是音頻tag頭,AudioTagHeader定義在2.2.1小節 |
VideoTagHeader | VideoTagHeader | 如果TagType==9,接着就是視頻tag頭,VideoTagHeader定義在后面 |
EncryptionHeader | EncryptionHeader | 如果Filter==1,接着就是加密頭,EncryptionHeader定義在后面 |
FilterParams | FilterParams | 如果Filter==1才有此字段 |
Data | tag的數據,數據格式與TagType的類型有關,if TagType == 8,AUDIODATA; if TagType == 9,VIDEODATA;if TagType == 18,SCRIPTDATA |
2.2 AUDIO DATA
音頻數據由音頻tag頭和音頻data構成。
2.2.1 音頻tag頭
音頻tag頭一個字節或者2個字節
字段 | 類型 | 描述 |
---|---|---|
SoundFormat | UB4 | 音頻編碼格式,定義入下: 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 7, 8, 14, 15是保留值 |
SoundRate | UB2 | 采樣率 0 = 5.5 kHz 1 = 11 kHz 2 = 22 kHz 3 = 44 kHz |
SoundSize | UB1 | 采樣位數 0 = 8-bit 1 = 16-bit |
SoundType | UB1 | 聲道模式 0 = 單聲道 1 = 雙聲道(立體聲) |
AACPacketType | UI8 | AAC包類型,如果SoundFormat = 10 才會有這個字段 0 = AAC sequence header 1 = AAC raw |
2.2.2 AAC音頻數據
字段 | 類型 | 描述 |
---|---|---|
data | IF AACPacketType == 0 AudioSpecificConfig ELSE IF AACPacketType == 1 Raw AAC frame data in UI8 [] |
AudioSpecificConfig定義在 ISO/IEC 14496-3 2009 中第1.6.2.1小節。請注意,這與來自MP4/F4V文件的esds box的內容不同 |
ISO/IEC 14496-3 2009確實不好找,但是我還是找到了。https://csclub.uwaterloo.ca/~ehashman/ISO14496-3-2009.pdf,有可能這個地址會失效,也可以點這里下載 ISO-IEC-14496-3-2009.7z。
AudioSpecificConfig
AudioSpecificConfig的結構在ISO/IEC 14496-3中描述得好復雜,wiki 的描述簡潔一些。
5 bits: object type #AudioObjectType
if (object type == 31)
6 bits + 32: object type
4 bits: frequency index #samplingFrequencyIndex
if (frequency index == 15)
24 bits: frequency
4 bits: channel configuration #channelConfiguration
var bits: AOT Specific Config
AudioObjectType定義在 ISO/IEC 14496-3 的 1.5.1.1 table 1.1
samplingFrequencyIndex對應表
samplingFrequencyIndex | 值 |
---|---|
0x0 | 96000 |
0x1 | 88200 |
0x2 | 64000 |
0x3 | 48000 |
0x4 | 44100 |
0x5 | 32000 |
0x6 | 24000 |
0x7 | 22050 |
0x8 | 16000 |
0x9 | 12000 |
0xa | 11025 |
0xb | 8000 |
0xc | 7350 |
0xd | reseverd |
0xe | reseverd |
0xf | escape value |
channelConfiguration 定義在 ISO/IEC 14496-3 的 1.6.3.5
以上定義可以查看這里 MPEG-4 Audio wiki 。
2.3 VIDEO DATA
視頻數據由視頻tag頭和視頻data構成。
2.3.1 視頻tag頭
字段 | 類型 | 描述 |
---|---|---|
Frame Type | UB4 | 視頻幀類型,定義如下: 1 = 關鍵幀 2 = 非關鍵幀(inter frame) 3 = disposable inter frame (H.263 only) 4 = generated key frame (reserved for server use only) 5 = video info/command frame |
CodecID | UB4 | 編碼格式,定義如下: 2 = H.263 3 = Screen video 4 = On2 VP6 5 = On2 VP6 with alpha channel 6 = Screen video version 2 7 = AVC(H264) |
AVCPacketType | if CodecID == 7 UI8 |
0 = AVC sequence header(序列頭) 1 = AVC NALU 2 = AVC end of sequence |
CompositionTime | IF CodecID == 7 SI24 |
IF AVCPacketType == 1 {Composition time offset} ELSE {0} 壓縮時間定義在ISO 14496-12, 8.15.3,在FLV中時間偏移單位是ms |
2.3.2 AVC視頻packet
字段 | 類型 | 描述 |
---|---|---|
Data | IF AVCPacketType == 0 {AVCDecoderConfigurationRecord} IF AVCPacketType == 1 |
如果AVCPacketType為0,data是AVC的編碼配置信息,解碼器需要使用,AVCDecoderConfigurationRecord定義在ISO/IEC 14496-15 5.2.4.1,此段和MP4/FLV中 avcc box 的內容一樣;如果AVCPacketType為1,data是AVC的編碼幀 |
ISO/IEC 14496-15確實不好下載,官方的需要買的,我找了好久找了到2010的第二版,我想第二版比第一版要好吧。我提供 ISO/IEC 14496-15 2010下載。
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;
}
}
}