提取FLV视频文件中的音频到MP3文件(代码)

// 提取FLV视频文件中的音频到MP3文件

// FLV2MP3.cpp, visual c++ 6.0

// Usage: FLV2mp3 filename.flv
// 江岳华 2010,5 本程序只说明原理,未注意代码风格

 

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#include <io.h>
#include <conio.h>
#include <string.h>

#pragma comment(lib,"ws2_32")

typedef struct tagTAG
{
 UINT prelen;
 BYTEtype;//video=0x09,audio=0x08,metadata=0x12
 BYTE size24[3];
 BYTE ts24[3];
 BYTE tshigh;
 BYTE sid[3];//0x000000
}
TAG;


typedef struct tagTAG2
{
 UINT prelen;
 BYTEtype;//video=0x09,audio=0x08,metadata=0x12
 UINT size;
 UINT ts;
 UINT sid;
}
TAG2;

void tag_to_tag2(TAG* a, TAG2* b)
{
 if(!a || !b)return;
 memset(b,0,sizeof(TAG2));

 b->prelen =htonl(a->prelen);
 b->type =a->type;

 BYTE* p =(BYTE*)(a->size24);
 b->size =(p[0]<<16)|(p[1]<<8)|p[2];

 p = (BYTE*)(a->ts24);
 b->ts =(a->tshigh<<24)|(p[0]<<16)|(p[1]<<8)|p[2];

 p = (BYTE*)(a->sid);
 b->sid =(p[0]<<16)|(p[1]<<8)|p[2];
}

int main(int argc, char* argv[])
{
 if(argc<2)
 {
  puts("Usage: FLV2mp3filename.flv");
  return 0;
 }

 if(strlen(argv[1])>=256)
 {
  printf("File name lengtherror!\n");
  return 0;
 }

 FILE* fp = fopen(argv[1],"rb");
 if(!fp)
 {
  printf("Open file %sfailed!\n",argv[1]);
  return 0;
 }

 long flen = filelength(fileno(fp));
 if(flen<24)
 {
  printf("File lengtherror!\n");
  fclose(fp);
  return 0;
 }
 fseek(fp,0,0);

 unsigned char* buf = new unsignedchar[flen];
 if(!buf)
 {
  printf("Memory overerror!\n");
  fclose(fp);
  return 0;
 }

 long pos=0;
 while (pos < flen)
 {
  printf("\r%d",pos);
  int ret =fread(buf+pos,1,flen-pos,fp);
  if(ret <1)break;
  pos += ret;
  printf("\r%d",pos);
  if(pos >=flen)break;
 }
 if(pos != flen)
 {
  printf("Read file lengtherror!\n");
  delete[] buf;
  fclose(fp);
  return 0;
 }
 puts("\nRead file OK!\n");

 unsigned char* h = (unsigned char*)buf;
 if(memcmp(h,"FLV",3)!=0)
 {
  printf("Not flvfile!\n");
  delete[] buf;
  fclose(fp);
  return 0;
 }
 if(h[3]!=1)
 {
  printf("Not flv ver1.0!\n");
  delete[] buf;
  fclose(fp);
  return 0;
 }
 if(h[4] > 0x07)
 {
  printf("Flv header avbyteerror!\n");
  delete[] buf;
  fclose(fp);
  return 0;
 }
 if(h[4] & 0x02)
 {
  printf("Flv header avbyte error2!\n");
  delete[] buf;
  fclose(fp);
  return 0;
 }

 if(h[4] & 0x04)
  puts("has audio.");
 
 if(h[4] & 0x01)
  puts("has video.");

 UINT offset =(h[5]<<24)|(h[6]<<16)|(h[7]<<8)|h[8];
 printf("body offset = %d\n",offset);
 if(offset!=9)
  puts("warring: body offset !=9!!!\n");

 h += offset;

#define WRITE_AUDIO
#ifdef WRITE_AUDIO
 FILE *fw = NULL;
 char name[512];
 memset(name,0,sizeof(name));
 strncpy(name,argv[1],strlen(argv[1]));
 name[sizeof(name)-5]='\0';
 strcat(name,".mp3");
 fw = fopen(name,"wb");
#endif

 while ((h+15)<(buf+pos))
 {
  TAG* t = (TAG*)h;
  TAG2 t2;
  memset(&t2,0,sizeof(TAG2));
  tag_to_tag2(t,&t2);

  printf("prelen=%08lx,type=%x,size=%08lx,ts=%08lx\n",t2.prelen,t2.type,t2.size,t2.ts);

  BYTE *d = h+15;

  if(t2.type ==0x08)//audio
  {
   int len =t2.size-1;

   intsoundfmt=(d[0]>>4)&0x0f;
    //0= Linear PCM, platform endian
    //1= ADPCM  Formats 7, 8, 14, and 15are
    //2= MP3  reserved for internaluse
    //3= Linear PCM, little endian
    //4= Nellymoser 16-kHz mono AAC is supported in Flash
    //5= Nellymoser 8-kHz mono Player9,0,115,0 and higher.
    //6= Nellymoser
    //7= G.711 A-law logarithmic PCM Speex is supported in Flash
    //8= G.711 mu-law logarithmic PCM Player10 and higher.
    //9= reserved
    //10= AAC
    //11= Speex
    //14= MP3 8-Khz
    //15= Device-specific sound
   intsoundrate=(d[0]>>2)&0x03;
    //0= 5.5-kHz For AAC: always 3
    //1= 11-kHz
    //2= 22-kHz
    //3= 44-kHz
   intsoundsize=(d[0]>>1)&0x01;
    //0= snd8Bit parameter only pertains to
    //1= snd16Bit uncompressed formats.
    //  Compressedformats always
    //  decodeto 16 bits internally.
    //  0= snd8Bit
    //  1= snd16Bit
   intsoundtype=d[0]&0x01;
    //0= sndMono For Nellymoser: always 0
    //1= sndStereo For AAC: always 1
   printf("soundfmt=%d,soundrate=%d,soundsize=%d,soundtype=%d\n",
    soundfmt,soundrate,soundsize,soundtype);

#ifdef WRITE_AUDIO
   if(soundfmt==2)//MP3
    if(fw)fwrite(d+1,1,len,fw);
#endif
  }
  else if(t2.type ==0x09)//video
  {
  }
  else if(t2.type ==0x12)//metadata
  {
  }

  //准备下次
  h += (15+t2.size);
 }
#ifdef WRITE_AUDIO
 if(fw)fclose(fw);
 fw = NULL;
#endif

 delete[] buf;
 fclose(fp);
 return 0;
}

你可能感兴趣的:(提取FLV视频文件中的音频到MP3文件(代码))