0

我正在使用RPi3上運行的Python腳本,並使用gstreamer連接到IP Camera的RTSP源,並將解碼後的H264幀提供給我的Python腳本。在EOS上重啓Python中的GStreamer管道

下面是用於從相機獲取幀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)') 

任何人都可以解釋這個問題嗎?謝謝!

+0

你是用gst_parse_launch還是類似的方式創建你的管道? – thiagoss

回答

0

當你

pipline.set_state(Gst.State.NULL)

這並不意味着這條管道已立即聯絡這種狀態。可以肯定你可以調用pipeline.get_state()。另外我建議處理set_state()的返回值。最後要重新演奏,沒有必要先去PAUSED(除非你想在PUASED和PLAYING之間做點什麼)。

+0

所以我在一些調試代碼中添加了在某些點上在命令行上打印管道狀態的操作。 EOS發佈時,管道仍處於「播放」狀態。然後我可以將它置於'READY'狀態,然後進入'NULL'狀態。爲了使管道恢復正常,我把管道放回'READY'(確認它已經準備好了,使用'get_state()')。但是,當我嘗試將其放回到「PLAYING」或「PAUSED」中時,我會遇到與以前相同的錯誤:'qtdemux。c(5847):gst_qtdemux_loop():/ GstPipeline:pipeline0/GstQTDemux:qtdemux0:\ nstreaming已停止,原因未鏈接(-1)' –

+0

當我使用我的RTSP源代替本地視頻播放時,出現非常類似的錯誤,除了這次是從'rtspsrc'而不是'qtdemux'。 gst_base_src_loop():/ GstPipeline:pipeline0/GstRTSPSrc:source/GstUDPSrc:udpsrc2:\ nstreaming已停止,原因未鏈接(-1)'' –

+0

嗯,未鏈接到qtdemux告訴它在重新使用時不會經歷相同的初始化,因爲它是新的。這可能是一個錯誤。如果您在EOS上重新創建管道並且它可以正常工作,則可以進行確認。你能爲gstreamer提交一個bug並添加你的python示例。 – ensonic