2010-10-10 149 views
5

我寫了一個小小的Python腳本,它使用一個Adder插件將兩個源碼流混合在一起。將音頻源添加到GStreamer管道中去除音頻源

啓動程序後,您會聽到audiotestsrc插件生成的1kHz音調。當您按Enter鍵時,另一個500Hz的測試音連接到Adder,以便您可以一起聽到它們。 (順便說一下,我真的不明白爲什麼我應該再次將管道設置爲播放狀態以聽取混音。是否有任何方法可以插入新聲源而不必重新啓動管道?)

當你再次按下Enter鍵,應從混音中刪除1kHz音調,並且500Hz音調應該繼續播放,但是我不再聽到任何東西。作爲最後一行,我在調試輸出中獲得pulse pulsesink.c:528:gst_pulsering_stream_underflow_cb:<pulseaudio_output> Got underflow。我真的不知道接下來要做什麼。

下面是完整的源代碼:

#!/usr/bin/python 
# On-the-go source removal doesn't work this way with GStreamer. Why? 

import gobject; 
gobject.threads_init() 
import gst; 

if __name__ == "__main__": 
    pipe = gst.Pipeline("mypipe") 

    adder = gst.element_factory_make("adder","audiomixer") 
    pipe.add(adder) 

    buzzer = gst.element_factory_make("audiotestsrc","buzzer") 
    buzzer.set_property("freq",1000) 
    pipe.add(buzzer) 

    pulse = gst.element_factory_make("pulsesink", "pulseaudio_output") 
    pipe.add(pulse) 

    buzzer.link(adder) 
    adder.link(pulse) 
    pipe.set_state(gst.STATE_PLAYING) 

    raw_input("1kHz test sound. Press <ENTER> to continue.") 

    buzzer2=gst.element_factory_make("audiotestsrc","buzzer2") 
    buzzer2.set_property("freq",500) 

    pipe.add(buzzer2) 
    buzzer2.link(adder) 
    pipe.set_state(gst.STATE_PLAYING) 

    raw_input("1kHz + 500Hz test sound playing simoultenously. Press <ENTER> to continue.") 

    buzzer.unlink(adder) 
    pipe.set_state(gst.STATE_PLAYING) 

    raw_input("Only 500Hz test sound. Press <ENTER> to stop.") 

回答

6

我發現我自己的解決方案。我必須使用Adder的請求板,並使用GStreamer的pad blocking功能。

這裏是工作的源代碼有一些描述:

#!/usr/bin/python 

import gobject; 
gobject.threads_init() 
import gst; 

if __name__ == "__main__": 
    # First create our pipeline 
    pipe = gst.Pipeline("mypipe") 

    # Create a software mixer with "Adder" 
    adder = gst.element_factory_make("adder","audiomixer") 
    pipe.add(adder) 

    # Gather a request sink pad on the mixer 
    sinkpad1=adder.get_request_pad("sink%d") 

    # Create the first buzzer.. 
    buzzer1 = gst.element_factory_make("audiotestsrc","buzzer1") 
    buzzer1.set_property("freq",1000) 
    pipe.add(buzzer1) 
    # .. and connect it's source pad to the previously gathered request pad 
    buzzersrc1=buzzer1.get_pad("src") 
    buzzersrc1.link(sinkpad1) 

    # Add some output 
    output = gst.element_factory_make("autoaudiosink", "audio_out") 
    pipe.add(output) 
    adder.link(output) 

    # Start the playback 
    pipe.set_state(gst.STATE_PLAYING) 

    raw_input("1kHz test sound. Press <ENTER> to continue.") 

    # Get an another request sink pad on the mixer 
    sinkpad2=adder.get_request_pad("sink%d") 

    # Create an another buzzer and connect it the same way 
    buzzer2 = gst.element_factory_make("audiotestsrc","buzzer2") 
    buzzer2.set_property("freq",500) 
    pipe.add(buzzer2) 

    buzzersrc2=buzzer2.get_pad("src") 
    buzzersrc2.link(sinkpad2) 

    # Start the second buzzer (other ways streaming stops because of starvation) 
    buzzer2.set_state(gst.STATE_PLAYING) 

    raw_input("1kHz + 500Hz test sound playing simoultenously. Press <ENTER> to continue.") 

    # Before removing a source, we must use pad blocking to prevent state changes 
    buzzersrc1.set_blocked(True) 
    # Stop the first buzzer 
    buzzer1.set_state(gst.STATE_NULL) 
    # Unlink from the mixer 
    buzzersrc1.unlink(sinkpad2) 
    # Release the mixers first sink pad 
    adder.release_request_pad(sinkpad1) 
    # Because here none of the Adder's sink pads block, streaming continues 

    raw_input("Only 500Hz test sound. Press <ENTER> to stop.")