參考文章看的是
http://www.360doc.com/content/16/1013/17/474846_598171645.shtml
測試檔案
相關檔案和部分工具
csdn下載下傳連結
cuc_ieschool.flv
使用相關工具如下:
float2hex.exe(二進制轉double的工具)
對比工具:
FlvAnalyzer
二進制檔案分析工具
Uedit32.exe
flv檔案頭(9+4 B)
前三個位元組 flv ,1 是版本 , 第五個位元組(1/4/5) , 1 video , 4 audio , 5 video and audio
腳本tag(script tag 11 B)
第一個B , tag type , 若 8 audio , 9 video , 0x12 metadata
3B body size (00 02 27)
3B timestamp
1B ,00
3B StreamId
amf0:資料中的儲存方式都是使用amf來序列化,本質上就是把int,double,String,都是用二進制存儲的,讀取的時候要能知道他分别是什麼資料
比如0x01就是boolean類型,後面的一位就是判斷ture,false的。
如果0x02代表string ,後面兩個位元組代表這個String有長,後面的就是String的内容。
第一個AMF包(1+2+10 = 13B)
00 0A ,代表這個String有10個位元組
後10 B ,就是這個String 的内容 “onmetadata”
第二個AMF包
0x08 是amf0中的MixedArray 相當于map,key-value 鍵值對
0x19表示元素個數 25個
那麼後面的元素都是使用key-value的方式存儲
主要是存儲一些基本資訊,比如duration,width,height,samplerate,一些視訊音頻的基本資訊資料。
元素“duration”(19B)
0x00 ,0x08長度 後8B “duration”
緊跟的一個位元組0x00就是後面的資料類型(number)占用8個位元組的double類型。
這個時候使用浮點轉換工具
float2hex.exe
得知是34.159秒
元素“width”(16B)
0x00 0x05 ,長度5 也就是 “width”
0x00 是number ,轉換的512(像素)
元素height(17B)
0x00 , 0x06 長度 “height”
0x00 number 轉換為 288(像素)
元素“videodatarate”(24B)
0x00 0x0D 13個長度videodatarate
視訊碼率為 179kb/s
元素framerate(20B)
0x09 長度 就是“framerate”
0x00 number
元素videocodecid(23B)
0x0c 12個元素“videocodecid”
0x00 number
轉換得 7 (視訊的編解碼器) , 因為有個對應表
元素audiodatarate(24B)
0x0d 就是audiodatarate的長度
0x00 number
音頻碼率
元素audiosamplearate(26B)
0x0f 16 audiosamplearate的長度
0x00 number
采樣率 44100
元素“audiosamplesize”(26B)
0x0f audiosamplesize的長度
0x00 number
采樣深度 16位
元素stereo(10位元組)
0x06 stereo的長度
後1B ,AMF0中的bool類型
最後1B ,0是單聲道。1是雙聲道
元素audiocodecid
0x0c audiocodecid 的長度
0x00 number
音頻的編解碼器 2
元素metadatacreator
0x0f metadatacreator 的長度
0x02 amf 中的String
0x00 0x03長度為3
内容是iku ,好像是用來辨別視訊中的資料是誰處理的
元素haskeyframes
0x0c 字元串的長度
0x02是amf中的字元串
0x00 , 0x04 是字元串長度 内容是true
元素hasvideo
0x08 字元串長度
0x02 是amf 中的String
0x00 0x04是長度 對應的true
元素hasaudio
同上。
元素hasmetadata
道理同上
元素canseektoend
同上,用來判斷是否可以滑動。
元素datasize
元素大小用string儲存的932906
元素videosize
Videosize大小是787866
元素audiosize
Audiosize元素大小140052
元素lasttimestamp
應該是最後一幀的時間戳
元素lastkeyframetimestamp
Lastkeyframetimestamp = 30 是最後一幀關鍵幀的時間戳
元素lastkeyframelocation
最後關鍵幀的位置886498
元素encoder
内容是Lavf55.19.104
元素filessize
檔案大小,轉換得1358127B , 也就是實際檔案大小
這應該是metadata結束标志
0x00 ,0x00 空字元串
0x09 Amf end of object
Previous tag size
内容是376
第一個videotag(11B)
0x09是tagtype 9是video , 0x08是audio , 0x12metadata
後3B 是bodysize ,
後3B是TimeStamp
後1B是timestampExtend
後3B 是StreamId
Video tag 資料部分固定的前5個位元組
0x17 的二進制是 10111 ,高四位是frametype , 低四位是codecid
10111 向左移動4位,就是frametype = 1 , 那麼codeid是7
後1B,是看是什麼資料類型。
0:avc序列頭 ,那麼後面的資料就是sps ,pps部分
1:avc nalu單元 ,後面的資料部分就是nalu單元
2:avc序列結束。低級别avc不需要
後3B 如果avc packet類型為1,那麼這3B為cts偏移。
見下圖
接下來就是previous tag size(4B)
前一個tag的大小共 56 位元組,body size(45)+ tag header(11) = 56
第一個audioTag
0x08 是tag type 。0x08 是audio
3B body size
3B 是TimeStamp
1B 是timeStampExtended
3B Stream ID
接下來資料部分的第一個位元組
4位是音頻格式
2位采樣率
1位采樣大小
1位聲道
見下圖
手動解析效果如下:
解析代碼在
檔案解析代碼如下 FlvParse.cpp