Page 1 of 1

Play videos with overlay text or graphics

Posted: Mon Dec 02, 2024 1:47 pm
by Rings
Since I can't get any further with Purebasic's on-board tools (the video lib is very limited at the moment, in the past you could extract the individual images of a video)

I am looking for a solution to display different videos and provide them with text and symbols as overlay.
You could try to do this as a FLOATING WINDOW (i.e. video in a window, text in a window, etc.) but then the transparency of, for example, the text or an icon is missing.
If necessary, I could even live with that.

To make matters worse, my target should later be Linux,
a “Windows Only” version is of relatively little use to me.

I could think of the VLC story, but I can't get it to work with the examples I can find here.
Does anyone have anything useful for me or do I really have to switch to python where almost everything is available?

Re: Play videos with overlay text or graphics

Posted: Mon Dec 02, 2024 8:15 pm
by TI-994A
Rings wrote: Mon Dec 02, 2024 1:47 pm...a solution to display different videos and provide them with text and symbols as overlay.
Image

A simple transparent window-overlay solution for Windows, which could be adapted for macOS as well. Not sure about Linux, though. :wink:

Code: Select all

UsePNGImageDecoder()

Declare windowHandler()
Declare imageProc(hwnd, msg, wParam, lParam)

; for downloading a sample window overlay for the player (from DropBox)
overlay.s = GetTemporaryDirectory() + "frame.png"
If FileSize(overlay) < 1
  ReceiveHTTPFile("https://www.dropbox.com/scl/fi/s5x11roeegqgsw7u1sljq/playTube.png?" +
                  "rlkey=jo8trjfh0j6dlhf818g6errdx&st=s3sdvweb&dl=1", 
                  GetTemporaryDirectory() + "frame.png")
EndIf

If InitMovie()
  movieName.s = OpenFileRequester("Select movie:", "", "Movie files|*.avi;*.mpg|All Files|*.*", 0)
  If movieName    
    LoadMovie(0, movieName)  
    mWidth = MovieWidth(0)
    mHeight = MovieHeight(0)
    OpenWindow(1, 100, 150, MovieWidth(0), MovieHeight(0), "",
               #PB_Window_ScreenCentered | #PB_Window_BorderLess)
    PlayMovie(0, WindowID(1))           
    LoadImage(0, GetTemporaryDirectory() + "frame.png")
    ResizeImage(0, MovieWidth(0), MovieHeight(0))    
    OpenWindow(0, 0, 0, MovieWidth(0), MovieHeight(0), "",
               #PB_Window_BorderLess | #PB_Window_ScreenCentered)
    BindEvent(#PB_Event_MoveWindow, @windowHandler())   
    StickyWindow(0, #True)
    SetWindowColor(0, #White)
    layeredStyle = GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED
    SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, layeredStyle)
    SetLayeredWindowAttributes_(WindowID(0), #White, 0, #LWA_COLORKEY) 
    ImageGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(0))
    sysProc = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @imageProc())    
    While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
  EndIf    
EndIf

; for moving the window and simulating player controls (play, pause, close)
Procedure imageProc(hwnd, msg, wParam, lParam)
  Shared sysProc, mWidth, mHeight
  Select msg     
    Case #WM_LBUTTONDOWN            
      If WindowMouseX(0) < mWidth And WindowMouseX(0) > mWidth - 50 And WindowMouseY(0) < 50        
        End
      ElseIf WindowMouseX(0) > (mWidth / 2) - 100 And WindowMouseX(0) < (mWidth / 2) And WindowMouseY(0) > mHeight - 50
        ResumeMovie(0)
      ElseIf WindowMouseX(0) < (mWidth / 2) + 100 And WindowMouseX(0) > (mWidth / 2) And WindowMouseY(0) > mHeight - 50
        PauseMovie(0)
      Else              
        SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)      
      EndIf      
  EndSelect 
  ProcedureReturn CallWindowProc_(sysProc, hwnd, msg, wParam, lParam)
EndProcedure  

Procedure windowHandler()  
  If EventWindow() = 0    
    ResizeWindow(1, WindowX(0), WindowY(0), #PB_Ignore, #PB_Ignore)
  EndIf  
EndProcedure

Re: Play videos with overlay text or graphics

Posted: Tue Dec 03, 2024 10:26 am
by Rings
thank you TI-994A for the example.
Unfortunally it did not work.

if i use the movie.pb from the examples it shows my movie,
yours not. i only see the white background and noticed
the correct size of the window (stretched to movie size)

i also check if the movie can be loaded:
result=LoadMovie(0, movieName)
If result<>0
Of course your example is "Windows" only,
i do not know how to "transparent the windows"
under linux.

Re: Play videos with overlay text or graphics

Posted: Wed Dec 04, 2024 8:13 am
by ozzie
Thanks, TI-994A. That works great under Windows and could be very useful for my requirements.

Re: Play videos with overlay text or graphics

Posted: Wed Dec 04, 2024 11:46 am
by wombats
I couldn't get a movie to play on Windows or Linux for some reason, but here's an example of making a child window semi-transparent on Linux (Qt and GTK) and macOS:

Code: Select all

EnableExplicit

ImportC ""
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    CompilerIf Not Subsystem("qt")
      gtk_widget_is_composited(*widget.GtkWidget)
      gtk_window_set_opacity(*window.GtkWindow, opacity.d)
    CompilerEndIf
  CompilerEndIf
EndImport

Define txt.s, x, y
If CreateImage(0, 100, 100)
  If StartDrawing(ImageOutput(0))
    txt = "Image"
    x = (OutputWidth() - TextWidth(txt)) / 2
    y = (OutputHeight() - TextHeight(txt)) / 2
    DrawText(x, y, "Image")
    StopDrawing()
  EndIf
  
  OpenWindow(0, 100, 100, 640, 480, "", #PB_Window_SystemMenu | #PB_Window_TitleBar)
  SetWindowColor(0, RGB(0, 0, 200))
  
  x = (WindowWidth(0) - ImageWidth(0)) / 2
  y = (WindowHeight(0) - ImageHeight(0)) / 2
  ImageGadget(0, x, y, ImageWidth(0), ImageHeight(0), ImageID(0))
  
  OpenWindow(1, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_WindowCentered, WindowID(0))
  
  SetWindowColor(0, RGB(0, 0, 255))
  
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      CompilerIf Subsystem("qt")
        QtScript("window(1).windowOpacity = 0.5;")
      CompilerElse
        gtk_window_set_opacity(WindowID(1), 0.5)
      CompilerEndIf
    CompilerCase #PB_OS_MacOS
      Define alpha.CGFloat = 0.5
      CocoaMessage(0, WindowID(1), "setOpaque:", #NO)
      CocoaMessage(0, WindowID(1), "setAlphaValue:@", @alpha)
  CompilerEndSelect
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Re: Play videos with overlay text or graphics

Posted: Wed Dec 04, 2024 2:42 pm
by moulder61
@wombats

I've been wondering how to do something like that in Linux? I'm sure that snippet will come in handy in one of my little projects. :D

Thanks,

Moulder.

Edit: Possible typo?

SetWindowColor(0, RGB(0, 0, 255))

I "think" it should be SetWindowColor(1, RGB(0, 0, 255)).

Re: Play videos with overlay text or graphics

Posted: Wed Dec 04, 2024 5:01 pm
by RASHAD
For Windows

Code: Select all

If InitMovie() = 0
  MessageRequester("Error", "Can't initialize movie playback !", 0) 
  End
EndIf

Procedure moveCB()
  ResizeWindow(10,WindowX(0)+40,WindowY(0)+40,#PB_Ignore,#PB_Ignore)
EndProcedure

LoadFont(0,"Comic San MS",24)

MovieName$ = OpenFileRequester("Choose the movie to play", "", "Movie files|*.avi;*.mpg|All Files|*.*", 0)

If MovieName$
  If LoadMovie(0, MovieName$)
    mwidth = MovieWidth(0)
    mwidth = MovieHeight(0)    
  EndIf
EndIf 

If OpenWindow(10, 0, 0, mwidth ,mwidth, "Transparent Win",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
  OpenWindow(0, WindowX(10), WindowY(10),400,400, "Transparent Win",#PB_Window_BorderLess|#PB_Window_Invisible,WindowID(10))
  SetWindowColor(0, RGB(255,0,255))
  SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE,#WS_EX_LAYERED | #WS_EX_TOOLWINDOW | #WS_EX_TOPMOST)
  SetLayeredWindowAttributes_(WindowID(0),RGB(255,0,255),0,#LWA_COLORKEY)
  iImage.i = CreateImage(#PB_Any, 400,400, 24)
  
  If StartDrawing(ImageOutput(iImage)) 
    Box(20,20,360,360,RGB(255,0,255))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawingFont(FontID(0))
    DrawText(100,100,"TEST",$0000FF)
    StopDrawing()
    
    ImageGadget(1,0,0,400,400,ImageID(iImage))
    DisableGadget(1,1)
  EndIf
  
  ButtonGadget(2,10,10,50,30,"Exit")
  
  HideWindow(0,0)
  StickyWindow(0,1)  
  
  If IsMovie(0)
    ResizeWindow(10,WindowX(0)+40,WindowY(0)+40,#PB_Ignore,#PB_Ignore)
    PlayMovie(0, WindowID(10))
  EndIf
  BindEvent(#PB_Event_MoveWindow,@moveCB())
  
  Repeat
    
    iEventID = WaitWindowEvent(1)
    Select iEventID
        
      Case #WM_LBUTTONDOWN        
        SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 2
            Quit = 1
        EndSelect
        
    EndSelect
    
  Until Quit = 1
EndIf

End

Re: Play videos with overlay text or graphics

Posted: Wed Dec 04, 2024 8:09 pm
by wombats
moulder61 wrote: Wed Dec 04, 2024 2:42 pm @wombats

I've been wondering how to do something like that in Linux? I'm sure that snippet will come in handy in one of my little projects. :D

Thanks,

Moulder.

Edit: Possible typo?

SetWindowColor(0, RGB(0, 0, 255))

I "think" it should be SetWindowColor(1, RGB(0, 0, 255)).
No worries. I'm glad it's useful. I don't think the colour of the windows actually matters - I just put it in there to hopefully make the opacity more obvious & and I like the colour blue. :lol:

Re: Play videos with overlay text or graphics

Posted: Wed Dec 04, 2024 8:47 pm
by moulder61
@wombats

I was trying to create a logout program with a semi transparent background but couldn't work it out so I faked it! :P

I might not have noticed the typo in your code except that in the process of trying to make the window black and less transparent I saw that it wasn't working as I expected?

If I ever do anything interesting with it I'll let you know. :wink:

Moulder.

Re: Play videos with overlay text or graphics

Posted: Sat Dec 07, 2024 2:58 pm
by TI-994A
Rings wrote: Tue Dec 03, 2024 10:26 am thank you TI-994A for the example.
Unfortunally it did not work.
...
...
Of course your example is "Windows" only,
i do not know how to "transparent the windows"
under linux.
Thanks for the feedback, @Rings. Sorry it doesn't work on Linux. I can't even get the PlayMovie() function to work on any of my Linux installations - some vlclib issue. :lol:

Re: Play videos with overlay text or graphics

Posted: Sat Dec 07, 2024 2:59 pm
by TI-994A
ozzie wrote: Wed Dec 04, 2024 8:13 am Thanks, TI-994A. That works great under Windows and could be very useful for my requirements.
Thank you for saying so, @ozzie. I'm always happy to hear positive feedback. :D

Re: Play videos with overlay text or graphics

Posted: Mon Dec 09, 2024 9:04 am
by Rings
Thank you Rashad for a working windows example.
And also a big thanx to Wombats , it works perfect on my linux mint.
(had no chance to test it against a mac os version) .

i will do some more tests(integrate video and overlay both ) later.

Re: Play videos with overlay text or graphics

Posted: Thu Feb 06, 2025 4:10 pm
by Rings
just a quick note,
the showstopper for my next project is solved.

i can put now a transparent windows(with Text & Graphics)
over a playing video,
also play 3 videos at once with different solutions(and windows)

all tested under linux X64(mint), gtk and QT work.
thx wombats for the "tranparent windows tips"
and fred to switch the movie lib to vlc .

Re: Play videos with overlay text or graphics

Posted: Thu Feb 06, 2025 4:32 pm
by skywalk
Sorry, I could not get any of the snippets to work on Windows 11?
I verified my mp4 files can be viewed in my locally installed VLC player.