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

Posted

技术标签:

【中文标题】随时随地在 GStreamer 管道中添加和删除音频源【英文标题】:Adding and removing audio sources to/from GStreamer pipeline on-the-go 【发布时间】:2010-10-10 08:56:44 【问题描述】:

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

启动程序后,您会听到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.")

【问题讨论】:

【参考方案1】:

我自己找到了解决方案。我必须使用带有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(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.")

【讨论】:

为什么这行buzzersrc1.unlink(sinkpad2) 与此处相关?蜂鸣器 1 的源焊盘 1 连接到加法器的 sinkpad1。但是这里正在取消链接到sinkpad2。这是笔误吗? 是的,我相信这是一个错字。已更正,但应该有人检查。目前我的机器上没有必要的工具。

以上是关于随时随地在 GStreamer 管道中添加和删除音频源的主要内容,如果未能解决你的问题,请参考以下文章

将管道设置为播放状态后,Gstreamer 回调未命中

如何将 opencv mat 写入 gstreamer 管道?

是否有命令行命令可以在一行中为 gstreamer 管道测试 appsrc 和 appsink?

在 RTMP 流上添加时间叠加的 Gstreamer 问题

从 python 中的 opencv 写入 Gstreamer 管道

在 GStreamer 中混合音频和视频冻结