Skip to main content
 首页 » 编程设计

python之GStreamer错误 "assertion ' GST_IS_ELEMENT(链接元素时src )' failed"

2025年05月04日12davidwang456

我正在使用 Python 和 GObject 自省(introspection)绑定(bind)开发一个基于 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() 

请您参考如下方法:

我发现了问题,我错误地链接了动态创建的 pad:

src.link(dest) 

应该是:

pad.link(dest.get_compatible_pad(pad, None))