解析swf文件的音频数据并生成mp3

本文介绍了一款能够从SWF文件中提取音频并转换为MP3格式的工具。通过解析SWF文件结构,该工具能识别并抽取音频数据,支持多种音频类型包括流式音频和事件音频。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#pragma once
#include <memory>
#include <Shlwapi.h>
#pragma comment(lib,"Shlwapi.lib")

#include <tchar.h>
#include <strsafe.h>

typedef unsigned char  UI8;
typedef unsigned short UI16;
typedef unsigned char UB;
typedef unsigned int  UI32;
typedef unsigned char byte;
//File mp3File;

#define SWFHEADSIZE 8
enum TagType
{
 /// <summary>Unknown tag</summary>
 Unknown = -1,
 /// <summary>End tag</summary>
 End = 0,
 /// <summary>ShowFrame tag</summary>
 ShowFrame = 1,
 /// <summary>DefineShape tag</summary>
 DefineShape = 2,
 /// <summary>PlaceObject tag</summary>
 PlaceObject = 3,
 /// <summary>RemoveObject tag</summary>
 RemoveObject = 4,
 /// <summary>DefineBits tag</summary>
 DefineBits = 6,
 /// <summary>DefineButton tag</summary>
 DefineButton = 7,
 /// <summary>JPEGTable tag</summary>
 JpegTable = 8,
 /// <summary>SetBackgroundColor tag</summary>
 SetBackgroundColor = 9,  
 /// <summary>DefineFont tag</summary>
 DefineFont = 10,
 /// <summary>DefineText tag</summary>
 DefineText = 11,
 /// <summary>DoAction tag</summary>
 DoAction = 12,
 /// <summary>DefineFontInfo tag</summary>
 DefineFontInfo = 13,
 /// <summary>DefineSound tag</summary>
 DefineSound = 14,
 /// <summary>StartSound tag</summary>
 StartSound = 15,
 /// <summary>DefineButtonSound tag</summary>
 DefineButtonSound = 17,
 /// <summary>SoundStreamHead tag</summary>
 SoundStreamHead = 18,
 /// <summary>SoundStreamBlock tag</summary>
 SoundStreamBlock = 19,
 /// <summary>DefineBitsLossLess tag</summary>
 DefineBitsLossLess = 20,
 /// <summary>DefineBitsJPEG2 tag</summary>
 DefineBitsJpeg2 = 21,
 /// <summary>DefineShape2 tag</summary>
 DefineShape2 = 22,
 /// <summary>DefineButtonCxForm tag</summary>
 DefineButtonCxForm = 23,
 /// <summary>Protect tag</summary>
 Protect = 24,
 /// <summary>PlaceObject2 tag</summary>
 PlaceObject2 = 26,
 /// <summary>RemoveObject2 tag</summary>
 RemoveObject2 = 28,
 /// <summary>DefineShape3 tag</summary>
 DefineShape3 = 32,
 /// <summary>DefineText2 tag</summary>
 DefineText2 = 33,
 /// <summary>DefineButton2 tag</summary>
 DefineButton2 = 34,
 /// <summary>DefineBitsJPEG3 tag</summary>
 DefineBitsJpeg3 = 35,
 /// <summary>DefineBitsLossLess2 tag</summary>
 DefineBitsLossLess2 = 36,
 /// <summary>DefineEditText tag</summary>
 DefineEditText = 37,
 /// <summary>DefineSprite tag</summary>
 DefineSprite = 39,
 /// <summary>FrameLabel tag</summary>
 FrameLabel = 43,
 /// <summary>SoundStreamHead2 tag</summary>
 SoundStreamHead2 = 45,
 /// <summary>DefineMorphShape tag</summary>
 DefineMorphShape = 46,
 /// <summary>DefineFont2 tag</summary>
 DefineFont2 = 48,
 /// <summary>ExportAssets tag</summary>
 ExportAssets = 56,
 /// <summary>ImportAssets tag</summary>
 ImportAssets = 57,
 /// <summary>EnableDebugger tag</summary>
 EnableDebugger = 58,
 /// <summary>InitAction tag</summary>
 InitAction = 59,
 /// <summary>DefineVideoStream tag</summary>
 DefineVideoStream = 60,
 /// <summary>VideoFrame tag</summary>
 VideoFrame = 61,
 /// <summary>DefineFontInfo2 tag</summary>
 DefineFontInfo2 = 62,
 /// <summary>EnableDebugger2 tag</summary>
 EnableDebugger2 = 64,
 /// <summary>ScriptLimit tag</summary>
 ScriptLimit = 65,
 /// <summary>SetTabIndex tag</summary>
 SetTabIndex = 66
};

struct RGB
{
 UI8 red;
 UI8 green;
 UI8 blue;
};
struct RGBA
{
 UI8 red;
 UI8 green;
 UI8 blue;
 UI8 alpha;
};
struct varRECT
{
 /************************************************************************/
 /* The FrameSize field defines the width and height of the on-screen display. This field is stored
 as a RECT structure, meaning that its size may vary according to the number of bits needed
 to encode the coordinates.                                                                     */
 /************************************************************************/
private:
 unsigned __int64 padA;
 unsigned __int64 padB;
public:
 int GetNbits()
 {
  return (padA>>3)&0x0000001F;
 }
 int GetRectBytesCount()
 {
  int Nbits = GetNbits();
  return (5+Nbits*4)/8+1;
 }
 //取一个字节的某几个字节,要从左边开始取
 void GetRect(RECT& rt)
 {
  
  unsigned char buf[16];
  memcpy(buf,&padA,8);
  memcpy(buf+8,&padB,8);

  int nByteIndex = 0;
  int nLeaveBits = 0;
  nLeaveBits = 3;
  int Nbits = buf[nByteIndex]>>nLeaveBits;
  
  int Xmin = 0;
  int size[4]={0,0,0,0};
  for (int n=0;n<4;n++)
  {
   int nFillBits = 0;
   while (nFillBits<Nbits)
   {
    if (nLeaveBits>0)
    {
     if (nLeaveBits<Nbits-nFillBits)
     {
      //取buf[nByteIndex]的剩下nLeaveBits位
      int andMode = 0;
      for (int i=0;i<nLeaveBits;i++)
      {
       andMode |= 0x01<<i;
      }
      size[n] |= (andMode&buf[nByteIndex])<<(Nbits-nFillBits-nLeaveBits);
      
      nFillBits += nLeaveBits;
      nLeaveBits = 0;
     }
     else
     {
      //取buf[nByteIndex]的剩下Nbits-nFillBits位
      int andMode = 0;
      int nNeedBits = Nbits - nFillBits;
      for (int i=0;i<nLeaveBits;i++)
      {
       if (i<nLeaveBits-nNeedBits)
        continue;
       andMode |= 0x01<<i;
      }
      nLeaveBits -= Nbits-nFillBits;
      size[n] |= (andMode&buf[nByteIndex])>>nLeaveBits;

      nFillBits += Nbits-nFillBits;
     }

    }
    else
    {
     //上一个字节填充完了,指向下一个字节
     nByteIndex++;
     nLeaveBits = 8;
    }
   }
  }
 
  //如果符号位为1,则转换数字
  int mode = 0x01<<(Nbits-1);
  int andmode = 0;
  for (int i=0;i<Nbits;i++)
  {
   andmode |= 0x01<<i;
  }
  andmode ^= 0xFFFFFFFF;
  for(int i=0;i<4;i++)
  {
   if (size[i]&mode)
   {
    size[i] |= andmode;
   }
  }
  rt.left = size[0];
  rt.right = size[1];
  rt.top = size[2];
  rt.bottom = size[3];
  return ;
 }
};

struct SwfFrameRate
{
private:
 unsigned short data;
public:
 float GetFrameRate()
 {
  unsigned char decimal = data&0xFF;
  float fDecimal = 0.0f;
  fDecimal+=(data>>8);
  for(int i=0;i<8;i++)
  {
   fDecimal += ((decimal&(0x80>>i))>>(7-i))*(1.0f/(2<<i));
  }
  return fDecimal;
 }
};
struct SwfFileHeader
{
 /************************************************************************/
 /* An FWS signature indicates an uncompressed SWF file; CWS
 indicates that the entire file after the first 8 bytes (that is, after the FileLength field) was
 compressed by using the ZLIB open standard.                                                                     */
 /************************************************************************/
 unsigned char Sigcompressed;
 unsigned char SigW;
 unsigned char SigS;
 unsigned char Version;
 /************************************************************************/
 /* If this is an uncompressed SWF file (FWS signature), the FileLength field should exactly match the file
 size. If this is a compressed SWF file (CWS signature), the FileLength field indicates the total
 length of the file after decompression, and thus generally does not match the file size.                                                                     */
 /************************************************************************/
 unsigned int FileLenth;
};
struct tagHeader
{
private:
 unsigned short TagCodeAndLength;
 unsigned short lowLength;
 unsigned short HighLength;
 
public:
 int GetType()
 {
  return TagCodeAndLength>>6;
 }
 //The length specified in the TagCodeAndLength field does not include the
 //RECORDHEADER that starts a tag.
 int GetLength()
 {
  int len = TagCodeAndLength&0x003F;
  return len;
 }
 int GetLengthEx()
 {
  signed long Length=0;
  Length |= lowLength;
  unsigned long high = HighLength;
  high=high<<16;
  Length |= high;
  return Length;
 }
};

struct tagSoundStreamHead2
{
 unsigned char PlaybackSoundType:1;
 unsigned char PlaybackSoundSize:1;
 unsigned char PlaybackSoundRate:2;
 unsigned char Reserved:4;

 unsigned char StreamSoundType:1;
 unsigned char StreamSoundSize:1;
 unsigned char StreamSoundRate:2;
 unsigned char StreamSoundCompression:4;

 unsigned short StreamSoundSampleCount;
 short LatencySeek;
};
struct tagFrameLabel
{
};
struct MATRIX
{
};
struct GRADIENT
{
};
struct FOCALGRADIENT
{
};
struct FILLSTYLE
{
 UI8 FillStyleType;
 union
 {
  RGBA ColorA;
  RGB  Color;
 };
 union
 {
  struct 
  {
   MATRIX GradientMatrix;
   GRADIENT Gradient;
  };
  FOCALGRADIENT FocalGradient;
  struct 
  {
   UI16 BitmapId;
   MATRIX BitmapMatrix;
  };

 };

};
struct FILLSTYLEARRAY
{
 UI8 FillStyleCount;
 union
 {
  struct 
  {
   UI16 FillStyleCountExtended;
   FILLSTYLE *FillStylesEx;
  };
  FILLSTYLE *FillStyles;
  
 };
 
};
struct LINESTYLE
{
};
struct LINESTYLE2
{
};
struct LINESTYLEARRAY
{
 UI8 LineStyleCount;//  Count of line styles.
 union
 {
  struct 
  {
   UI16 LineStyleCountExtended; //If LineStyleCount = 0xFF Extended count of line styles.
   union
   {
    LINESTYLE *LineStylesEx;// (if Shape1,Shape2, or Shape3)
    LINESTYLE2 *LineStyles2Ex;// (if Shape4)
   };
  };
  union
  {
   LINESTYLE *LineStyles;// (if Shape1,Shape2, or Shape3)
   LINESTYLE2 *LineStyles2;// (if Shape4)
  };
 };
};
struct SHAPERECORD
{
};
struct SHAPEWITHSTYLE
{
 LINESTYLEARRAY FillStyles;//Array of fill styles.
 LINESTYLEARRAY LineStyles;//Array of line styles.
 unsigned char Number:4;// Number of fill index bits.
 unsigned char NumLineBits:4;//Number of line index bits.
 SHAPERECORD ShapeRecords;// Shape records
};
/************************************************************************/
/* Generally speaking, tags in a SWF can occur in any order.            */
/************************************************************************/
/************************************************************************/
/* Following the header is a series of tagged data blocks. All tags share a common format, so any
program parsing a SWF file can skip over blocks it does not understand. */
/************************************************************************/
struct BaseTag
{
};
struct tagDefineSound
{
 UI16 SoundId;
 UB SoundType:1;
 UB SoundSize:1;
 UB SoundRate:2;
 UB SoundFormat:4;
 UI32 SoundSampleCount;
 byte *SoundData;

};
struct FrameHeader
{
 unsigned char sync1:8; //同步信息1   0xFF

 unsigned char crc:1; //CRC校验  0x01/0x00
 unsigned char layer:2; //层          0x01
 unsigned char version:2; //版本      0x03
 unsigned char sync2:3; //同步信息2   0x07

 unsigned char privatebit:1; //私有bit,可以用来做特殊应用 0x00
 unsigned char padding:1; //填充空白字    0x00/0x01
 unsigned char sample_rate_index:2; //采样率索引  0x00
 unsigned char bit_rate_index:4; //位率索引  0x0A

 unsigned char emphasis:2; //强调方式  0x00
 unsigned char original:1; //原始媒体 0x01
 unsigned char copyright:1; //版权标志 0x00
 unsigned char mode_extension:2; //扩展模式,仅用于联合立体声 0x00
 unsigned char channel_mode:2; //声道模式   0x00
};

struct MP3SOUNDDATA
{
 short SeekSamples;
 FrameHeader mp3FrameHead;
};

struct tagPlaceObject
{
 UI16 CharacterId;
 UI16 Depth;
 MATRIX matrix;
};

struct  tagPlaceObject2
{
 UB PlaceFlagMove:1;
 UB PlaceFlagHasCharacter:1;
 UB PlaceFlagHasMatrix:1;
 UB PlaceFlagHasColorTransform:1;
 UB PlaceFlagHasRatio:1;
 UB PlaceFlagHasName:1;
 UB PlaceFlagHasClipDepth:1;
 UB PlaceFlagHasClipActions:1;
 UI16 Depth;//  Depth of character
};
// int g_TagIndex = -1;
//
// void GetTagInfo(File& swf ,TagType type,int len)
// {
//
//  g_TagIndex++;
//
//  switch(type)
//  {
//  case SetBackgroundColor:
//   {
//    RGB backgroundColor;
//    swf.Read(&backgroundColor,len);
//    break;
//   }
//  case SoundStreamHead:
//   {
//    tagSoundStreamHead2 head;
//    swf.Read(&head,len);
//    break;
//   }
//  case SoundStreamHead2:
//   {
//    tagSoundStreamHead2 head;
//    swf.Read(&head,len);
//    break;
//   }
//  case SoundStreamBlock:
//   {
//    //printf("Writing sound data---%d/n",g_TagIndex);
//    unsigned char*pBuf = (unsigned char*)malloc(len);
//    swf.Read(pBuf,len);
//    mp3File.Write(pBuf+4,len-4);
//    free(pBuf);
//    break;
//   }
//  case FrameLabel:
//   {
//    unsigned char*pBuf = (unsigned char*)malloc(len);
//    swf.Read(pBuf,len);
//    break;
//   }
// //  case DefineShape2:
// //   {
// //    UI16 ShapeId;
// //    swf.Read(&ShapeId,sizeof(ShapeId));
// //    varRECT ShapeBounds;
// //    swf.Read(&ShapeBounds,sizeof(varRECT));
// //    RECT ShapeBoundsEx;
// //    ShapeBounds.GetRect(ShapeBoundsEx);
// //    int bytes = ShapeBounds.GetRectBytesCount();
// //    swf.Seek(bytes-sizeof(varRECT),FILE_CURRENT);
// //
// //    break;
// //   }
//  case DefineSound:
//   {
//    tagDefineSound ds;
//    swf.Read(&ds,7);
//    ds.SoundData = (byte*)malloc(len-7);
//    swf.Read(ds.SoundData,len-7);
//    MP3SOUNDDATA data;
//    CopyMemory(&data,ds.SoundData,6);
//    //mp3File.Write(ds.SoundData+2,len-9);
//    free(ds.SoundData);
//    break;
//   }
//  case PlaceObject2:
//   {
//    if (len>0)
//    {
//     unsigned char*pBuf = (unsigned char*)malloc(len);
//     swf.Read(pBuf,len);
//
//     tagPlaceObject2 po;
//     CopyMemory(&po,pBuf,3);
//
//     UI16 CharacterId = 0;
//     if (po.PlaceFlagHasCharacter)
//     {
//      CopyMemory(&CharacterId,pBuf+3,2);
//     }
//     if (po.PlaceFlagHasMatrix)
//     {
//     }
//     
//     free(pBuf);
//    }
//    break;
//   }
//  case RemoveObject:
//   {
//    if (len>0)
//    {
//     unsigned char*pBuf = (unsigned char*)malloc(len);
//     swf.Read(pBuf,len);
//     free(pBuf);
//    }
//    break;
//   }
//  case RemoveObject2:
//   {
//    if (len>0)
//    {
//     unsigned char*pBuf = (unsigned char*)malloc(len);
//     swf.Read(pBuf,len);
//     free(pBuf);
//    }
//    break;
//   }
//  case ShowFrame:
//   {
//    //do nothing
//    break;
//   }
//  case End:
//   {
//    //do nothing
//    break;
//   }
//  default:
//   {
//    if (len>0)
//    {
//     unsigned char*pBuf = (unsigned char*)malloc(len);
//     swf.Read(pBuf,len);
//     free(pBuf);
//    }
//
//   }
//   
//  }
//}

 

 

#pragma once
#include <windows.h>
#include <tchar.h>
//#include <strsafe.h>
class File
{
public:
 File(void);
public:
 ~File(void);

 BOOL Open(LPCTSTR lpFileName,DWORD dwDesiredAccess/*参考CreateFile*/);
 void Close();
 DWORD Seek(LONG lDistanceToMove,DWORD dwMoveMethod/*参考SetFilePointer*/);
 DWORD SeekToBegin( );
 DWORD SeekToEnd( );
 DWORD GetLength( ) const;
 DWORD Read( LPVOID lpBuffer,DWORD nNumberOfBytesToRead);
 DWORD Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite);
private:
 HANDLE m_hFile;
};

 

#include "StdAfx.h"
#include "File.h"
#include <assert.h>

extern DWORD g_dwLastError;
File::File(void)
{
 m_hFile=INVALID_HANDLE_VALUE;
}

File::~File(void)
{
 if (m_hFile!=INVALID_HANDLE_VALUE)
 {
  CloseHandle(m_hFile);
  m_hFile = INVALID_HANDLE_VALUE;
 }
}
BOOL File::Open(LPCTSTR lpFileName,DWORD dwDesiredAccess)
{
 m_hFile = CreateFile(lpFileName,dwDesiredAccess,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
 return m_hFile!=INVALID_HANDLE_VALUE ? TRUE:FALSE;
}
void File::Close()
{
 if (m_hFile!=INVALID_HANDLE_VALUE)
 {
  CloseHandle(m_hFile);
  m_hFile = INVALID_HANDLE_VALUE;
 }
}
DWORD File::Seek(LONG lDistanceToMove,DWORD dwMoveMethod/*参考SetFilePointer*/)
{
 assert(m_hFile!=INVALID_HANDLE_VALUE);
 return SetFilePointer(m_hFile,lDistanceToMove,NULL,dwMoveMethod);
}

DWORD File::SeekToBegin( )
{
 assert(m_hFile!=INVALID_HANDLE_VALUE);
 return SetFilePointer(m_hFile,0,NULL,FILE_BEGIN);
}
DWORD File::SeekToEnd( )
{
 assert(m_hFile!=INVALID_HANDLE_VALUE);
 return SetFilePointer(m_hFile,0,NULL,FILE_END);
}

DWORD File::GetLength( ) const
{
 assert(m_hFile!=INVALID_HANDLE_VALUE);
 return GetFileSize(m_hFile,NULL);
}

DWORD File::Read( LPVOID lpBuffer,DWORD nNumberOfBytesToRead)
{
 assert(m_hFile!=INVALID_HANDLE_VALUE);
 DWORD dwNumberOfBytesRead;
 ReadFile(m_hFile,lpBuffer,nNumberOfBytesToRead,&dwNumberOfBytesRead,NULL);
 return dwNumberOfBytesRead;
}

DWORD File::Write(LPVOID lpBuffer,DWORD nNumberOfBytesToWrite)
{
 assert(m_hFile!=INVALID_HANDLE_VALUE);
 DWORD dwNumberOfBytesWrite;
 WriteFile(m_hFile,lpBuffer,nNumberOfBytesToWrite,&dwNumberOfBytesWrite,NULL);
 return dwNumberOfBytesWrite;
}

 

#pragma once
#include "File.h"
#include "DataType.h"

#define  SWF_EXPORT __declspec(dllexport)
#define  WM_PROGRESS_CONVERT WM_USER+1001
class SWF_EXPORT CSwf : public File
{
private:
 SwfFileHeader m_head;
 RECT   m_rFrameSize;
 float   m_fFrameRate;
 USHORT   m_nFrameCount;

 BOOL CheckCompress();
 int  DeCompressSwf(const TCHAR *pDest,const TCHAR *pSrc);
public:
 CSwf();
public:
 ~CSwf(void);

 BOOL ReadSwf(const TCHAR *pFilePath);
 BOOL ParseSoundData2Mp3(const TCHAR *pMp3File);

 int  GetSwfVersion(){return m_head.Version;};
public:
 void SetMessageHwnd(HWND hwnd){m_hwnd = hwnd;};
private:
 TCHAR m_szSrcFile[MAX_PATH];
 DWORD m_dwHeadSize;
 HWND m_hwnd;
};

 

#include "StdAfx.h"
#include "Swf.h"
#include "zlib.h"
#pragma comment(lib,"zlib.lib")

static const TCHAR *pTmpFile = L"tmp.swf";
CSwf::CSwf()
{
 ZeroMemory(&m_head,sizeof(m_head));
 ZeroMemory(&m_rFrameSize,sizeof(m_rFrameSize));
 m_fFrameRate = 0.0f;
 m_nFrameCount = 0;
 m_dwHeadSize = 0;
 m_hwnd = NULL;
 ZeroMemory(m_szSrcFile,sizeof(m_szSrcFile));
}

CSwf::~CSwf(void)
{
 if (PathFileExists(pTmpFile))
 {
  Close();
  DeleteFile(pTmpFile);
 }
}

BOOL CSwf::ReadSwf(const TCHAR *pFilePath)
{
 StringCchCopy(m_szSrcFile,MAX_PATH,pFilePath);
 if(!Open(pFilePath,FILE_READ_DATA))
  return FALSE;
 if (CheckCompress())
 {
  Close();
  int err = DeCompressSwf(pTmpFile,pFilePath);
  if (err<0)
  {
   return FALSE;
  }
  if(!Open(pTmpFile,FILE_READ_DATA))
   return FALSE;
 }

 SeekToBegin();//前面可能有读过数据,必须seek到开始,确保读取正确数据

 DWORD dwRead = 0;
 dwRead = Read(&m_head,SWFHEADSIZE);
 m_dwHeadSize+=SWFHEADSIZE;

 varRECT FrameSize;
 dwRead = Read(&FrameSize,sizeof(FrameSize));
 FrameSize.GetRect(m_rFrameSize);

 Seek(FrameSize.GetRectBytesCount()-dwRead,FILE_CURRENT);//读取的字节比实际需要大了,需要往前seek
 m_dwHeadSize+=FrameSize.GetRectBytesCount();

 SwfFrameRate fr;
 dwRead = Read(&fr,sizeof(fr));
 m_fFrameRate = fr.GetFrameRate();
 m_dwHeadSize+=dwRead;

 dwRead = Read(&m_nFrameCount,sizeof(m_nFrameCount));
 m_dwHeadSize+=dwRead;
}
BOOL CSwf::ParseSoundData2Mp3(const TCHAR *pMp3File)
{
 File mp3File;
 File mp3Event;
 TCHAR EventFile[MAX_PATH];

 BOOL bExistSoundData = FALSE;
 BOOL bExistEventSoundData = FALSE;
 Seek(m_dwHeadSize,FILE_BEGIN);

 DWORD dwTagIndex = 0;

 tagHeader taghead;
 DWORD dwRead = 0;
 while ((dwRead=Read(&taghead,sizeof(taghead)))>0)
 {
  int tagLen = taghead.GetLength();
  TagType type = (TagType)taghead.GetType();

  if (tagLen==0x3F)
  {
   tagLen = taghead.GetLengthEx();
  }
  else
  {
   Seek(sizeof(unsigned short)-dwRead,FILE_CURRENT);
  }

  if (type==SoundStreamBlock)
  {
   if (!bExistSoundData)
   {
    if (!mp3File.Open(pMp3File,FILE_WRITE_DATA))
    {
     return FALSE;
    }
   }
   bExistSoundData = TRUE;
   unsigned char*pBuf = (unsigned char*)malloc(tagLen);
   Read(pBuf,tagLen);
   mp3File.Write(pBuf+4,tagLen-4);//SampleCount and SeekSamples size = 4
   free(pBuf);
  }
  else if (type == DefineSound)
  {
   if (!bExistEventSoundData)
   {
    StringCchCopy(EventFile,MAX_PATH,pMp3File);
    //PathRemoveFileSpec(EventFile);
    //StringCchCat(EventFile,MAX_PATH,L"//event.mp3");
    LPTSTR lpFile =  PathFindExtension(EventFile);
    StringCchCopy(lpFile,sizeof(L"_event.mp3"),L"_event.mp3");
    if (!mp3Event.Open(EventFile,FILE_WRITE_DATA))
    {
     return FALSE;
    }
   }
   bExistEventSoundData = TRUE;

   unsigned char*pBuf = (unsigned char*)malloc(tagLen);
   Read(pBuf,tagLen);
   mp3Event.Write(pBuf+4,tagLen-4);//SampleCount and SeekSamples size = 4
   free(pBuf);
  }
  else
  {
   if (type == ShowFrame)
   {
    dwTagIndex++;
    int percent = (int)dwTagIndex*100/m_nFrameCount;
    if (m_hwnd)
    {
     ::SendMessage(m_hwnd,WM_PROGRESS_CONVERT,NULL,(LPARAM)percent);
    }
   }
   if (tagLen>0)
   {
    unsigned char*pBuf = (unsigned char*)malloc(tagLen);
    Read(pBuf,tagLen);
    free(pBuf);
   }
  }
  
 }
 if (bExistEventSoundData&&!bExistSoundData)
 {
  mp3Event.Close();
  _wrename(EventFile,pMp3File);
 }
 return bExistSoundData||bExistEventSoundData;
}
BOOL CSwf::CheckCompress()
{
 SeekToBegin();
 byte  c;
 Read(&c,sizeof(c));
 return c == 'F' ? FALSE : TRUE;
}

int CSwf::DeCompressSwf(const TCHAR *pDest,const TCHAR *pSrc)
{

 File a;
 if(!a.Open(pSrc,FILE_ALL_ACCESS)) return -1;

 File b;
 if(!b.Open(pDest,FILE_ALL_ACCESS)) return -1;

 DWORD dwSize = a.GetLength();
 DWORD dwReal = 0;
 unsigned char* pData = (unsigned char*)malloc(dwSize);
 dwReal=a.Read(pData,dwSize);
 if (pData[0]=='F')
 {
  return 0;
 }
 pData[0]='F';

 b.Write(pData,SWFHEADSIZE);
 uLong uncomprLen = dwSize*10;
 unsigned char* uncompr = (unsigned char*)malloc(uncomprLen);
 int err = uncompress(uncompr, &uncomprLen, (const Bytef*)pData+SWFHEADSIZE, dwReal-SWFHEADSIZE);
 b.Write(uncompr,uncomprLen);
 free(pData);
 free(uncompr);
 return err;
}

 

// ConvertSwfToMp3Dlg.h : 头文件
//

#pragma once
#include "afxcmn.h"
#include "afxwin.h"


// CConvertSwfToMp3Dlg 对话框
class CConvertSwfToMp3Dlg : public CDialog
{
// 构造
public:
 CConvertSwfToMp3Dlg(CWnd* pParent = NULL); // 标准构造函数

// 对话框数据
 enum { IDD = IDD_CONVERTSWFTOMP3_DIALOG };

 protected:
 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持


// 实现
protected:
 HICON m_hIcon;

 // 生成的消息映射函数
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 DECLARE_MESSAGE_MAP()
public:
 CString m_szSwfFile;
public:
 CString m_szMp3File;
public:
 afx_msg void OnBnClickedButtonOpen();
public:
 afx_msg void OnBnClickedButtonSave();
public:
 afx_msg void OnBnClickedButtonStart();
 afx_msg LRESULT OnProgressConvert(WPARAM wparm, LPARAM lparm);
public:
 CProgressCtrl m_Progress;
 BOOL m_bConverting;
public:
 CStatic m_text;
};

 

// ConvertSwfToMp3Dlg.cpp : 实现文件
//

#include "stdafx.h"
#include "ConvertSwfToMp3.h"
#include "ConvertSwfToMp3Dlg.h"
#include "Swf.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
 CAboutDlg();

// 对话框数据
 enum { IDD = IDD_ABOUTBOX };

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CConvertSwfToMp3Dlg 对话框

 


CConvertSwfToMp3Dlg::CConvertSwfToMp3Dlg(CWnd* pParent /*=NULL*/)
 : CDialog(CConvertSwfToMp3Dlg::IDD, pParent)
 , m_szSwfFile(_T(""))
 , m_szMp3File(_T(""))
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 m_bConverting = FALSE;
}

void CConvertSwfToMp3Dlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
 DDX_Text(pDX, IDC_EDIT1, m_szSwfFile);
 DDX_Text(pDX, IDC_EDIT2, m_szMp3File);
 DDX_Control(pDX, IDC_PROGRESS_Convert, m_Progress);
 DDX_Control(pDX, IDC_STATIC_PRO, m_text);
}

BEGIN_MESSAGE_MAP(CConvertSwfToMp3Dlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 //}}AFX_MSG_MAP
 ON_BN_CLICKED(IDC_BUTTON_OPEN, &CConvertSwfToMp3Dlg::OnBnClickedButtonOpen)
 ON_BN_CLICKED(IDC_BUTTON_SAVE, &CConvertSwfToMp3Dlg::OnBnClickedButtonSave)
 ON_BN_CLICKED(IDC_BUTTON_START, &CConvertSwfToMp3Dlg::OnBnClickedButtonStart)
 ON_MESSAGE(WM_PROGRESS_CONVERT,&CConvertSwfToMp3Dlg::OnProgressConvert)
END_MESSAGE_MAP()


// CConvertSwfToMp3Dlg 消息处理程序

BOOL CConvertSwfToMp3Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // 将“关于...”菜单项添加到系统菜单中。

 // IDM_ABOUTBOX 必须在系统命令范围内。
 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
 //  执行此操作
 SetIcon(m_hIcon, TRUE);   // 设置大图标
 SetIcon(m_hIcon, FALSE);  // 设置小图标

 // TODO: 在此添加额外的初始化代码
 m_Progress.SetRange(0,100);
 return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CConvertSwfToMp3Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CConvertSwfToMp3Dlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this); // 用于绘制的设备上下文

  SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

  // 使图标在工作矩形中居中
  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  // 绘制图标
  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CConvertSwfToMp3Dlg::OnQueryDragIcon()
{
 return static_cast<HCURSOR>(m_hIcon);
}


void CConvertSwfToMp3Dlg::OnBnClickedButtonOpen()
{
 // TODO: 在此添加控件通知处理程序代码
 CFileDialog openFileDlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER,L"Flash Files (*.swf)|*.swf||");
 if (IDOK == openFileDlg.DoModal())
 {
  m_szSwfFile = openFileDlg.GetOFN().lpstrFile;
  
  TCHAR musicFile[MAX_PATH];
  GetModuleFileName(NULL,musicFile,MAX_PATH);
  PathRemoveFileSpec(musicFile);
  StringCchCat(musicFile,MAX_PATH,L"//FlashToMp3//");
  if (!PathFileExists(musicFile))
  {
   CreateDirectory(musicFile,NULL);
  }
  StringCchCat(musicFile,MAX_PATH,PathFindFileName(m_szSwfFile));
  PathRenameExtension(musicFile,L".mp3");
  m_szMp3File = musicFile;

  m_Progress.SetPos(0);
  CString text;
  text.Format(L"%d",0);
  text+=L"%";
  m_text.SetWindowText(text);
  UpdateData(FALSE);
 }
}

void CConvertSwfToMp3Dlg::OnBnClickedButtonSave()
{
 // TODO: 在此添加控件通知处理程序代码
 CFileDialog openFileDlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER,L"Flash Files (*.mp3)|*.mp3||");
 if (IDOK == openFileDlg.DoModal())
 {
  TCHAR tmp[MAX_PATH];
  StringCchCopy(tmp,MAX_PATH,openFileDlg.GetOFN().lpstrFile);
  PathRenameExtension(tmp,L".mp3");
  m_szMp3File = tmp;
  UpdateData(FALSE);
 }
}
UINT __cdecl ConverThead( LPVOID pParam )
{

 CConvertSwfToMp3Dlg *pDlg = (CConvertSwfToMp3Dlg*)pParam;
 pDlg->m_bConverting = TRUE;
 if (pDlg->m_szSwfFile==_T(""))
 {
  AfxMessageBox(L"Please select a flash first!");
  pDlg->m_bConverting = FALSE;
  return -1;
 }

 CSwf swf;
 swf.ReadSwf(pDlg->m_szSwfFile);
 swf.SetMessageHwnd(pDlg->m_hWnd);

 TCHAR path[MAX_PATH];
 StringCchCopy(path,MAX_PATH,pDlg->m_szMp3File);
 PathRemoveFileSpec(path);
 
 if(!swf.ParseSoundData2Mp3(pDlg->m_szMp3File))
  AfxMessageBox(L"No sound data exits!");
 else
 {
  ShellExecute(NULL, L"explore", path, NULL, NULL, SW_SHOWNORMAL);
 }

 pDlg->m_bConverting = FALSE;
 
 return 0;
}

void CConvertSwfToMp3Dlg::OnBnClickedButtonStart()
{
 // TODO: 在此添加控件通知处理程序代码
 if (m_bConverting)
 {
  return;
 }


 if (m_szMp3File==_T(""))
 {
  TCHAR musicFile[MAX_PATH];
  GetModuleFileName(NULL,musicFile,MAX_PATH);
  PathRemoveFileSpec(musicFile);
  StringCchCat(musicFile,MAX_PATH,L"//FlashToMp3//");
  if (!PathFileExists(musicFile))
  {
   CreateDirectory(musicFile,NULL);
  }
  StringCchCat(musicFile,MAX_PATH,PathFindFileName(m_szSwfFile));
  PathRenameExtension(musicFile,L".mp3");
  m_szMp3File = musicFile;

  UpdateData(FALSE);
 }

 AfxBeginThread(ConverThead,(LPVOID)this);
}
LRESULT CConvertSwfToMp3Dlg::OnProgressConvert(WPARAM wparm, LPARAM lparm)
{
 m_Progress.SetPos((int)lparm);
 CString text;
 text.Format(L"%d",(int)lparm);
 text+=L"%";
 m_text.SetWindowText(text);
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值