Mi aplicación crea imágenes a partir de fractales y me encanta la sensación de 'volar' alrededor de un fractal. Una vez guardé aproximadamente 2000 bitmaps en un archivo y creé un AVI a partir de él usando Premiere. Esa experiencia es bastante frustrante aunque logré crear una película. Eso fue espectacular. Por supuesto, quiero crear un video desde mi aplicación. En realidad, no me importa la ingeniosidad del códec, la compresión o lo que sea. Solo quiero tener un video que pueda reproducir en la mayoría de los sistemas.¿Cómo convertir bitmaps a video?
En el pasado lo he intentado pero nunca he tenido éxito. Me activó un question recientemente, pero lamentablemente no se pudo ejecutar FFMpeg.
actualización
decidí adaptar la pregunta un poco y poner una recompensa por ello. He visto varias soluciones, pero la más atractiva (porque es simple) me parece TAviWrite. Intenté TAviWriter pero no tuve éxito. En el procedimiento TAviWriter.Write; la llamada a la función alrededor de la línea 370
AVIERR := AVISaveV(s,
// pchar(FileName),
nil, // File handler
nil, // Callback
nStreams, // Number of streams
Streams,
CompOptions); // Compress options for VideoStream
no vuelve AVIERR_OK.
Actualización 2
La razón para el error anteriormente mencionado es una declaración falsa de AVISaveV, debe ser declarada como AVISaveVW como Tlama señaló. El código correcto para crear archivos filoes AVI a partir de archivos BMP se publica a continuación. El código original siguiente era downloaded from efg con una unidad de ejemplo.
Utilizando Delphi XE en Windows 7.
unit AviWriter;
/////////////////////////////////////////////////////////////////////////////
// //
// AviWriter -- a component to create rudimentary AVI files //
// by Elliott Shevin, with large pieces of code //
// stolen from Anders Melander //
// version 1.0. Please send comments, suggestions, and advice //
// to [email protected] //
/////////////////////////////////////////////////////////////////////////////
interface
uses
Windows,Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ole2;
////////////////////////////////////////////////////////////////////////////////
// //
// Video for Windows //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// Adapted from Thomas Schimming's VFW.PAS //
// (c) 1996 Thomas Schimming, [email protected] //
// (c) 1998,99 Anders Melander //
// //
////////////////////////////////////////////////////////////////////////////////
// //
// Ripped all COM/ActiveX stuff and added some AVI stream functions. //
// //
////////////////////////////////////////////////////////////////////////////////
// Unicode version created by Arnold and TLama (2012) //
////////////////////////////////////////////////////////////////////////////////
type
LONG = Longint;
PVOID = Pointer;
const
// TAVIFileInfo dwFlag values
AVIF_HASINDEX = $00000010;
AVIF_MUSTUSEINDEX = $00000020;
AVIF_ISINTERLEAVED = $00000100;
AVIF_WASCAPTUREFILE = $00010000;
AVIF_COPYRIGHTED = $00020000;
AVIF_KNOWN_FLAGS = $00030130;
AVIERR_UNSUPPORTED = $80044065; // MAKE_AVIERR(101)
AVIERR_BADFORMAT = $80044066; // MAKE_AVIERR(102)
AVIERR_MEMORY = $80044067; // MAKE_AVIERR(103)
AVIERR_INTERNAL = $80044068; // MAKE_AVIERR(104)
AVIERR_BADFLAGS = $80044069; // MAKE_AVIERR(105)
AVIERR_BADPARAM = $8004406A; // MAKE_AVIERR(106)
AVIERR_BADSIZE = $8004406B; // MAKE_AVIERR(107)
AVIERR_BADHANDLE = $8004406C; // MAKE_AVIERR(108)
AVIERR_FILEREAD = $8004406D; // MAKE_AVIERR(109)
AVIERR_FILEWRITE = $8004406E; // MAKE_AVIERR(110)
AVIERR_FILEOPEN = $8004406F; // MAKE_AVIERR(111)
AVIERR_COMPRESSOR = $80044070; // MAKE_AVIERR(112)
AVIERR_NOCOMPRESSOR = $80044071; // MAKE_AVIERR(113)
AVIERR_READONLY = $80044072; // MAKE_AVIERR(114)
AVIERR_NODATA = $80044073; // MAKE_AVIERR(115)
AVIERR_BUFFERTOOSMALL = $80044074; // MAKE_AVIERR(116)
AVIERR_CANTCOMPRESS = $80044075; // MAKE_AVIERR(117)
AVIERR_USERABORT = $800440C6; // MAKE_AVIERR(198)
AVIERR_ERROR = $800440C7; // MAKE_AVIERR(199)
// TAVIStreamInfo dwFlag values
AVISF_DISABLED = $00000001;
AVISF_VIDEO_PALCHANGES = $00010000;
AVISF_KNOWN_FLAGS = $00010001;
type
TAVIFileInfoW = record
dwMaxBytesPerSec,// max. transfer rate
dwFlags, // the ever-present flags
dwCaps,
dwStreams,
dwSuggestedBufferSize,
dwWidth,
dwHeight,
dwScale,
dwRate, // dwRate/dwScale == samples/second
dwLength,
dwEditCount: DWORD;
szFileType: array[0..63] of WideChar; // descriptive string for file type?
end;
PAVIFileInfoW = ^TAVIFileInfoW;
TAVIStreamInfoW = 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 WideChar;
end;
TAVIStreamInfo = TAVIStreamInfoW;
PAVIStreamInfo = ^TAVIStreamInfo;
PAVIStream = pointer;
PAVIFile = pointer;
TAVIStreamList = array[0..0] of PAVIStream;
PAVIStreamList = ^TAVIStreamList;
TAVISaveCallback = function (nPercent: integer): LONG; stdcall;
TAVICompressOptions = packed record
fccType : DWORD;
fccHandler : DWORD;
dwKeyFrameEvery : DWORD;
dwQuality : DWORD;
dwBytesPerSecond : DWORD;
dwFlags : DWORD;
lpFormat : pointer;
cbFormat : DWORD;
lpParms : pointer;
cbParms : DWORD;
dwInterleaveEvery : DWORD;
end;
PAVICompressOptions = ^TAVICompressOptions;
// Palette change data record
const
RIFF_PaletteChange: DWORD = 1668293411;
type
TAVIPalChange = packed record
bFirstEntry : byte;
bNumEntries : byte;
wFlags : WORD;
peNew : array[byte] of TPaletteEntry;
end;
PAVIPalChange = ^TAVIPalChange;
APAVISTREAM = array[0..1] of PAVISTREAM;
APAVICompressOptions = array[0..1] of PAVICompressOptions;
procedure AVIFileInit; stdcall;
procedure AVIFileExit; stdcall;
function AVIFileOpen(var ppfile: PAVIFile; szFile: PChar; uMode: UINT; lpHandler: pointer): HResult; stdcall;
function AVIFileCreateStream(pfile: PAVIFile; var ppavi: PAVISTREAM; var psi: TAVIStreamInfo): HResult; stdcall;
function AVIStreamSetFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; cbFormat: LONG): HResult; stdcall;
function AVIStreamReadFormat(pavi: PAVIStream; lPos: LONG; lpFormat: pointer; var cbFormat: LONG): HResult; stdcall;
function AVIStreamWrite(pavi: PAVIStream; lStart, lSamples: LONG; lpBuffer: pointer; cbBuffer: LONG; dwFlags: DWORD; var plSampWritten: LONG; var plBytesWritten: LONG): HResult; stdcall;
function AVIStreamRelease(pavi: PAVISTREAM): ULONG; stdcall;
function AVIFileRelease(pfile: PAVIFile): ULONG; stdcall;
function AVIFileGetStream(pfile: PAVIFile; var ppavi: PAVISTREAM; fccType: DWORD; lParam: LONG): HResult; stdcall;
function CreateEditableStream(var ppsEditable: PAVISTREAM; psSource: PAVISTREAM): HResult; stdcall;
function AVISaveV(szFile: PChar; pclsidHandler: PCLSID; lpfnCallback: TAVISaveCallback;
nStreams: integer; pavi: APAVISTREAM; lpOptions: APAVICompressOptions): HResult; stdcall;
const
AVIERR_OK = 0;
AVIIF_LIST = $01;
AVIIF_TWOCC = $02;
AVIIF_KEYFRAME = $10;
streamtypeVIDEO = $73646976; // DWORD('v', 'i', 'd', 's')
streamtypeAUDIO = $73647561; // DWORD('a', 'u', 'd', 's')
type
TPixelFormat = (pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom);
type
TAviWriter = class (TComponent)
private
TempFileName : string;
pFile : PAVIFile;
fHeight : integer;
fWidth : integer;
fStretch : boolean;
fFrameTime : integer;
fFileName : string;
fWavFileName : string;
VideoStream : PAVISTREAM;
AudioStream : PAVISTREAM;
procedure AddVideo;
procedure AddAudio;
procedure InternalGetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer;
var ImageSize: longInt; PixelFormat: TPixelFormat);
function InternalGetDIB(Bitmap: HBITMAP; Palette: HPALETTE;
var BitmapInfo; var Bits; PixelFormat: TPixelFormat): Boolean;
procedure InitializeBitmapInfoHeader(Bitmap: HBITMAP; var Info: TBitmapInfoHeader;
PixelFormat: TPixelFormat);
procedure SetWavFileName(value : string);
public
Bitmaps : TList;
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure Write;
published
property Height : integer read fHeight write fHeight;
property Width : integer read fWidth write fWidth;
property FrameTime: integer read fFrameTime write fFrameTime;
property Stretch : boolean read fStretch write fStretch;
property FileName : string read fFileName write fFileName;
property WavFileName : string read fWavFileName write SetWavFileName;
end;
procedure Register;
implementation
procedure AVIFileInit; stdcall; external 'avifil32.dll' name 'AVIFileInit';
procedure AVIFileExit; stdcall; external 'avifil32.dll' name 'AVIFileExit';
function AVIFileOpen; external 'avifil32.dll' name 'AVIFileOpenW';
function AVIFileCreateStream; external 'avifil32.dll' name 'AVIFileCreateStreamW';
function AVIStreamSetFormat; external 'avifil32.dll' name 'AVIStreamSetFormat';
function AVIStreamReadFormat; external 'avifil32.dll' name 'AVIStreamReadFormat';
function AVIStreamWrite; external 'avifil32.dll' name 'AVIStreamWrite';
function AVIStreamRelease; external 'avifil32.dll' name 'AVIStreamRelease';
function AVIFileRelease; external 'avifil32.dll' name 'AVIFileRelease';
function AVIFileGetStream; external 'avifil32.dll' name 'AVIFileGetStream';
function CreateEditableStream; external 'avifil32.dll' name 'CreateEditableStream';
function AVISaveV; external 'avifil32.dll' name 'AVISaveVW';
constructor TAviWriter.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
fHeight := screen.height div 10;
fWidth := screen.width div 10;
fFrameTime := 1000;
fStretch := true;
fFileName := '';
Bitmaps := TList.create;
AVIFileInit;
TempFileName := {tempdir +} 'temp.avi';
end;
destructor TAviWriter.Destroy;
begin
Bitmaps.free;
AviFileExit;
inherited;
end;
procedure TAviWriter.Write;
var
ExtBitmap : TBitmap;
nstreams : integer;
i : integer;
Streams : APAVISTREAM;
CompOptions : APAVICompressOptions;
AVIERR : integer;
refcount : integer;
begin
AudioStream := nil;
VideoStream := nil;
// If no bitmaps are on the list, raise an error.
if Bitmaps.count < 1
then raise Exception.Create('No bitmaps on the Bitmaps list');
// If anything on the Bitmaps TList is not a bitmap, raise
// an error.
for i := 0 to Bitmaps.count - 1 do
begin
ExtBitmap := Bitmaps[i];
if not(ExtBitmap is TBitmap)
then raise Exception.Create('Bitmaps[' + inttostr(i)
+ '] is not a TBitmap');
end; // for
try
AddVideo;
if WavFileName <> ''
then AddAudio;
// Create the output file.
if WavFileName <> ''
then nstreams := 2
else nstreams := 1;
Streams[0] := VideoStream;
Streams[1] := AudioStream;
CompOptions[0] := nil;
CompOptions[1] := nil;
AVIERR := AVISaveV(
pchar(FileName),
nil, // File handler
nil, // Callback
nStreams, // Number of streams
Streams,
CompOptions); // Compress options for VideoStream
if AVIERR <> AVIERR_OK then
raise Exception.Create('Unable to write output file');
finally
if assigned(VideoStream)
then AviStreamRelease(VideoStream);
if assigned(AudioStream)
then AviStreamRelease(AudioStream);
try
repeat
refcount := AviFileRelease(pFile);
until refcount <= 0;
except
// ignore exception
end; // try..except
DeleteFile(TempFileName);
end; // try..finally
end;
procedure TAviWriter.AddVideo;
var
Pstream: PAVISTREAM;
StreamInfo: TAVIStreamInfo;
BitmapInfo: PBitmapInfoHeader;
BitmapInfoSize: Integer;
BitmapSize: longInt;
BitmapBits: pointer;
Bitmap: TBitmap;
ExtBitmap: TBitmap;
Samples_Written: LONG;
Bytes_Written: LONG;
AVIERR: integer;
i: integer;
ok: Int64;
mode: uInt32;
fn: pChar;
err: string;
begin
// Open AVI file for write
pfile := nil;
mode := OF_CREATE or OF_WRITE or OF_SHARE_EXCLUSIVE;
fn := pchar (TempFileName);
ok := AVIFileOpen (pFile, fn, mode, nil);
if ok = AVIERR_BADFORMAT then err := 'The file could not be read, indicating a corrupt file or an unrecognized format.';
if ok = AVIERR_MEMORY then err := 'The file could not be opened because of insufficient memory.';
if ok = AVIERR_FILEREAD then err := 'A disk error occurred while reading the file.';
if ok = AVIERR_FILEOPEN then err := 'A disk error occurred while opening the file.';
if ok = REGDB_E_CLASSNOTREG then err := 'According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it.';
if err <> '' then raise Exception.Create (err);
// Allocate the bitmap to which the bitmaps on the Bitmaps Tlist
// will be copied.
Bitmap := TBitmap.create;
Bitmap.Height := self.Height;
Bitmap.Width := self.Width;
// Write the stream header.
try
FillChar (StreamInfo, sizeof (StreamInfo), 0);
// Set frame rate and scale
StreamInfo.dwRate := 1000;
StreamInfo.dwScale := fFrameTime;
StreamInfo.fccType := streamtypeVIDEO;
StreamInfo.fccHandler := 0;
StreamInfo.dwFlags := 0;
StreamInfo.dwSuggestedBufferSize := 0;
StreamInfo.rcFrame.Right := self.width;
StreamInfo.rcFrame.Bottom := self.height;
// Open AVI data stream
if (AVIFileCreateStream(pFile, pStream, StreamInfo) <> AVIERR_OK) then
raise Exception.Create('Failed to create AVI video stream');
try
// Write the bitmaps to the stream.
for i := 0 to Bitmaps.count - 1 do
begin
BitmapInfo := nil;
BitmapBits := nil;
try
// Copy the bitmap from the list to the AVI bitmap,
// stretching if desired. If the caller elects not to
// stretch, use the first pixel in the bitmap as a
// background color in case either the height or
// width of the source is smaller than the output.
// If Draw fails, do a StretchDraw.
ExtBitmap := Bitmaps[i];
if fStretch
then Bitmap.Canvas.StretchDraw
(Rect(0,0,self.width,self.height),ExtBitmap)
else try
with Bitmap.Canvas do begin
Brush.Color := ExtBitmap.Canvas.Pixels[0,0];
Brush.Style := bsSolid;
FillRect(Rect(0,0,Bitmap.Width,Bitmap.Height));
Draw(0,0,ExtBitmap);
end;
except
Bitmap.Canvas.StretchDraw
(Rect(0,0,self.width,self.height),ExtBitmap);
end;
// Determine size of DIB
InternalGetDIBSizes(Bitmap.Handle, BitmapInfoSize, BitmapSize, pf8bit);
if (BitmapInfoSize = 0) then
raise Exception.Create('Failed to retrieve bitmap info');
// Get DIB header and pixel buffers
GetMem(BitmapInfo, BitmapInfoSize);
GetMem(BitmapBits, BitmapSize);
InternalGetDIB
(Bitmap.Handle, 0, BitmapInfo^, BitmapBits^, pf8bit);
// On the first time through, set the stream format.
if i = 0 then
if (AVIStreamSetFormat(pStream, 0, BitmapInfo, BitmapInfoSize) <> AVIERR_OK) then
raise Exception.Create('Failed to set AVI stream format');
// Write frame to the video stream
AVIERR :=
AVIStreamWrite(pStream, i, 1, BitmapBits, BitmapSize, AVIIF_KEYFRAME,
Samples_Written, Bytes_Written);
if AVIERR <> AVIERR_OK then
raise Exception.Create
('Failed to add frame to AVI. Err='
+ inttohex(AVIERR,8));
finally
if (BitmapInfo <> nil) then
FreeMem(BitmapInfo);
if (BitmapBits <> nil) then
FreeMem(BitmapBits);
end;
end;
// Create the editable VideoStream from pStream.
if CreateEditableStream(VideoStream,pStream) <> AVIERR_OK then
raise Exception.Create
('Could not create Video Stream');
finally
AviStreamRelease(pStream);
end;
finally
Bitmap.free;
end;
end;
procedure TAviWriter.AddAudio;
var
InputFile : PAVIFILE;
InputStream : PAVIStream;
err: string;
ok: Int64;
begin
// Open the audio file.
ok := AVIFileOpen(InputFile, pchar(WavFileName),OF_READ, nil);
if ok = AVIERR_BADFORMAT then err := 'The file could not be read, indicating a corrupt file or an unrecognized format.';
if ok = AVIERR_MEMORY then err := 'The file could not be opened because of insufficient memory.';
if ok = AVIERR_FILEREAD then err := 'A disk error occurred while reading the file.';
if ok = AVIERR_FILEOPEN then err := 'A disk error occurred while opening the file.';
if ok = REGDB_E_CLASSNOTREG then err := 'According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it.';
if err <> '' then raise Exception.Create (err);
// Open the audio stream.
try
if (AVIFileGetStream(InputFile, InputStream, 0, 0) <> AVIERR_OK) then
raise Exception.Create('Unable to get audio stream');
try
// Create AudioStream as a copy of InputStream
if (CreateEditableStream(AudioStream,InputStream) <> AVIERR_OK) then
raise Exception.Create('Failed to create editable AVI audio stream');
finally
AviStreamRelease(InputStream);
end;
finally
AviFileRelease(InputFile);
end;
end;
// --------------
// InternalGetDIB
// --------------
// Converts a bitmap to a DIB of a specified PixelFormat.
//
// Note: The InternalGetDIBSizes function can be used to calculate the
// nescessary sizes of the BitmapInfo and Bits buffers.
//
// From graphics.pas, "optimized" for our use
function TAviWriter.InternalGetDIB
(
Bitmap: HBITMAP; // The handle of the source bitmap
Palette: HPALETTE; // The handle of the source palette
var BitmapInfo; // The buffer that will receive the DIB's TBitmapInfo structure.
// A buffer of sufficient size must have been allocated prior to
// calling this function
var Bits; // The buffer that will receive the DIB's pixel data
PixelFormat: TPixelFormat // The pixel format of the destination DIB
): Boolean; // True on success, False on failure
var
OldPal : HPALETTE;
DC : HDC;
begin
InitializeBitmapInfoHeader(Bitmap, TBitmapInfoHeader(BitmapInfo), PixelFormat);
OldPal := 0;
DC := CreateCompatibleDC(0);
try
if (Palette <> 0) then
begin
OldPal := SelectPalette(DC, Palette, False);
RealizePalette(DC);
end;
Result := (GetDIBits(DC, Bitmap, 0, abs(TBitmapInfoHeader(BitmapInfo).biHeight),
@Bits, TBitmapInfo(BitmapInfo), DIB_RGB_COLORS) <> 0);
finally
if (OldPal <> 0) then
SelectPalette(DC, OldPal, False);
DeleteDC(DC);
end;
end;
// -------------------
// InternalGetDIBSizes
// -------------------
// Calculates the buffer sizes nescessary for convertion of a bitmap to a DIB
// of a specified PixelFormat.
// See the GetDIBSizes API function for more info.
// From graphics.pas, "optimized" for our use
procedure TAviWriter.InternalGetDIBSizes
(
Bitmap: HBITMAP; // The handle of the source bitmap
var InfoHeaderSize: Integer; // The returned size of a buffer that will receive
// the DIB's TBitmapInfo structure
var ImageSize: longInt; // The returned size of a buffer that will receive the DIB's pixel data
PixelFormat: TPixelFormat // The pixel format of the destination DIB
);
var
Info: TBitmapInfoHeader;
begin
InitializeBitmapInfoHeader(Bitmap, Info, PixelFormat);
// Check for palette device format
if (Info.biBitCount > 8) then
begin
// Header but no palette
InfoHeaderSize := SizeOf(TBitmapInfoHeader);
if ((Info.biCompression and BI_BITFIELDS) <> 0) then
Inc(InfoHeaderSize, 12);
end else
// Header and palette
InfoHeaderSize := SizeOf(TBitmapInfoHeader) + SizeOf(TRGBQuad) * (1 shl Info.biBitCount);
ImageSize := Info.biSizeImage;
end;
// --------------------------
// InitializeBitmapInfoHeader
// --------------------------
// Fills a TBitmapInfoHeader with the values of a bitmap when converted to a
// DIB of a specified PixelFormat.
// From graphics.pas, "optimized" for our use
procedure TAviWriter.InitializeBitmapInfoHeader
(
Bitmap: HBITMAP; // The handle of the source bitmap
var Info: TBitmapInfoHeader; // The TBitmapInfoHeader buffer that will receive the values
PixelFormat: TPixelFormat // The pixel format of the destination DIB
);
var
DIB : TDIBSection;
Bytes : Integer;
function AlignBit(Bits, BitsPerPixel, Alignment: Cardinal): Cardinal;
begin
Dec(Alignment);
Result := ((Bits * BitsPerPixel) + Alignment) and not Alignment;
Result := Result SHR 3;
end;
begin
DIB.dsbmih.biSize := 0;
Bytes := GetObject(Bitmap, SizeOf(DIB), @DIB);
if (Bytes = 0) then
raise Exception.Create('Invalid bitmap');
// Error(sInvalidBitmap);
if (Bytes >= (sizeof(DIB.dsbm) + sizeof(DIB.dsbmih))) and
(DIB.dsbmih.biSize >= sizeof(DIB.dsbmih)) then
Info := DIB.dsbmih
else
begin
FillChar(Info, sizeof(Info), 0);
with Info, DIB.dsbm do
begin
biSize := SizeOf(Info);
biWidth := bmWidth;
biHeight := bmHeight;
end;
end;
case PixelFormat of
pf1bit: Info.biBitCount := 1;
pf4bit: Info.biBitCount := 4;
pf8bit: Info.biBitCount := 8;
pf24bit: Info.biBitCount := 24;
else
// Error(sInvalidPixelFormat);
raise Exception.Create('Invalid pixel format');
// Info.biBitCount := DIB.dsbm.bmBitsPixel * DIB.dsbm.bmPlanes;
end;
Info.biPlanes := 1;
Info.biCompression := BI_RGB; // Always return data in RGB format
Info.biSizeImage := AlignBit(Info.biWidth, Info.biBitCount, 32) * Cardinal(abs(Info.biHeight));
end;
procedure TAviWriter.SetWavFileName(value : string);
begin
if lowercase(fWavFileName) <> lowercase(value)
then if lowercase(ExtractFileExt(value)) <> '.wav'
then raise Exception.Create('WavFileName must name a file '
+ 'with the .wav extension')
else fWavFileName := value;
end;
procedure Register;
begin
RegisterComponents('Samples', [TAviWriter]);
end;
end.
Son de AviFil32, agregué los encabezados al ejemplo de código. Como el código es bastante antiguo, supongo que no se refieren a Unicode. ¿Debo reemplazar el 'procedimiento AVIFileInit; stdcall; nombre 'avifil32.dll' externo 'AVIFileInit'' por 'procedimiento AVIFileInit; stdcall; nombre externo 'avifil32.dll' 'AVIFileInitW''? – Arnold
¡Hizo lo que aconsejó y AddVideo funciona !. Ahora estoy tratando de entender lo que sucede en AVIsaveV. ¿El mismo tipo de consejo se aplica a esa función? – Arnold
No, solo aquellos que terminan con el carácter 'A', pero debe verificarlo de acuerdo con la referencia de MSDN. Por ejemplo, si miras el ['AVIFileOpen'] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd756800%28v=vs.85%29.aspx) entonces puedes ver en al final de la página, la sección 'Unicode y ANSI names' y esta sección está disponible solo para las funciones que tienen versiones ANSI y Unicode. – TLama