随时随地向 GStreamer 管道添加和删除音频源

发布于 2024-09-26 12:03:03 字数 1535 浏览 9 评论 0原文

我编写了一个小 Python 脚本,它使用 Adder 插件将两个源流混合在一起。

启动程序后,您会听到由 audiotestsrc 插件生成的 1kHz 音调。当您按 Enter 时,另一个 500Hz 测试音会连接到 Adder,以便您同时听到它们。 (顺便说一句,我真的不明白为什么我应该在这里再次将管道设置为播放状态来听到混音。有什么方法可以插入新的源而不必重新启动管道?)

当您按 Enter 一次时再次,1kHz 音调应该从混音中移除,500Hz 音调应该继续播放,但我却什么也没听到。我得到一个脉冲pulsesink.c:528:gst_pulsering_stream_underflow_cb:最后一行在调试输出中出现下溢。我真的不知道下一步该尝试什么。

这是完整的源代码:

#!/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.")

I wrote a little Python script which uses an Adder plugin to mix two source streams together.

After starting the program, you hear a 1kHz tone generated by the audiotestsrc plugin. When you press Enter, an another 500Hz test tone is connected to the Adder so you hear them together. (By the way, i don't really get why should i set the pipeline again to playing state here to hear the mix. Is there any way i can plug in new sources without having to restart the pipeline?)

When you press Enter once again, the 1kHz tone should be removed from the mix and the 500Hz tone should keep playing, but instead i hear nothing anymore. I get a pulse pulsesink.c:528:gst_pulsering_stream_underflow_cb:<pulseaudio_output> Got underflow in the debug output as the last line. I don't really know what to try next.

Here is the full source code:

#!/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.")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小嗷兮 2024-10-03 12:03:03

我自己找到了解决方案。我必须将请求垫与 Adder 一起使用,并使用 pad 阻止 功能。

这是带有一些描述的工作源代码:

#!/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(sinkpad1)
    # 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.")

I've found the solution on my own. I had to use request pads with Adder and use the pad blocking capability of GStreamer.

Here's the working source code with some descriptions:

#!/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(sinkpad1)
    # 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.")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文