You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:54:05