2010-10-10 101 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.")