Добавление и удаление аудиоисточников в / из конвейера GStreamer на ходу - PullRequest
5 голосов
/ 10 октября 2010

Я написал небольшой скрипт на Python, который использует плагин Adder для смешивания двух исходных потоков.

После запуска программы вы слышите тон 1 кГц, генерируемый плагином audiotestsrc. Когда вы нажимаете Enter, к Adder подключается еще один тестовый сигнал с частотой 500 Гц, поэтому вы слышите их вместе. (Кстати, я не совсем понимаю, почему я должен снова установить конвейер в состояние воспроизведения, чтобы услышать микс. Есть ли способ подключить новые источники, не перезапуская конвейер?)

Когда вы нажимаете Enter еще раз, тон 1кГц должен быть удален из микса, а тон 500Гц должен продолжать играть, но вместо этого я больше ничего не слышу. Я получаю 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 Ответ

6 голосов
/ 10 октября 2010

Я нашел решение самостоятельно.Мне пришлось использовать пэды запросов с Adder и использовать блокировку пэдов *1003* в GStreamer.

Вот рабочий исходный код с некоторыми описаниями:

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