以內存流的方式播放FLASH

 

 

     以前想在程序中嵌入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;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章