Python使用Gstreamer shmsrc多进程时appsink回调失败问题
问题根因
- 核心问题确实是GLib主循环未正确运行:GStreamer的
new-sample信号属于GLib信号系统,必须依赖运行在对应线程上下文的GLib主循环才能完成事件分发。没有主循环的情况下信号不会触发,手动调用pull_sample()会陷入阻塞等待事件推送,直到管线中断才会返回。 - 之前添加主循环后崩溃大概率是因为把主循环放在主线程直接运行,阻塞了后续代码执行,或是线程初始化顺序错误。
修复方案
第一步:调整主循环与管线初始化顺序
必须在管线信号绑定前启动独立线程运行GLib主循环,完整修正后的进程3代码如下:
import gi from threading import Thread gi.require_version('Gst', '1.0') gi.require_version("GstApp", "1.0") from gi.repository import Gst, GLib, GstApp # 优先初始化GStreamer Gst.init(None) # 启动独立线程运行GLib主循环,daemon参数保证主进程退出时自动结束循环线程 main_loop = GLib.MainLoop() main_loop_thread = Thread(target=main_loop.run, daemon=True) main_loop_thread.start() # 管线配置新增queue缓存、drop丢帧配置,避免阻塞 pipeline_String = "shmsrc socket-path=/tmp/tmpsock do-timestamp=true ! video/x-raw, format=(string)I420, width=(int)1280, height=(int)720, framerate=(fraction)30/1 ! \ videoconvert ! \ videorate ! video/x-raw,format=(string)RGB, framerate=(fraction)30/1 ! \ queue ! \ appsink name=sink drop=true" pipeline = Gst.parse_launch(pipeline_String) appsink = pipeline.get_by_name("sink") appsink.set_property("emit-signals", True) appsink.connect("new-sample", __on_new_sample) # 最后启动管线 pipeline.set_state(Gst.State.PLAYING) def __on_new_sample(app_sink): print("called") sample = app_sink.pull_sample() print("sample pull success") # 必须返回OK,否则GStreamer会判定处理失败,停止推送后续信号 return Gst.FlowReturn.OK
第二步:其他验证点
- 如果是在类中实现的逻辑,注意
self.pipeline的引用正确性,避免变量名指向错误导致的管线状态异常。 - 如果回调处理耗时较长,可以将采样数据的处理逻辑放到独立线程执行,避免阻塞主循环导致信号分发延迟。
内容的提问来源于stack exchange,提问作者aris-t
相关产品推荐
相关产品推荐

