Search code examples
pythonwinapitkinterffmpegwin32gui

Embedding ffplay window into tkinter frame by using SetParent win32gui function


i'm using to embed the ffplay window into my tkinter frame.

that's my code:

file = "path/to/the/file.mp4"
command = subprocess.Popen(["ffplay","-i","%s"%file],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True,)
pid = gw.getWindowsWithTitle('%s'%file) #getting the hwnd of the ffplay window
hwnd = re.findall(r'\d+',str(pid))
x = int(videoWidget.winfo_x()) #video widget is the target tkinter frame
y =int(videoWidget.winfo_y())
width =  int(videoWidget.winfo_width())
height =  int(videoWidget.winfo_height())
win32gui.MoveWindow(int(hwnd[-1]), int(x), int(y),int(width) , int(height), 1) # trying to move the ffplay window to the videowidget geometry 
win32gui.SetParent(int(hwnd[-1]),int(stream_id)) #trying to set the parent of the ffplay window to the videowidget, that should show the ffplay window in the tkinter frame

the code run without any error, but the both ffplay window and tkinter window stop responding without any error

if any one can help me in this i'll be thankful


Solution

  • Root cause of stopping responding: stdout=PIPE and/or stderr=PIPE. It blocks the output of ffmpeg and cause a deadlock.

    You could create a new console for the output of the ffmpeg.

    My test sample:

    import subprocess
    from subprocess import Popen, CREATE_NEW_CONSOLE
    import pygetwindow as gw
    import win32gui
    import regex as re
    import time
    file = "path/to/the/file.mp4"
    proc = subprocess.Popen(["ffplay","-i","%s"%file], creationflags = CREATE_NEW_CONSOLE)
    
    time.sleep(2) #make sure the window has been started and available to find.
    pid = gw.getWindowsWithTitle('%s'%file) #getting the hwnd of the ffplay window
    hwnd = re.findall(r'\d+',str(pid))
    print(hwnd)
    x = 0 #video widget is the target tkinter frame
    y = 0
    width =  800
    height =  500
    win32gui.MoveWindow(int(hwnd[-1]), int(x), int(y),int(width) , int(height), 1) # trying to move the ffplay window to the videowidget geometry 
    

    In addition, you should make sure you have started the window before calling getWindowsWithTitle.