C++ 解析flv文件

#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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值