我正在研究在 RPi3 上运行的 Python 脚本,并使用 gstreamer 连接到我的 IP 摄像机的 RTSP 源,并将解码的 H264 帧提供给我的 Python 脚本。
这是用于从相机获取帧的 gstreamear 管道:
rtspsrc location=rtsp://ip:port/path ! rtph264depay ! h264parse ! decodebin ! videoconvert ! video/x-raw, format=BGR ! appsink name=sink
问题:由于相机的互联网连接速度较慢/不可靠,我时不时会丢帧,这会导致生成 EOS 信号。互联网连接带宽有时可能会导致流中断。
目标:在 EOS 信号上,我想重新启动管道,以便 gstreamer 可以继续为我的程序提供帧。
我尝试过的:我在总线上附加了一个回调函数,它通过使用监听消息
bus.connect("message", on_message)
在“on_message”函数中,我能够成功确定消息是否是 EOS 信号。如果我检测到 EOS 信号,我会尝试通过执行以下操作重新启动管道:
pipline.set_state(Gst.State.NULL)
pipline.set_state(Gst.State.PAUSED)
pipline.set_state(Gst.State.PLAYING)
不幸的是,这不起作用。一旦我的 scipt 尝试使用上面的代码片段重新启动管道,我就会在总线上出现以下错误。而且我知道相机在线,所以这不是问题。
('ERROR!!!:', 'source', '!:!', 'Could not read from resource.')
('Debug info:', 'gstrtspsrc.c(5583): gst_rtspsrc_send (): /GstPipeline:pipeline0/GstRTSPSrc:source:\nGot error response: 400 (Bad Request).')
('ERROR!!!:', 'source', '!:!', 'Could not write to resource.')
('Debug info:', 'gstrtspsrc.c(6933): gst_rtspsrc_close (): /GstPipeline:pipeline0/GstRTSPSrc:source:\nCould not send message. (Generic error)')
('ERROR!!!:', 'udpsrc2', '!:!', 'Internal data stream error.')
('Debug info:', 'gstbasesrc.c(2951): gst_base_src_loop (): /GstPipeline:pipeline0/GstRTSPSrc:source/GstUDPSrc:udpsrc2:\nstreaming stopped, reason not-linked (-1)')
如果问题出在 rtspsrc,我还尝试使用 filesrc 使用本地短视频,并使用 gstreamer 到达视频文件末尾时生成的 EOS 信号来测试我是否能够重新启动管道。这是我用来播放本地视频的示例管道:
filesrc location=file.mp4 ! qtdemux ! decodebin ! videoconvert ! video/x-raw, format=BGR ! appsink name=sink
如果成功,它应该再次开始播放视频,但没有运气......相反,我收到以下错误,这让我认为 filesrc 需要以某种方式重置。与 rtsp 示例相同,其中 rtspsrc 生成错误
('ERROR!!!:', 'qtdemux0', '!:!', 'Internal data stream error.')
('Debug info:', 'qtdemux.c(5847): gst_qtdemux_loop (): /GstPipeline:pipeline0/GstQTDemux:qtdemux0:\nstreaming stopped, reason not-linked (-1)')
任何人都可以阐明这个问题吗?谢谢!