Gstreamer: Не можете одновременно слушать аудио + запись с alsasrc?

Я пишу приложение C, которое использует gstreamer для записи звука с ТВ-тюнера.

У меня есть карта ТВ-тюнера со звуковой картой типа hw:1,0. Доступ к источнику звука по умолчанию осуществляется в качестве источника воспроизведения, когда приложение начинает использовать ALSA API.

Я хочу написать функцию для записи звука из этого источника с помощью бэкэнда GStreamer.

Моя следующая проблема, похоже, связана с небольшим состоянием гонки, в котором мой hw: 1,0 уже используется, и мне нужно что-то записать.

Что я могу сделать, чтобы это сработало?

ОБНОВЛЕНИЕ: Воспроизведение звука не использует GStreamer API, если доступны alsa и libv4l2util, он автоматически запустит потоковую передачу звука между устройством V4L2 (hw:1.0) и устройством вывода звука (hw:0.0) с использованием функций ALSA.

Я пытаюсь остановить потоковую передачу ALSA и использую тройник элемента Gstreamer:

int main (int argc, char *argv[])
{
    GstCaps *filter;

    GMainLoop *loop;
    GstBus *bus;

    GstElement *pipeline, *audiosource, *audiosink, *audioresample, *audiobin, *audiotee, *encodebin, *filesink, *savebin;

    GstEncodingProfile *profile;

    gst_init (&argc, &argv);
    loop = g_main_loop_new (NULL, FALSE);

    pipeline = gst_pipeline_new("pipeline");
    audiosource = gst_element_factory_make("alsasrc", NULL);
    audiosink = gst_element_factory_make("alsasink", NULL);
    audioresample = gst_element_factory_make("audioresample", NULL);
    audiotee = gst_element_factory_make("tee", NULL);
    encodebin = gst_element_factory_make("encodebin", NULL);
    filesink = gst_element_factory_make("filesink", NULL);

    audiobin = gst_bin_new ("abin");
    savebin = gst_bin_new ("sbin");

    profile = gst_get_encoding_profile(my.settings.profile);

    if (!pipeline || !audiosource || !audiosink || !audioresample || !audiobin)
            return -1;

    g_object_set(G_OBJECT(audiosource), "device", "hw:1,0", NULL);
    g_object_set(G_OBJECT(filesink), "location", "save.ogg", NULL);
    g_object_set(encodebin, "profile", profile, NULL);
    gst_encoding_profile_unref(profile);

    g_object_set(G_OBJECT(audiobin), "async-handling", TRUE, NULL);
    g_object_set(G_OBJECT(savebin), "async-handling", TRUE, NULL);


    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    gst_bin_add_many (GST_BIN (audiobin), audiosource, audioresample, audiotee, audiosink, NULL);
    gst_bin_add_many (GST_BIN (savebin), encodebin, filesink, NULL);
    gst_bin_add_many (GST_BIN (pipeline), audiobin, savebin, NULL);

    filter = gst_caps_new_simple("audio/x-raw", "rate", G_TYPE_INT, 32000, NULL);
    if (!gst_element_link_filtered(audiosource, audioresample, filter))
            return -1;

    if (!gst_element_link_many(audioresample, audiotee, audiosink, NULL))
            return -1;

    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    g_main_loop_run (loop);

    gst_element_set_state (pipeline, GST_STATE_NULL);
    gst_object_unref (GST_OBJECT (pipeline));

    return 0;
}

Теперь я слышу звук, запись начинается, но созданный файл записи не содержит данных.


person Cecylia    schedule 10.01.2015    source источник
comment
Это, конечно, не полный код, элементы даже не связаны и не добавлены в конвейер, и я не вижу элементов для фактического воспроизведения звука. Пожалуйста, обновите свой вопрос, указав фактический код.   -  person Mathieu_Du    schedule 10.01.2015


Ответы (1)


В обновленном вопросе я вижу, что encodebin добавлен в конвейер, но не связан с аудио-тройником, это будет вашей проблемой. Я ожидаю, что в вашем текущем коде с бесполезными audiobin и savebin вы также получите сообщение об ошибке при попытке сделать это в соответствии с «неправильной иерархией элементов». Избавьтесь от этих двух мусорных ведер, и это должно работать.

person Mathieu_Du    schedule 11.01.2015