2016-07-01 28 views
1

我用下面的配置工作了幾天,現在在管道管道: - 2個現場輸入流(RTMP) - 進入一個合成 - outputing另一個RTMP流如何下手pendings輸入

隨着一些轉換器,隊列等之間,它工作得很好。

但我的問題是,RTMP輸入一個可能不可用在啓動時,這樣的管道無法啓動,與以下錯誤崩潰: - 錯誤:無法讀取流 任何數據 - 錯誤:內部數據流錯誤

什麼是正確的方式來使這項工作,即開始與第一個輸入流,即使第二個還沒有準備好呢?

我嘗試了幾種方法:動態地改變管道,玩墊探頭,聽錯誤消息,但到目前爲止,我不能使它工作。

感謝, PL

回答

0

當你沒有張貼我猜你是確定與概念性的答案任何代碼..

有用於rtspsrc,使用它可以控制時,它會失敗幾個選項 - reagarding超時超過或超過最大試驗次數。這些都是(如果所有不知道):

retry - this may be not very useful if it deals only with ports .. 
timeout - if you want to try with UDP some longer time you can enlarge this one 
tcp-timeout - this is important, try to play with it - make it much larger 
connection-speed - maybe it will help to make smaller this one 
protocols - I have experience that for bad streams TCP was much better for me 

實際的概念(我不是專家,把它當作另一種觀點的問題):

您可以創建兩個垃圾桶 - 一個用於每個流。我會使用rtspsrc和decodebin,並阻止decodebin的輸出板,直到我有所有的pad,然後我將連接到合成器。

當你收到任何錯誤(它應該在等待所有焊盤的階段),那麼你會把箱子置於NULL狀態(我的意思是GStreamer狀態稱爲NULL)並且再次播放/放棄.. 那麼你有使用墊有問題(不知道是什麼:D)..你可以發佈你的代碼嗎? 也許嘗試丟棄錯誤信息,以不解體的管道。

此外,你有隻有視頻輸入? 我猜不,你可以使用音頻混音器..也可以使用合成器有很好的OpenGL版本,它的速度要快得多,它叫glvideomixer ..但它可能會引入另一個與OpenGL相關的問題..如果你有英特爾GPU,那麼你可能是安全的。

0

感謝@otopolsky的輸入。 我不確定你對rtspsrc屬性的評論,因爲我使用的是rtmpsrc。

無論如何,我試圖按照您的想法將輸入流放入垃圾箱。 爲了我的演示代碼,我只做了一個輸入流,把所有的音頻放在一邊。

的管道如下:

rtmpsrc => decodebin => videoscale => videorate => capsfilter 
=> compositor.sink_0 => capsfilter => x264enc => flvmux => rtmpsink 

我生成bin一旦管道處於播放狀態,從而保證了倉動態添加到管道。 的集裝箱拿到了第二個輸入的所有元素:

rtmpsrc => decodebin => videoscale => videorate => capsfilter 

我還設置一個鬼墊倉,關於這一點我用一個探頭,將做bin和管道之間的實際鏈接:

def _prob_block(self, pad, info, data): 
    pad.remove_probe(info.id) 
    src_pad = self.bin.get_static_pad('src') 
    sink_pad = self.compositor.get_request_pad('sink_1') 
    src_pad.link(sink_pad) 
    return Gst.PadProbeReturn.OK 

ghost_pad = Gst.GhostPad.new('src', self.capsfilter_video_ben.get_static_pad('src')) 
self.bin.add_pad(ghost_pad) 
ghost_pad.add_probe(Gst.PadProbeType.BLOCK_DOWNSTREAM, self._prob_block, None) 

然後,我有我的應用程序這個僞代碼:

def _activate_bin(): 
    # ... this is where I create bin along with bin elements 
    # ... and create the ghost pad (see above) 
    # Then add the bin to the pipeline 
    pipe._pipeline.add(bin) 
    bin.set_state(Gst.State.PLAYING) 

pipe = Pipeline() 
GObject.timeout_add_seconds(10, _activate_bin) 
pipe._pipeline.set_state(Gst.State.PLAYING) 

這種近乎完美的作品,管道與一個輸入(sink_0),通過共同去啓動mpositor然後進入rtmpsink(我實際上可以播放輸出流)。 然後10秒鐘後,我將bin添加到管道(合成器的pad'sink_1')。這裏再一次,這工作完美無瑕,直到我有兩個輸入合成器。這是它開始凍結的地方。

從我能讀的,它可能來自延遲和/或時鐘,但我無法設法解決這個問題。 有趣的是,當我用兩個輸入流啓動管道時,我都沒有問題。

你有什麼想法爲什麼它有不同的行爲?