Gtk video playback in menu window

I created a video player in Gtk3 using Gstreamer in Python3. It works, except when I add GtkMenuBar (place 2). Then it will either show a black screen or crash with an error. The exception refers to XInitThreads , which I call (place 1) (I took this from the pitivi project), but this does not seem to be the difference.

Question: How do I make this work?

Other things I would like to know:

  • Why does manilaba break this?
  • This will clearly break through to anything other than X, is there some kind of pre-engineered component of the theses of this logic and cross-platform that I lack?

System:

  • python3
  • GTK3
  • Ubuntu 16.04

An exception:

 [xcb] Unknown request in queue while dequeuing [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. python3: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed. 

Code (in small form to demonstrate the concept):

 import gi gi.require_version('Gtk', '3.0') gi.require_version('Gst', '1.0') gi.require_version('GstVideo', '1.0') from gi.repository import Gtk, xlib from gi.repository import Gst, Gdk, GdkX11, GstVideo Gst.init(None) Gst.init_check(None) # Place 1 from ctypes import cdll x11 = cdll.LoadLibrary('libX11.so') x11.XInitThreads() # [xcb] Unknown request in queue while dequeuing # [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called # [xcb] Aborting, sorry about that. # python3: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed. # (foo.py:31933): Gdk-WARNING **: foo.py: Fatal IO error 11 (Resource temporarily unavailable) on X server :1. class PipelineManager(object): def __init__(self, window, pipeline): self.window = window if isinstance(pipeline, str): pipeline = Gst.parse_launch(pipeline) self.pipeline = pipeline bus = pipeline.get_bus() bus.set_sync_handler(self.bus_callback) pipeline.set_state(Gst.State.PLAYING) def bus_callback(self, bus, message): if message.type is Gst.MessageType.ELEMENT: if GstVideo.is_video_overlay_prepare_window_handle_message(message): Gdk.threads_enter() Gdk.Display.get_default().sync() win = self.window.get_property('window') if isinstance(win, GdkX11.X11Window): message.src.set_window_handle(win.get_xid()) else: print('Nope') Gdk.threads_leave() return Gst.BusSyncReply.PASS pipeline = Gst.parse_launch('videotestsrc ! xvimagesink sync=false') window = Gtk.ApplicationWindow() header_bar = Gtk.HeaderBar() header_bar.set_show_close_button(True) # window.set_titlebar(header_bar) # Place 2 drawing_area = Gtk.DrawingArea() drawing_area.connect('realize', lambda widget: PipelineManager(widget, pipeline)) window.add(drawing_area) window.show_all() def on_destroy(win): try: Gtk.main_quit() except KeyboardInterrupt: pass window.connect('destroy', on_destroy) Gtk.main() 
+5
source share
1 answer

While searching for documentation on a particular issue, I came across a link to the gtksink widget. This seems to be the right way to put the video in the gtk window, but unfortunately none of its manuals use it.

Using the gtksink widget eliminates all problems and greatly reduces code complexity.

Revised Code:

 from pprint import pprint import gi gi.require_version('Gtk', '3.0') gi.require_version('Gst', '1.0') gi.require_version('GstVideo', '1.0') from gi.repository import Gtk, Gst Gst.init(None) Gst.init_check(None) class GstWidget(Gtk.Box): def __init__(self, pipeline): super().__init__() self.connect('realize', self._on_realize) self._bin = Gst.parse_bin_from_description('videotestsrc', True) def _on_realize(self, widget): pipeline = Gst.Pipeline() factory = pipeline.get_factory() gtksink = factory.make('gtksink') pipeline.add(gtksink) pipeline.add(self._bin) self._bin.link(gtksink) self.pack_start(gtksink.props.widget, True, True, 0) gtksink.props.widget.show() pipeline.set_state(Gst.State.PLAYING) window = Gtk.ApplicationWindow() header_bar = Gtk.HeaderBar() header_bar.set_show_close_button(True) window.set_titlebar(header_bar) # Place 2 widget = GstWidget('videotestsrc') widget.set_size_request(200, 200) window.add(widget) window.show_all() def on_destroy(win): try: Gtk.main_quit() except KeyboardInterrupt: pass window.connect('destroy', on_destroy) Gtk.main() 
+2
source

Source: https://habr.com/ru/post/1258312/


All Articles