#include "stdafx.h"
#include <windows.h>
typedef struct FLV_HEADER
{
BYTE btSignature[3];
BYTE btVersion;
BYTE btFlags;
BYTE btDataOffset[4];
FLV_HEADER()
{
memset(this, 0, sizeof(FLV_HEADER));
}
};
typedef struct TAG_HEADER
{
BYTE btPreviousTagSize[4];
BYTE btTagType;
BYTE btDataSize[3];
BYTE btTimeStamp[3];
BYTE btReserved;
BYTE btStreamID[3];
TAG_HEADER()
{
memset(this, 0, sizeof(TAG_HEADER));
}
};
void printfTagAudioInfo(TAG_HEADER& _tag_header, int j, DWORD dwPreviousTagSize, DWORD dwDataSize, DWORD dwTimeStamp, BYTE btAudioFormat, BYTE btSamplingRate, BYTE btSamplingLen, BYTE btAudioType)
{
printf("%d :%d ", j, dwPreviousTagSize);
if (_tag_header.btTagType == 0x08){
printf("Audio ");
}
if (_tag_header.btTagType == 0x09){
printf("vedio ");
}
if (_tag_header.btTagType == 0x12){
printf("srcipt ");
}
printf(":%d :%d ", dwDataSize, dwTimeStamp);
switch (btAudioFormat)
{
case 0:
printf("Linear PCM, platform endian");
break;
case 1:
printf("ADPCM");
break;
case 2:
printf("MP3");
break;
case 3:
printf("Linear PCM, little endian");
break;
case 4:
printf("Nellymoser 16-kHz mono");
break;
case 5:
printf("Nellymoser 8-kHz mono");
break;
case 6:
printf("Nellymoser");
break;
case 7:
printf("G.711 A-law logarithmic PCM");
break;
case 8:
printf("G.711 mu-law logarithmic PCM");
break;
case 9:
printf("reserved");
break;
case 10:
printf("AAC");
break;
case 11:
printf("Speex");
break;
case 14:
printf("MP3 8-Khz");
break;
case 15:
printf("Device-specific sound");
break;
default:
printf("UNKNOWN");
break;
}
printf(" ");
switch (btSamplingRate)
{
case 0:
printf("5.5-kHz");
break;
case 1:
printf("1-kHz");
break;
case 2:
printf("22-kHz");
break;
case 3:
printf("44-kHz");
break;
default:
printf("UNKNOWN");
break;
}
printf(" ");
switch (btSamplingLen)
{
case 0:
printf("8Bit");
break;
case 1:
printf("16Bit");
break;
default:
printf("UNKNOWN");
break;
}
printf(" ");
switch (btAudioType)
{
case 0:
printf("Mono");
break;
case 1:
printf("Stereo");
break;
default:
printf("UNKNOWN");
break;
}
printf("\r\n");
}
void printfTagVedioInfo(TAG_HEADER& _tag_header, int j, DWORD dwPreviousTagSize, DWORD dwDataSize, DWORD dwTimeStamp, BYTE btFrameType, BYTE btCodecID)
{
printf("%d :%d ", j, dwPreviousTagSize);
if (_tag_header.btTagType == 0x08){
printf("Audio ");
}
if (_tag_header.btTagType == 0x09){
printf("vedio ");
}
if (_tag_header.btTagType == 0x12){
printf("srcipt ");
}
printf(":%d :%d ", dwDataSize, dwTimeStamp);
switch (btFrameType)
{
case 1:
printf("key frame ");
break;
case 2:
printf("inter frame");
break;
case 3:
printf("disposable inter frame");
break;
case 4:
printf("generated keyframe");
break;
case 5:
printf("video info/command frame");
break;
default:
printf("UNKNOWN");
break;
}
printf(" ");
switch (btCodecID)
{
case 1:
printf("JPEG (currently unused)");
break;
case 2:
printf("Sorenson H.263");
break;
case 3:
printf("Screen video");
break;
case 4:
printf("On2 VP6");
break;
case 5:
printf("On2 VP6 with alpha channel");
break;
case 6:
printf("Screen video version 2");
break;
case 7:
printf("AVC");
break;
default:
printf("UNKNOWN");
break;
}
printf("\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
BYTE *btData = NULL;
DWORD dwFileSize = 0;
HANDLE hFile = CreateFile(L"E:\\video\\cuc_ieschool.flv", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE){
dwFileSize = GetFileSize(hFile, NULL);
btData = new BYTE[dwFileSize];
memset(btData, 0, dwFileSize);
DWORD dwRead = 0;
ReadFile(hFile, btData, dwFileSize, &dwRead, NULL);
CloseHandle(hFile);
}
FLV_HEADER _flv_header;
memcpy(&_flv_header, btData, sizeof(FLV_HEADER));
printf("%c %c %c 版本:%d 视频:%d 音频:%d\n", _flv_header.btSignature[0], _flv_header.btSignature[1], _flv_header.btSignature[2], _flv_header.btVersion, _flv_header.btFlags & 0x1, (_flv_header.btFlags >> 2) & 0x01);
int j = 1;
int i = sizeof(FLV_HEADER);
while (i < dwFileSize){
TAG_HEADER _tag_header;
memcpy(&_tag_header, btData + i, sizeof(TAG_HEADER));
DWORD dwPreviousTagSize = (_tag_header.btPreviousTagSize[0]<<24) | (_tag_header.btPreviousTagSize[1]<<16) | (_tag_header.btPreviousTagSize[2] <<8) | _tag_header.btPreviousTagSize[3];
DWORD dwDataSize = (_tag_header.btDataSize[0]<<16) | (_tag_header.btDataSize[1]<<8) | _tag_header.btDataSize[2];
DWORD dwTimeStamp = (_tag_header.btTimeStamp[0]<<16) | (_tag_header.btTimeStamp[1]<<8) | _tag_header.btTimeStamp[2];
if (_tag_header.btTagType == 0x08){
BYTE btInfo = btData[i + sizeof(TAG_HEADER)];//取得音频信息
BYTE btAudioFormat = btInfo>>4;//音频格式.
BYTE btSamplingRate = (btInfo>>2) & 0x03;//采样率0 = 5.5-kHz;1 = 11-kHz;2 = 22-kHz;3 = 44-kHz;对于AAC总是3
BYTE btSamplingLen = (btInfo>>1) & 0x01;//采样长度.0 = snd8Bit;1 = snd16Bit;压缩过的音频都是16bit
BYTE btAudioType = btInfo & 0x01;
printfTagAudioInfo(_tag_header, j, dwPreviousTagSize, dwDataSize, dwTimeStamp, btAudioFormat, btSamplingRate, btSamplingLen, btAudioType);
}
if (_tag_header.btTagType == 0x09){
BYTE btInfo = btData[i + sizeof(TAG_HEADER)];//取得视频信息
BYTE btFrameType = btInfo >>4;//帧类型
BYTE btCodecID = btInfo & 0x0f;
printfTagVedioInfo(_tag_header, j, dwPreviousTagSize, dwDataSize, dwTimeStamp, btFrameType, btCodecID);
}
j++;
i += sizeof(TAG_HEADER) + dwDataSize;//每个Tag由也是由两部分组成的:Tag Header和Tag Data。
}
if (btData){
delete[] btData;
btData = NULL;
}
return 0;
}
http://download.csdn.net/detail/sz76211822/9716241
格式解析:http://blog.csdn.net/sz76211822/article/details/53760825