我正在使用Python和GObject自省绑定开发基于GStreamer的程序。我正在尝试建立此管道:
videomixer name=mix ! autovideosink \ uridecodebin uri=v4l2:///dev/video0 ! mix.
使用gst-launch-1.0管道可以完美地工作,但是我的Python程序给出了错误:
(minimal.py:12168): GStreamer-CRITICAL **: gst_element_link_pads_full: assertion 'GST_IS_ELEMENT (src)' failed on_error(): (GError('Internal data flow error.',), 'gstbasesrc.c(2865): gst_base_src_loop (): /GstPipeline:pipeline0/GstURIDecodeBin:uridecodebin0/GstV4l2Src:source:\nstreaming task paused, reason not-linked (-1)')
#!/usr/bin/python3 import gi gi.require_version('Gst', '1.0') from gi.repository import GObject, Gst, Gtk, GdkX11, GstVideo GObject.threads_init() Gst.init(None) class Source: def __init__(self, uri, pipeline, mixer): self.uri = uri self.pipeline = pipeline self.mixer = mixer self.src = Gst.ElementFactory.make('uridecodebin', None) self.pipeline.add(self.src) self.src.set_property('uri', uri) self.src.connect('pad-added', self.on_pad_added, self.src, self.mixer) def on_pad_added(self, element, pad, src, dest): name = pad.query_caps(None).to_string() print('on_pad_added:', name) if name.startswith('video/'): src.link(dest) class Main: def __init__(self): self.window = Gtk.Window() self.window.connect('destroy', self.quit) self.window.set_default_size(1280, 720) self.drawingarea = Gtk.DrawingArea() self.window.add(self.drawingarea) self.pipeline = Gst.Pipeline() self.bus = self.pipeline.get_bus() self.bus.add_signal_watch() self.bus.connect('message::error', self.on_error) self.bus.enable_sync_message_emission() self.bus.connect('sync-message::element', self.on_sync_message) self.mixer = Gst.ElementFactory.make('videomixer', None) self.sink = Gst.ElementFactory.make('autovideosink', None) self.pipeline.add(self.mixer) self.pipeline.add(self.sink) self.mixer.link(self.sink) video = Source('v4l2:///dev/video0', self.pipeline, self.mixer) def run(self): self.window.show_all() # You need to get the XID after window.show_all(). You shouldn't get it # in the on_sync_message() handler because threading issues will cause # segfaults there. self.xid = self.drawingarea.get_property('window').get_xid() self.pipeline.set_state(Gst.State.PLAYING) Gtk.main() def quit(self, window): self.pipeline.set_state(Gst.State.NULL) Gtk.main_quit() def on_sync_message(self, bus, msg): if msg.get_structure().get_name() == 'prepare-window-handle': msg.src.set_window_handle(self.xid) def on_error(self, bus, msg): print('on_error():', msg.parse_error()) main = Main() main.run()
我发现了问题,我错误地链接了动态创建的垫:
src.link(dest)
本来应该:
pad.link(dest.get_compatible_pad(pad, None))