Skip to content Skip to sidebar Skip to footer

Get The Window Handle In Pygi

In my program I use PyGObject/PyGI and GStreamer to show a video in my GUI. The video is shown in a Gtk.DrawingArea and therefore I need to get it's window-handle in the realize-si

Solution 1:

I finally got it. To address the "window handle"-issue I use the workaround/hack by Marwin Schmitt (see here):

def_on_video_realize(self, widget):
    # The window handle must be retrieved first in GUI-thread and before# playing pipeline.
    video_window = self._drawing_area.get_property('window')
    if sys.platform == "win32":
        ifnot video_window.ensure_native():
            print("Error - video playback requires a native window")
        ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
        ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object]
        drawingarea_gpointer = ctypes.pythonapi.PyCapsule_GetPointer(video_window.__gpointer__, None)
        gdkdll = ctypes.CDLL ("libgdk-3-0.dll")
        self._video_window_handle = gdkdll.gdk_win32_window_get_handle(drawingarea_gpointer)
    else:
        self._video_window_handle = video_window.get_xid()

But there was also the problem, that the "sync-message"-handler was never called. I found out that not all video sinks support embedded video, see here. For example the d3dvideosink does support embedded video, but I was running Windows in a virtual machine and even though 3D hardware acceleration was activated it probably didn't work. Running the same code on a non-virtualized Windows leads to a callback to the "sync-message"-handler where the previously fetched window-handle can be set:

def_on_player_sync_message(self, bus, message):
    if message.get_structure() isNone:
        returnifnot GstVideo.is_video_overlay_prepare_window_handle_message(message):
        return
    imagesink = message.src
    imagesink.set_property("force-aspect-ratio", True)
    imagesink.set_window_handle(self._video_window_handle)

Playback on Windows works fine now.

Solution 2:

Have you tried:

defOnSyncMessage(self, bus, msg):
    if msg.get_structure() isNone:
        returnTrue
    message_name = msg.get_structure().get_name()
    if message_name == 'prepare-window-handle':
        imagesink = msg.src
        imagesink.set_property('force-aspect-ratio', True)
        imagesink.set_window_handle(self.DrawingArea.GetHandle())
    returnTrue

Post a Comment for "Get The Window Handle In Pygi"