GStreamer Python重启失败

1 投票
1 回答
696 浏览
提问于 2025-04-18 15:52

我遇到了一个错误,下面的代码第一次运行时没问题,但在我结束这个进程后再试一次时,new_sample 从来没有被调用,也没有收到任何数据,尽管我成功创建了管道并启动了主循环。

为了让它再次运行,我必须重启我的电脑。我觉得这可能和清理 gstreamer 管道有关,但我已经尝试了很多方法,还是找不到 gstreamer 进程在 ps aux 中的踪影。另外,我还要提到,如果我用 gst-launch-1.0 运行相同的管道,它每次都能正常工作。我认为这个问题是特定于 Python 实现的。

def new_sample(appsink):
    sample = appsink.emit('pull-sample')
    print "pull sample"
    buffer = sample.get_buffer()
    print "got buffer"
    data = buffer.extract_dup(0, buffer.get_size())
    save_image(data)
    return False

'''
 gst-launch-1.0 -v tcpclientsrc host=YOUR-PI-IP-ADDRESS port=5000  ! gdpdepay  ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink sync=false
'''
def start_consume(ip=DEFAULT_IP_ADDRESS, port=DEFAULT_PORT):
    global pipeline

    GObject.threads_init()
    Gst.init(None)

    pipeline = Gst.Pipeline()

    tcpsrc = Gst.ElementFactory.make('tcpclientsrc','tcpsrc')
    tcpsrc.set_property("host", ip)
    tcpsrc.set_property("port", port)

    gdepay = Gst.ElementFactory.make('gdpdepay', 'gdepay')

    rdepay = Gst.ElementFactory.make('rtph264depay', 'rdepay')

    avdec = Gst.ElementFactory.make('avdec_h264', 'avdec')

    vidconvert = Gst.ElementFactory.make('videoconvert', 'vidconvert')

    asink = Gst.ElementFactory.make('appsink', 'asink')
    asink.set_property('sync', False)
    asink.set_property('emit-signals', True)
    asink.set_property('drop', True)
    asink.connect('new-sample', new_sample)
    asink.connect('pull-sample', pull_sample)
    asink.connect('pull-preroll', pull_preroll)

    pipeline.add(tcpsrc)
    pipeline.add(gdepay)
    pipeline.add(rdepay)
    pipeline.add(avdec)
    pipeline.add(vidconvert)
    pipeline.add(asink)

    tcpsrc.link(gdepay)
    gdepay.link(rdepay)
    rdepay.link(avdec)
    avdec.link(vidconvert)
    vidconvert.link(asink)
    pipeline.set_state(Gst.State.PLAYING)
    return pipeline

if __name__ == "__main__":
    try:
        loop = GObject.MainLoop()
        pipeline = start_consume()
        loop.run()
    except KeyboardInterrupt:
        print "Closing pipeline"
        pipeline.set_state(Gst.State.NULL)
        loop.quit() 

1 个回答

1

我发现错误出在关闭gstreamer管道上。用控制键加反斜杠(control + \)来关闭是有效的,而用控制键加c(control + c)就不行。

撰写回答