Gstreamer流水线RTSP流断线重连超时设置与GST_MESSAGE_EOS处理问题
GStreamer RTSP流超时及自动重连问题解答
超时参数定位与配置
你找不到timeout参数是因为该参数不属于uridecodebin本身,uridecodebin是容器类元件,处理RTSP流时会内部自动实例化rtspsrc元件负责拉流,20秒无响应触发EOS就是rtspsrc的默认配置。
你可以通过uridecodebin的element-added信号,在内部元件创建完成时捕获rtspsrc并修改参数,示例代码如下(Python为例,C/C++逻辑一致):
import gi gi.require_version('Gst', '1.0') from gi.repository import Gst Gst.init(None) # uridecodebin的element-added信号回调 def on_element_added(uridecodebin, new_element): # 判断新创建的元件是否为rtspsrc if Gst.ElementFactory.get_list_type(new_element.get_factory()) == Gst.ElementFactoryType.SRC and "rtspsrc" in new_element.get_name(): # 修改超时时间为60秒,可按需调整,单位为秒 new_element.set_property("timeout", 60) # 开启丢包重传,进一步降低断流触发概率 new_element.set_property("do-retransmission", True) # 绑定信号到你的uridecodebin实例 uridecodebin = Gst.ElementFactory.make("uridecodebin", "src") uridecodebin.connect("element-added", on_element_added)
EOS消息触发时重建uridecodebin失效的解决方案
失效的核心原因是:当总线收到GST_MESSAGE_EOS时,EOS事件已经走完了整条流水线的所有元件,流水线已经进入终止流的状态,残留的流锁、未释放的缓冲区会导致动态替换元件失效。可以通过以下两种方案解决:
方案1:提前拦截EOS事件(优先推荐)
不要等EOS传到总线,直接在uridecodebin的输出pad上挂载事件探测,拦截EOS事件并阻止它向下游传递,此时流水线仍处于正常运行状态,可直接执行重建逻辑:
def uridecodebin_pad_added(uridecodebin, src_pad, pipeline): # 给输出pad加下行事件探测 src_pad.add_probe(Gst.PadProbeType.EVENT_DOWNSTREAM, eos_probe_callback, pipeline) def eos_probe_callback(pad, probe_info, pipeline): event = probe_info.get_event() if event.type == Gst.EventType.EOS: # 拦截EOS事件,不向下游传递 # 此处执行你的uridecodebin重建逻辑即可,此时流水线状态正常,替换可生效 return Gst.PadProbeReturn.DROP return Gst.PadProbeReturn.OK # 绑定pad-added信号 uridecodebin.connect("pad-added", uridecodebin_pad_added, pipeline)
方案2:总线收到EOS后按流程重建
如果已经在总线回调里收到了EOS,需要按以下顺序操作才能生效:
- 将整条流水线的状态切换为
GST_STATE_READY,等待状态切换完成,清理所有流资源 - 移除旧的uridecodebin实例,销毁相关资源
- 创建新的uridecodebin实例,绑定必要的信号、设置参数,添加到流水线中
- 链接uridecodebin与下游元件
- 将流水线重新切换为
GST_STATE_PLAYING
内容的提问来源于stack exchange,提问作者harry_tums
相关产品推荐
相关产品推荐

