Page 1 of 2

Playing a Flash movie from memory (no temporary files)

Posted: Sun Jul 16, 2006 3:46 am
by Esteban1
This is a little trick I recently discovered. It can be adapted to load a movie from resources.

Code: Select all

; 
; Embedded flash player example (ActiveX) 
; 
; By AlphaSND 
; 
; Translated to PB4 by Flype
; Playing from included data by Esteban1
;
; Flash ActiveX interface definition 
; 

Interface IShockwaveFlash Extends IDispatch 
  get_ReadyState(a) 
  get_TotalFrames(a) 
  get_Playing(a) 
  put_Playing(a) 
  get_Quality(a) 
  put_Quality(a) 
  get_ScaleMode(a) 
  put_ScaleMode(a) 
  get_AlignMode(a) 
  put_AlignMode(a) 
  get_BackgroundColor(a) 
  put_BackgroundColor(a) 
  get_Loop(a) 
  put_Loop(a) 
  get_Movie(a) 
  put_Movie(a) 
  get_FrameNum(a) 
  put_FrameNum(a) 
  SetZoomRect(a,b,c,d) 
  Zoom(a) 
  Pan(a,b,c) 
  Play() 
  Stop() 
  Back() 
  Forward() 
  Rewind() 
  StopPlay() 
  GotoFrame(a) 
  CurrentFrame(a) 
  IsPlaying(a) 
  PercentLoaded(a) 
  FrameLoaded(a,b) 
  FlashVersion(a) 
  get_WMode(a) 
  put_WMode(a) 
  get_SAlign(a) 
  put_SAlign(a) 
  get_Menu(a) 
  put_Menu(a) 
  get_Base(a) 
  put_Base(a) 
  get_scale(a) 
  put_scale(a) 
  get_DeviceFont(a) 
  put_DeviceFont(a) 
  get_EmbedMovie(a) 
  put_EmbedMovie(a) 
  get_BGColor(a) 
  put_BGColor(a) 
  get_Quality2(a) 
  put_Quality2(a) 
  LoadMovie(a,b.p-bstr) 
  TGotoFrame(a,b) 
  TGotoLabel(a,b) 
  TCurrentFrame(a,b) 
  TCurrentLabel(a,b) 
  TPlay(a) 
  TStopPlay(a) 
  SetVariable(a,b.p-bstr) 
  GetVariable(a,b.p-bstr) 
  TSetProperty(a,b,c) 
  TGetProperty(a,b,c) 
  TCallFrame(a,b) 
  TCallLabel(a,b) 
  TSetPropertyNum(a,b,c) 
  TGetPropertyNum(a,b,c) 
  get_SWRemote(a) 
  put_SWRemote(a) 
  get_Stacking(a) 
  put_Stacking(a) 
EndInterface 

Prototype AtlAxWinInit() 
Prototype AtlAxCreateControl(a.p-bstr,b.l,c.l,d.l) 
Prototype AtlAxGetControl(a.l,b.l) 

Procedure.l FlashLoadFromData(SwfStart.l,SwfEnd.l,*FlashObject.IShockwaveFlash)
  FlashBuffer=AllocateMemory(SwfEnd-SwfStart+8) ; let's make room
  If FlashBuffer
    PokeL(FlashBuffer,$55665566) ;now write the header
    PokeL(FlashBuffer+4,SwfEnd-SwfStart) ; and the file size
    CopyMemory(SwfStart,FlashBuffer+8,SwfEnd-SwfStart) ; then copy the whole file.
    If CreateStreamOnHGlobal_(FlashBuffer,#True,@FlashStream.IStream)=0 ;Create a stream.
      *FlashObject\QueryInterface(?IID_IPersistStreamInit,@FlashPSI.IPersistStreamInit) ; Ask for IPersistStreamInit interface     
      If FlashPSI 
        If FlashPSI\load(FlashStream)=0 ;load the stream we created
          ReturnValue=1
        EndIf
        FlashPSI\Release(); self explained
      EndIf  
      FlashStream\Release() ; idem
    EndIf
    FreeMemory(FlashBuffer) ;idem
  EndIf
  ProcedureReturn ReturnValue
EndProcedure

If OpenLibrary(0,"atl.dll") 
  AtlAxWinInit.AtlAxWinInit             = GetFunction(0, "AtlAxWinInit") 
  AtlAxCreateControl.AtlAxCreateControl = GetFunction(0, "AtlAxCreateControl") 
  AtlAxGetControl.AtlAxGetControl       = GetFunction(0, "AtlAxGetControl") 
Else 
  MessageRequester("Error", "OpenLibrary() failed.") 
  End 
EndIf 

;Movie$ = "c:\clock.swf" 
;Movie$ = "c:\\WINDOWS\\Help\\Tours\\mmTour\\segment1.swf" 

CoInitialize_(0) 

If OpenWindow(0, 100, 100, 300, 315, "") 
  
  CreateGadgetList(WindowID(0)) 
  ContainerGadget(0, 0, 0, 300, 275) ; This will be our container window, where the ActiveX will be rendered 
  CloseGadgetList() 
  
  ButtonGadget(1, 10, 285, 70, 25, "Play", #PB_Button_Toggle) 
  ;ButtonGadget(2, 90, 285, 70, 25, "Play") 
  
  If AtlAxWinInit() 
    
    AtlAxCreateControl("ShockwaveFlash.ShockwaveFlash", GadgetID(0), 0, @Container.IUnknown) ; It always create the IE control even if flash isn't found 
    
    If Container 
      
      AtlAxGetControl(GadgetID(0),@oFlash.IShockwaveFlash) 
      
      If oFlash 
        
        If oFlash\QueryInterface(?IID_ShockwaveFlash, @oFlash) = 0 ; Be sure it's a flash object in the IE container 
          
          ;oFlash\LoadMovie(0, Movie$)
          FlashLoadFromData(?FlashFileStart,?FlashFileEnd,oFlash) ; Let's get it from included data
          oFlash\get_ReadyState(@state)   ; 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete.  
          
          Select state 
            Case 4 , 3 
              ;oFlash\Play() 
              oFlash\FlashVersion(@Version) 
              Debug "Flash Version: " + Hex(Version) 
              ;oFlash\put_BackgroundColor($000000) 
              oFlash\get_BackgroundColor(@BackColor) 
              Debug "BackColor: " + Hex(BackColor) 
            Default 
              Debug state 
              MessageRequester("Error", "The movie can't be loaded ("+Movie$+")") 
          EndSelect 
          oFlash\put_Quality(0) 
          Repeat 
            Select WaitWindowEvent(50) 
              Case #PB_Event_CloseWindow 
                Break 
              Case #PB_Event_SizeWindow 
                ResizeGadget(0, #PB_Ignore, #PB_Ignore, WindowWidth(0), WindowHeight(0)-35) 
                ResizeGadget(1, #PB_Ignore, WindowHeight(0)-30, #PB_Ignore, #PB_Ignore) 
                ;ResizeGadget(2, #PB_Ignore, WindowHeight(0)-30, #PB_Ignore, #PB_Ignore) 
              Case #PB_Event_Gadget 
                Select EventGadget() 
                  Case 1 
                    Select GetGadgetState(1) 
                      Case 0 : oFlash\Stop() 
                      Case 1 : oFlash\Play() 
                    EndSelect 
                EndSelect 
            EndSelect 
            oFlash\CurrentFrame(@frame) 
            SetWindowTitle(0, "Frame " + Str(frame)) 
          ForEver 
          
          oFlash\Release() 
          
        EndIf 
        
        oFlash\Release() 
        
      EndIf 
      
    EndIf 
    
  EndIf 
  
  CloseWindow(0)   ; Don't forget this one, else the program will crash 
  
EndIf 

CoUninitialize_() 

End 

DataSection 
IID_ShockwaveFlash: Data.q $11CFAE6DD27CDB6C,$000054534544B896 
IID_IPersistStreamInit:
Data.l $7FD52380
Data.w $4E07,$101B
Data.b $AE,$2D,$08,$00,$2B,$2E,$C7,$13
FlashFileStart:
IncludeBinary "c:\\WINDOWS\\Help\\Tours\\mmTour\\segment1.swf"
FlashFileEnd:
EndDataSection
I don't know if it works for Flash versions other than 8.

Posted: Sun Jul 16, 2006 5:38 am
by Rings
i got an PoLink-Error while compiling:

Unresolved external Symbol:

'_SYS_ToBSTR'


anything missing ?

Posted: Sun Jul 16, 2006 6:33 am
by J. Baker
Works fine here with flash player 9. :wink:

Posted: Sun Jul 16, 2006 8:37 am
by Esteban1
Rings wrote:i got an PoLink-Error while compiling:

Unresolved external Symbol:

'_SYS_ToBSTR'


anything missing ?
Oops...
My only contribution in the previous code is the FlashLoadFromData procedure. Did you try the original source?
http://www.purebasic.fr/english/viewtopic.php?t=20428

Posted: Sun Jul 16, 2006 10:01 am
by Rings
the bug is in:

Prototype AtlAxCreateControl(a.p-bstr,b.l,c.l,d.l)

and the call

AtlAxCreateControl("ShockwaveFlash.ShockwaveFlash", GadgetID(0), 0, @Container.IUnknown)

its the p-bstr typecasting

Posted: Sun Jul 16, 2006 4:50 pm
by Rings
solved with an update from Beta11 to a Releaseversion.

Posted: Mon Jul 17, 2006 6:53 am
by bingo
:D also works in VISTA :!:

Posted: Thu Sep 28, 2006 9:43 pm
by J. Baker
EDIT Better code, a couple post down. ;)

Posted: Fri Mar 09, 2007 4:26 pm
by wilbert
I'm trying to display a flash movie with a transparent background.
I used AtlAxAttachControl and set wmode to transparent but the background keeps black all the time.

Does someone know what I'm doing wrong ?

Code: Select all

Interface IShockwaveFlash Extends IDispatch
  get_ReadyState(a)
  get_TotalFrames(a)
  get_Playing(a)
  put_Playing(a)
  get_Quality(a)
  put_Quality(a)
  get_ScaleMode(a)
  put_ScaleMode(a)
  get_AlignMode(a)
  put_AlignMode(a)
  get_BackgroundColor(a)
  put_BackgroundColor(a)
  get_Loop(a)
  put_Loop(a)
  get_Movie(a)
  put_Movie(a)
  get_FrameNum(a)
  put_FrameNum(a)
  SetZoomRect(a,b,c,d)
  Zoom(a)
  Pan(a,b,c)
  Play()
  Stop()
  Back()
  Forward()
  Rewind()
  StopPlay()
  GotoFrame(a)
  CurrentFrame(a)
  IsPlaying(a)
  PercentLoaded(a)
  FrameLoaded(a,b)
  FlashVersion(a)
  get_WMode(a)
  put_WMode(a.p-bstr)
  get_SAlign(a)
  put_SAlign(a)
  get_Menu(a)
  put_Menu(a)
  get_Base(a)
  put_Base(a)
  get_scale(a)
  put_scale(a)
  get_DeviceFont(a)
  put_DeviceFont(a)
  get_EmbedMovie(a)
  put_EmbedMovie(a)
  get_BGColor(a)
  put_BGColor(a)
  get_Quality2(a)
  put_Quality2(a)
  LoadMovie(a,b.p-bstr)
  TGotoFrame(a,b)
  TGotoLabel(a,b)
  TCurrentFrame(a,b)
  TCurrentLabel(a,b)
  TPlay(a)
  TStopPlay(a)
  SetVariable(a,b.p-bstr)
  GetVariable(a,b.p-bstr)
  TSetProperty(a,b,c)
  TGetProperty(a,b,c)
  TCallFrame(a,b)
  TCallLabel(a,b)
  TSetPropertyNum(a,b,c)
  TGetPropertyNum(a,b,c)
  get_SWRemote(a)
  put_SWRemote(a)
  get_Stacking(a)
  put_Stacking(a)
EndInterface

Prototype AtlAxAttachControl(a.l,b.l,c.l)

Procedure.l FlashLoadFromData(SwfStart.l,SwfEnd.l,*FlashObject.IShockwaveFlash)
  FlashBuffer=AllocateMemory(SwfEnd-SwfStart+8) ; let's make room
  If FlashBuffer
    PokeL(FlashBuffer,$55665566) ;now write the header
    PokeL(FlashBuffer+4,SwfEnd-SwfStart) ; and the file size
    CopyMemory(SwfStart,FlashBuffer+8,SwfEnd-SwfStart) ; then copy the whole file.
    If CreateStreamOnHGlobal_(FlashBuffer,#True,@FlashStream.IStream)=0 ;Create a stream.
      *FlashObject\QueryInterface(?IID_IPersistStreamInit,@FlashPSI.IPersistStreamInit) ; Ask for IPersistStreamInit interface     
      If FlashPSI
        If FlashPSI\load(FlashStream)=0 ;load the stream we created
          ReturnValue=1
        EndIf
        FlashPSI\Release(); self explained
      EndIf 
      FlashStream\Release() ; idem
    EndIf
    FreeMemory(FlashBuffer) ;idem
  EndIf
  ProcedureReturn ReturnValue
EndProcedure

If OpenLibrary(0,"atl.dll")
  AtlAxAttachControl.AtlAxAttachControl = GetFunction(0, "AtlAxAttachControl")
Else
  MessageRequester("Error", "OpenLibrary() failed.")
  End
EndIf

CoInitialize_(0)

If OpenWindow(0, 100, 100, 370, 370,"FlashPlayer",#PB_Window_ScreenCentered | #PB_Window_BorderLess)
 
  SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_TRANSPARENT)

  CoCreateInstance_(?IID_ShockwaveFlash, 0, $17, ?IID_IShockwaveFlash, @oFlash.IShockwaveFlash)

  If oFlash

    oFlash\put_WMode("Transparent")
    AtlAxAttachControl(oFlash, WindowID(0), 0)
      
    FlashLoadFromData(?FlashFileStart,?FlashFileEnd,oFlash)

    Repeat
      WaitWindowEvent()
    Until GetAsyncKeyState_(#VK_ESCAPE)
         
    oFlash\Release()
         
  EndIf
 
  CloseWindow(0)
 
EndIf

CoUninitialize_()

End

DataSection

IID_IShockwaveFlash:
Data.q $11CFAE6DD27CDB6C,$000054534544B896

IID_ShockwaveFlash:
Data.q $11CFAE6DD27CDB6E,$000054534544B896

IID_IPersistStreamInit:
Data.q $101B4E077FD52380,$13C72E2B00082DAE

FlashFileStart:
IncludeBinary "wood.swf"
FlashFileEnd:
EndDataSection

Posted: Sat Mar 10, 2007 7:36 am
by Esteban1
wilbert wrote:I'm trying to display a flash movie with a transparent background.
I used AtlAxAttachControl and set wmode to transparent but the background keeps black all the time.

Does someone know what I'm doing wrong ?
Hmmm...

I'm not sure but I think that's not possible using ATL.

You should use COMFramework to make your own container because the only way to get a real transparent background is to use the windowless mode.
Take a look at this.

Posted: Fri Feb 08, 2008 1:39 am
by J. Baker
Not the best but it has transparency and you are able to click through the transparency. It's also dragable. ;)

Code: Select all

Interface IShockwaveFlash Extends IDispatch
  get_ReadyState(a)
  get_TotalFrames(a)
  get_Playing(a)
  put_Playing(a)
  get_Quality(a)
  put_Quality(a)
  get_ScaleMode(a)
  put_ScaleMode(a)
  get_AlignMode(a)
  put_AlignMode(a)
  get_BackgroundColor(a)
  put_BackgroundColor(a)
  get_Loop(a)
  put_Loop(a)
  get_Movie(a)
  put_Movie(a)
  get_FrameNum(a)
  put_FrameNum(a)
  SetZoomRect(a,b,c,d)
  Zoom(a)
  Pan(a,b,c)
  Play()
  Stop()
  Back()
  Forward()
  Rewind()
  StopPlay()
  GotoFrame(a)
  CurrentFrame(a)
  IsPlaying(a)
  PercentLoaded(a)
  FrameLoaded(a,b)
  FlashVersion(a)
  get_WMode(a)
  put_WMode(a.p-bstr)
  get_SAlign(a)
  put_SAlign(a)
  get_Menu(a)
  put_Menu(a)
  get_Base(a)
  put_Base(a)
  get_scale(a)
  put_scale(a)
  get_DeviceFont(a)
  put_DeviceFont(a)
  get_EmbedMovie(a)
  put_EmbedMovie(a)
  get_BGColor(a)
  put_BGColor(a)
  get_Quality2(a)
  put_Quality2(a)
  LoadMovie(a,b.p-bstr)
  TGotoFrame(a,b)
  TGotoLabel(a,b)
  TCurrentFrame(a,b)
  TCurrentLabel(a,b)
  TPlay(a)
  TStopPlay(a)
  SetVariable(a,b.p-bstr)
  GetVariable(a,b.p-bstr)
  TSetProperty(a,b,c)
  TGetProperty(a,b,c)
  TCallFrame(a,b)
  TCallLabel(a,b)
  TSetPropertyNum(a,b,c)
  TGetPropertyNum(a,b,c)
  get_SWRemote(a)
  put_SWRemote(a)
  get_Stacking(a)
  put_Stacking(a)
EndInterface

Prototype AtlAxAttachControl(a.l,b.l,c.l)

Procedure.l FlashLoadFromData(SwfStart.l,SwfEnd.l,*FlashObject.IShockwaveFlash)
  FlashBuffer=AllocateMemory(SwfEnd-SwfStart+8) ; let's make room
  If FlashBuffer
    PokeL(FlashBuffer,$55665566) ;now write the header
    PokeL(FlashBuffer+4,SwfEnd-SwfStart) ; and the file size
    CopyMemory(SwfStart,FlashBuffer+8,SwfEnd-SwfStart) ; then copy the whole file.
    If CreateStreamOnHGlobal_(FlashBuffer,#True,@FlashStream.IStream)=0 ;Create a stream.
      *FlashObject\QueryInterface(?IID_IPersistStreamInit,@FlashPSI.IPersistStreamInit) ; Ask for IPersistStreamInit interface     
      If FlashPSI
        If FlashPSI\load(FlashStream)=0 ;load the stream we created
          ReturnValue=1
        EndIf
        FlashPSI\Release(); self explained
      EndIf
      FlashStream\Release() ; idem
    EndIf
    FreeMemory(FlashBuffer) ;idem
  EndIf
  ProcedureReturn ReturnValue
EndProcedure

If OpenLibrary(0,"atl.dll")
  AtlAxAttachControl.AtlAxAttachControl = GetFunction(0, "AtlAxAttachControl")
Else
  MessageRequester("Error", "OpenLibrary() failed.")
  End
EndIf

CoInitialize_(0)

If OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_BorderLess)
 
HideWindow(0, 1)

SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED) 

SetLayeredWindowAttributes_(WindowID(0),RGB(0,0,0),0,#LWA_COLORKEY)

CoCreateInstance_(?IID_ShockwaveFlash, 0, $17, ?IID_IShockwaveFlash, @oFlash.IShockwaveFlash)

  If oFlash

    oFlash\put_WMode("Transparent")
    oFlash\put_Quality(1)
    
    AtlAxAttachControl(oFlash, WindowID(0), 0)
     
    FlashLoadFromData(?FlashFileStart,?FlashFileEnd,oFlash)
    
    Delay(100) 
    HideWindow(0, 0)

    Repeat
      Event = WaitWindowEvent()
      
      If Event = #WM_LBUTTONDOWN
       SendMessage_(WindowID(0) ,#WM_NCLBUTTONDOWN, #HTCAPTION, 0)
      EndIf
      
    Until GetAsyncKeyState_(#VK_ESCAPE)
         
    oFlash\Release()
         
  EndIf
 
  CloseWindow(0)
 
EndIf

CoUninitialize_()

End

DataSection

IID_IShockwaveFlash:
Data.q $11CFAE6DD27CDB6C,$000054534544B896

IID_ShockwaveFlash:
Data.q $11CFAE6DD27CDB6E,$000054534544B896

IID_IPersistStreamInit:
Data.q $101B4E077FD52380,$13C72E2B00082DAE

FlashFileStart:
IncludeBinary "transparent.swf"
FlashFileEnd:
EndDataSection

Posted: Fri Feb 08, 2008 2:05 am
by SFSxOI
I get a 'The memory pointer passed to FreeMemory() is invalid' error at FreeMemory(FlashBuffer)

Posted: Fri Feb 08, 2008 2:33 am
by J. Baker
SFSxOI wrote:I get a 'The memory pointer passed to FreeMemory() is invalid' error at FreeMemory(FlashBuffer)
Yeah, it does that sometimes. I'm not sure why. Just try it until it works.

Posted: Sat Feb 09, 2008 6:26 pm
by bingo
in vista easier with SHCreateMemStream ... 8)

http://msdn2.microsoft.com/en-us/librar ... S.85).aspx

Posted: Sat Feb 09, 2008 7:12 pm
by J. Baker
I believe since fDeleteOnRelease is set to true, it automatically releases. So that line of code can be removed, I think?