FLV檔案解析

2021-06-17 23:33:20 字數 4452 閱讀 6037

flv header

一般比較簡單,包括檔案型別之類的全域性資訊

檔案型別

3bytes

總是flv(0x46 0x4c 0x56),否則...

版本1byte

一般是0x01,表示flv version 1

流資訊1byte

header長度

4bytes

整個檔案頭的長度,一般是9(3+1+1+4),有時候後面還有些別的資訊,就不是9了

flv body

flv body就是由很多tag組成的,乙個tag包括下列資訊:

previoustagsize

4bytes

前乙個tag的長度,第乙個tag就是0

tag型別

1byte

三類:

資料區長度

3bytes

時間戳3bytes

單位毫秒,如果是指令碼tag就是0

擴充套件時間戳

1byte

作為時間戳的高位

streamsid

3bytes

總是0(不知道幹啥用)

資料區根據不同的tag型別就有不同的資料區

audio tag 資料區

audio資訊

1byte

前四位bits表示音訊格式:

下面兩位bits表示samplerate:

下面一位bit表示每個取樣的長度:

下面一位bit表示型別:

audio資料區

不定video tag 資料區

video資訊

1byte

前四位bits表示型別:

後四位bits表示編碼器id:

video資料區

不定**:

#include

#include

#include

#include

#include

using namespace std;

#define hton16(x)  ((x>>8&0xff)|(x<<8&0xff00))

#define hton24(x)  ((x>>16&0xff)|(x<<16&0xff0000)|x&0xff00)

#define hton32(x)  ((x>>24&0xff)|(x>>8&0xff00)|\

(x<<8&0xff0000)|(x<<24&0xff000000))

#define str(x) (x.c_str())

#define fcur(x) (ftell(x))

#define fseek(x,f) (fseek(f,x,seek_cur))

#define fset(x,f) (fseek(f,x,seek_set))

#define log(x,f) (fprintf(f,str(x)))

file *ffile=null;

file *flog=null;

int audionum=0;

int videonum=0;

int lasttime=0;

unsigned int size;

bool init();

void clear();

bool read8(int &i8,file*f);

bool read16(int &i16,file*f);

bool read24(int &i24,file*f);

bool read32(int &i32,file*f);

bool readtime(int &itime,file*f);

bool peek8(int &i8,file*f);

bool readhead();

void readbody();

string getaudioinfo(int info);

string getvideoinfo(int info);

char filename[256]=;

char logfilename[256]=;

bool hasname=false;

int main(int argc,char**argv)

if(!init())

if(!readhead())

readbody();

printf("time:%.4f s audio num:%d video num:%d\n",lasttime*1.0/1000,audionum,videonum);

fprintf(flog,"time:%.4f s audio num:%d video num:%d\n",lasttime*1.0/1000,audionum,videonum);

cout<<"read over"return 0; }

bool init()

ffile=fopen(filename,"rb");

flog=fopen(logfilename,"wb");

if(ffile==null||flog==null)

fseek(ffile,0,seek_end);

size=fcur(ffile);

fseek(ffile,0,seek_set);

return true; }

void clear()

bool read8(int &i8,file*f)

bool read16(int &i16,file*f)

bool read24(int &i24,file*f)

bool read32(int &i32,file*f)

bool peek8(int &i8,file*f)

bool readtime(int &itime,file*f)

bool readhead()

fseek(2,ffile);

if (!read32(headlength,ffile))

return false;

printf("headlength:%d\n",headlength);

/跳過頭部長度/

fseek(ffile,0,seek_set);

fseek(headlength,ffile);

return true; }

void readbody() ;

sprintf(m_tt,"fseek:%d ",fcur(,ffile));

temp+=m_tt;

fseek(4,ffile);

int type=0;

int time=0;

int htime=0;

int datelength=0;

int info=0;

char buff[256]=;

if (!read8(type,ffile))

break;

if (!read24(datelength,ffile))

break;

if(!readtime(time,ffile))

break;

/*if (!read24(time))

break;

//時間高位///

if (!read8(htime))

break;

*/跳過streamid/

fseek(3,ffile);

if(!peek8(info,ffile))

break;

lasttime=time;

switch(type)

temp+="\n";

log(temp,flog);

fseek(datelength,ffile); }

}string getaudioinfo(int info) ;

int temptype=0;

temptype=info>>4&0xf;

switch (temptype)

temptype=0;

temptype=info>>2&0x3;

switch (temptype)

temptype=0;

temptype=info>>1&0x1;

switch (temptype)

temptype=0;

temptype=info&0x1;

switch (temptype)

return temp; }

string getvideoinfo(int info) ;

int temptype=0;

temptype=info>>4&0xf;

switch (temptype)

memset(buff,0,100);

temptype=0;

temptype=info&0xf;

switch (temptype)

return temp; }

FLV檔案格式解析

flv是流 封裝格式,我們可以將其資料看為二進位制位元組流。總體上看,flv包括檔案頭 file header 和檔案體 file body 兩部分,其中檔案體由一系列的tag及tag size對組成。因此乙個flv檔案看上去是下面的結構 其中,previous tag size 緊跟在每個 tag...

FLV檔案格式解析

原創出處 flv是流 封裝格式,我們可以將其資料看為二進位制位元組流。總體上看,flv包括檔案頭 file header 和檔案體 file body 兩部分,其中檔案體由一系列的tag及tag size對組成。因此乙個flv檔案看上去是下面的結構 一 file header結構 file head...

FLV檔案格式解析

flv是流 封裝格式,我們可以將其資料看為二進位制位元組流。總體上看,flv包括檔案頭 fileheader 和檔案體 file body 兩部分,其中檔案體由一系列的tag及tagsize對組成。因此乙個flv檔案看上去是下面的結構 一 file header結構 fileheader在當前版本中...