以前想在程序中嵌入FLASH,flash文件不能以资源的方式嵌入到文件中,也就是flash要以单独的文件一起发布,有点不爽,也有方法通过管道技术实现内存流的方式播放,但随着flash的升级,这种方法也不行了。搜索google,一些商业性的控件实现了以流的方式来播放,要钱的,下载DEMO,反汇编跟踪,功力有限,半途而废,再搜,哈哈找到TFlashPlayerControl源码,贴出其中关键的代码
procedure TFlashPlayerControl.LoadMovieFromStream(Layer:Integer;Src: TStream);
var
unCompress: TStream;
Mem, Mem2: TMemoryStream;
SRCSize: longint;
PersistStream: IPersistStreamInit;
SAdapt: TStreamAdapter;
ISize: int64;
B: byte;
ASign: array [0..2] of char;
isCompress: boolean;
ZStream: TDeCompressionStream;
rc:TRect;
hdcScreen,hdcMem:HDC;
begin
rc := ClientRect;
hdcScreen := CreateDC('DISPLAY', nil, nil, nil);
hdcMem:=CreateCompatibleDC(hdcScreen);
{$IFDEF DEMO_VERSION}
DrawText(hdcMem, PChar('DEMO VERSION'), -1, rc, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
{$ENDIF}
Src.Read(ASign, 3);
isCompress := ASign = 'CWS';
if isCompress then
begin
unCompress := TMemoryStream.Create;
ASign := 'FWS';
unCompress.Write(ASign, 3);
unCompress.CopyFrom(Src, 1);
SRC.Read(SRCSize, 4);
unCompress.Write(SRCSize, 4);
ZStream := TDeCompressionStream.Create(Src);
try
unCompress.CopyFrom(ZStream, SRCSize - 8);
finally
ZStream.free;
end;
unCompress.Position := 0;
end else
begin
Src.Position := Src.Position - 3;
SRCSize := Src.Size - Src.Position;
unCompress := Src;
end;
EmbedMovie := false;
FOleObject.QueryInterface(IPersistStreamInit, PersistStream);
PersistStream.GetSizeMax(ISize);
Mem := TMemoryStream.Create;
Mem.SetSize(ISize);
SAdapt := TStreamAdapter.Create(Mem);
PersistStream.Save(SAdapt, true);
SAdapt.Free;
Mem.Position := 1;
Mem2 := TMemoryStream.Create;
B := $66;
Mem2.Write(B, 1);
Mem2.CopyFrom(Mem, 3);
Mem2.Write(SRCSize, 4);
Mem2.CopyFrom(unCompress, SRCSize);
Mem2.CopyFrom(Mem, Mem.Size - Mem.Position);
Mem2.Position := 0;
SAdapt := TStreamAdapter.Create(Mem2);
PersistStream.Load(SAdapt);
SAdapt.Free;
Mem2.Free;
Mem.Free;
PersistStream := nil;
if isCompress then unCompress.Free;
end;
看到 {$IFDEF DEMO_VERSION} 了吗?以后TFlashPlayerControl发布新版本就可以很轻松的破解了,哈哈
------------------
added 2008.5.21
今天看 Delphi SWF SDK 时候看到他的控件 TShockwaveFlashEx,而且是源码是公开的,里面就有
汗一个。
看来在内存中播放flash早就公开了,国内研究这个不多。付上源码
procedure TShockwaveFlashEx.LoadMovieFromStream(Src: TStream);
var
unCompress: TStream;
Mem, Mem2: TMemoryStream;
SRCSize: longint;
PersistStream: IPersistStreamInit;
SAdapt: TStreamAdapter;
ISize: int64;
B: byte ;
ASign: array [ 0 .. 2 ] of char ;
isCompress: boolean;
ZStream: TDeCompressionStream;
begin
// prepare src movie
Src.Read(ASign, 3 );
isCompress : = ASign = ' CWS ' ;
if isCompress then
begin
unCompress : = TMemoryStream.Create;
ASign : = ' FWS ' ;
unCompress.Write(ASign, 3 );
unCompress.CopyFrom(Src, 1 ); // version
SRC.Read(SRCSize, 4 );
unCompress.Write(SRCSize, 4 );
ZStream : = TDeCompressionStream.Create(Src);
try
unCompress.CopyFrom(ZStream, SRCSize - 8 );
finally
ZStream.free;
end;
unCompress.Position : = 0 ;
end else
begin
Src.Position : = Src.Position - 3 ;
SRCSize : = Src.Size - Src.Position;
unCompress : = Src;
end;
// store "template"
EmbedMovie : = false ;
FOleObject.QueryInterface(IPersistStreamInit, PersistStream);
PersistStream.GetSizeMax(ISize);
Mem : = TMemoryStream.Create;
Mem.SetSize(ISize);
SAdapt : = TStreamAdapter.Create(Mem);
PersistStream.Save(SAdapt, true );
SAdapt.Free;
// insetr movie to "template"
Mem.Position : = 1 ;
Mem2 : = TMemoryStream.Create;
B : = $ 66 ; // magic flag: "f" - embed swf; "g" - without swf;
Mem2.Write(B, 1 );
Mem2.CopyFrom(Mem, 3 );
Mem2.Write(SRCSize, 4 );
Mem2.CopyFrom(unCompress, SRCSize);
Mem2.CopyFrom(Mem, Mem.Size - Mem.Position);
// load activeX data
Mem2.Position : = 0 ;
SAdapt : = TStreamAdapter.Create(Mem2);
PersistStream.Load(SAdapt);
SAdapt.Free;
// free all
Mem2.Free;
Mem.Free;
PersistStream : = nil;
if isCompress then unCompress.Free;
end;