type TAVIStreamInfoA = record fccType, fccHandler, dwFlags, // Contains AVITF_* flags dwCaps: DWORD; wPriority, wLanguage: WORD; dwScale, dwRate, // dwRate / dwScale == samples/second dwStart, dwLength, // In units above... dwInitialFrames, dwSuggestedBufferSize, dwQuality, dwSampleSize: DWORD; rcFrame: TRect; dwEditCount, dwFormatChangeCount: DWORD; szName: array[0..63] of AnsiChar; end; type AVI_COMPRESS_OPTIONS=Record // 'avi 文件压缩选项avi_compress_options 结构 下面的opts fccType : integer; fccHandler : integer; dwKeyFrameEvery : integer; dwQuality : integer; dwBytesPerSecond : integer ; dwFlags : integer ; lpFormat : integer ; cbFormat : integer ; lpParms : integer ; cbParms : integer ; dwInterleaveEvery : integer ; end; TAVIStreamInfo = TAVIStreamInfoA; PAVIStreamInfo = ^TAVIStreamInfo; // PAVIStreamInfow=^TaviStreamInfo; TWavFormat=Twaveformat; TAVISaveCallback = function(nPercent: integer): LONGint; stdcall; function AVIFileOpen(var ppfile: pointer; szFile: PChar; uMode: UINT; lpHandler: pointer): HResult; stdcall; procedure AVIFileInit; stdcall; procedure AVIFileExit; stdcall; function AVIFileCreateStream(pfile: pointer; var ppavi: pointer; var psi: TAVIStreamInfo): HResult; stdcall; function AVIStreamSetFormat(pavi: pointer; lPos: LONGint; lpFormat: pointer; cbFormat: LONGint): HResult; stdcall; function AVIStreamWrite(pavi: pointer; lStart, lSamples: LONGint; lpBuffer: pointer; cbBuffer: LONGint; dwFlags: DWORD; var plSampWritten: LONGint; var plBytesWritten: LONGint): HResult; stdcall; function AVIStreamRelease(pavi: pointer): ULONG; stdcall; function AVIFileRelease(pfile: pointer): ULONG; stdcall; function CreateEditableStream(var ppsEditable: pointer; psSource: pointer): HResult; stdcall; procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; var ImageSize: longInt; PixelFormat: TPixelFormat); procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader; PixelFormat: TPixelFormat); function AlignBit(Bits, BitsPerPixel, Alignment: Cardinal): Cardinal; function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE; var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean; // {自定义 下} Function AVISaveOptions(hwnd : integer; uiFlags : integer; nStreams : integer;var ppavi : pointer;var ppOptions : pointer) : HResult;stdcall; Function AVISaveOptionsFree(nStreams : Integer;var ppOptions :pointer):integer;stdcall; Function AVIMakeCompressedStream(var ppsCompressed :pointer;psSource : pointer;var lpOptions: AVI_COMPRESS_OPTIONS;pclsidHandler : Integer) : Integer;stdcall; const streamtypeVIDEO = $73646976; // DWORD( 'v', 'i', 'd', 's' ) streamtypeAUDC = $63647561; // mmioFOURCC('a', 'u', 'd', 'c') //可能有问题 AVIIF_KEYFRAME = $10; ICMF_CHOOSE_KEYFRAME = $1; ICMF_CHOOSE_DATARATE = $2; // {自定义 下} //鼠标样式 //TMouseStyle=(HidMouse,CirMouse,ThrMouse,NorMouse); // {自定义 上} type TAvi = class(TObject) private // {自定义 下} pOpts,psCompressed:pointer; Opts:AVI_COMPRESS_OPTIONS; //压缩格式 // pStreamW,pWaveFormat:pointer; // {自定义 上} pFile, pStream, BitmapBits: pointer; //pStream ==ps pStreamW:pointer; StreamInfo: TAVIStreamInfo; // StreamInfoW:TAVIStreamInfo; // WaveFormat:TWavFormat; //wavformat BitmapInfo: PBitmapInfoHeader; BitmapInfoSize: Integer; BitmapSize, Dummy: longInt; apxf: TPixelFormat; //选择多少位的图片 i: Integer; public constructor Create(as_avifile: string; bmp: TBitmap; fPxf: TPixelFormat = pf8bit; AviRate: integer = 1); destructor Destroy; override; procedure Add(bmp: TBitmap); procedure CreateWav(channels{ 1(单声)或者2(立体声) }, resolution{ 8或者16,代表8位或16位声音 }: word; rate{ 声音频率,如11025,22050, 44100}: Integer; fn{ 对应的文件名称 }: string); //创建WAV文件 function AddWave(var src:string):boolean; end;
//-------------------------------------------------------------------
//在指定文件夹下生产 wav文件 procedure Tavi.CreateWav(channels{ 1(单声)或者2(立体声) }, resolution{ 8或者16,代表8位或16位声音 }: word; rate{ 声音频率,如11025,22050, 44100}: Integer; fn{ 对应的文件名称 }: string); //创建WAV文件 var wf : file of TWavHeader; wh : TWavHeader; begin wh.rId := $46464952; wh.rLen := 36; wh.wId := $45564157; wh.fId := $20746d66; wh.fLen := 16; wh.wFormatTag := 1; wh.nChannels := channels; wh.nSamplesPerSec := rate; wh.nAvgBytesPerSec := channels*rate*(resolution div 8); wh.nBlockAlign := channels*(resolution div 8); wh.wBitsPerSample := resolution; wh.dId := $61746164; wh.wSampleLength := 0; system.assignfile(wf,fn); {打开对应文件 } rewrite(wf); {移动指针到文件头} write(wf,wh); {写进文件头 } closefile(wf); {关闭文件 } end; constructor TAvi.Create(as_avifile: string; bmp: TBitmap; fPxf: TPixelFormat = pf8bit; AviRate: integer = 1); begin inherited Create; apxf := fPxf; i := 0; AVIFileInit; if (AVIFileOpen(pFile, PChar(as_avifile), OF_WRITE or OF_CREATE or OF_SHARE_EXCLUSIVE, nil) <> 0) then raise Exception.Create('创建avi文件失败'); InternalGetDIBSizes(bmp.Handle, BitmapInfoSize, BitmapSize, fPxf); FillChar(StreamInfo, sizeof(StreamInfo), 0); StreamInfo.fccType := streamtypeVIDEO; StreamInfo.fccHandler := 0; StreamInfo.dwFlags := 0; StreamInfo.dwSuggestedBufferSize := BitmapSize*3; //自定义*3 StreamInfo.rcFrame.Right := bmp.Width-256; StreamInfo.rcFrame.Bottom := bmp.Height-32; StreamInfo.dwScale := 1; StreamInfo.dwRate := AviRate; if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> 0) then raise Exception.Create('创建avi流失败'); {自定义 下} popts:=@opts; if (aviSaveOptions(form1.Handle,ICMF_CHOOSE_KEYFRAME or ICMF_CHOOSE_DATARATE,1,pstream,popts) <>1) then begin AVISaveOptionsFree(0,popts); raise Exception.Create('压缩格式设置错误'); end; if(AVIMakeCompressedStream(psCompressed,pstream,Opts,0) <>0) then //生成有压缩格式的流 raise Exception.Create('请选择正确的压缩格式'); {自定义 上} BitmapInfo := nil; BitmapBits := nil; // Get DIB header and pixel buffers GetMem(BitmapInfo, BitmapInfoSize); GetMem(BitmapBits, BitmapSize); InternalGetDIB(bmp.Handle, 0, BitmapInfo^, BitmapBits^, apxf); //原 if (AVIStreamSetFormat(pStream, 0, BitmapInfo, BitmapInfoSize) <> 0) then if (AVIStreamSetFormat(psCompressed, 0, BitmapInfo, BitmapInfoSize) <> 0) then raise Exception.Create('设置avi流格式失败'); showmessage('设置压缩格式成功'); end; destructor TAvi.Destroy; begin if (BitmapInfo <> nil) then FreeMem(BitmapInfo); if (BitmapBits <> nil) then FreeMem(BitmapBits); if (pStream <>nil) then AVIStreamRelease(pStream); if(psCompressed <>nil) then AVIStreamRelease(psCompressed); if (pstreamw <>nil) then AVIStreamRelease(pstreamw); AVIFileRelease(pFile); AVIFileExit; inherited Destroy; end; procedure TAvi.Add(bmp: TBitmap); begin try InternalGetDIB(bmp.Handle, 0, BitmapInfo^, BitmapBits^, apxf); //原 if AVIStreamWrite(pStream, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME, Dummy, Dummy) <> 0 then if AVIStreamWrite(psCompressed, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME,Dummy, Dummy) <> 0 then raise Exception.Create('添加帧到avi文件失败'); Inc(i); except Destroy; end; end;
