Куренто: невозможно получить обратный вызов от резака элементов GStreamer

Я пытаюсь применить некоторые плагины GStreamer к kurento mediapipeline, здесь я ожидаю, что код Gstreamer, который отлично работает в автономной программе, отправляет сообщения обратного вызова, связанные с cutter.

Вот мой код:

namespace kurento
{
    namespace module
    {
        namespace vadcustomfilter
        {
            std::string Id = "";

            void VADCustomFilterImpl::busMessage(GstMessage * message)
            {
                GST_ERROR("***In BusMessage***");

                if (message->type == GST_MESSAGE_EOS)
                {
                    g_object_set(G_OBJECT(valve), "drop", FALSE, NULL);
                }

                const GstStructure *s = gst_message_get_structure(message);
                const gchar *name = gst_structure_get_name(s);
                GST_INFO("Name: %s\n", name);

                if (message->type == GST_MESSAGE_ELEMENT)
                {
                    if (strcmp(name, "cutter") == 0)
                    {
                        GstClockTime time = 0;
                        GstClockTime prevsilencetime = 0;

                        if (!gst_structure_get_boolean(s, "above", &above))
                        {
                            GST_ERROR("could not parse above");
                        }

                        GST_INFO("above: %d", above);

                        if (above)
                        {
                            if (isSpeaking == 0)
                            {
                                revsilencetime = time;                              
                                g_object_set(G_OBJECT(valve), "drop", FALSE, NULL);
                            }
                            /*Send Voice Detected Event */                          
                            try
                            {
                                GST_ERROR("Sending Event: VoiceDetected");
                                VoiceDetected event(shared_from_this(), "voice-detected", Id.c_str());
                                signalVoiceDetected(event);
                                GST_ERROR("Sent Event: VoiceDetected");
                            }
                            catch (std::bad_weak_ptr & e)
                            {
                                GST_ERROR("EXCEPTION: Voice activity detected ");
                            }
                            isSpeaking = 1;
                        }
                        else
                        {
                            if (isSpeaking == 1)
                            {
                                g_object_set(G_OBJECT(valve), "drop", TRUE, NULL);
                            }
                            isSpeaking = 0;
                        }
                    }
                }
            }


            VADCustomFilterImpl::VADCustomFilterImpl(const boost::property_tree::
                ptree & config,
                std::shared_ptr <
                MediaPipeline > mediaPipeline,
                const std::string &pipelineId) :FilterImpl
                (config,
                std::dynamic_pointer_cast <MediaObjectImpl> (mediaPipeline))
            {
-->Edit Start       

                g_object_set (element, "filter-factory", "audioconvert", NULL);
                g_object_get (G_OBJECT (element), "filter", &audioconvertfilter, NULL);

                if (audioconvertfilter == NULL) {
                    throw KurentoException (MEDIA_OBJECT_NOT_FOUND, "MediaObject not found: audioconvertfilter");
                }

                g_object_set (element, "filter-factory", "cutter", NULL);
                g_object_get (G_OBJECT (element), "filter", &cutterfilter, NULL);

                if (cutterfilter == NULL) {
                    throw KurentoException (MEDIA_OBJECT_NOT_FOUND, "MediaObject not found: cutterfilter");
                }

                g_object_set (G_OBJECT (cutterfilter), "threshold-dB", -39.0, NULL);
                g_object_set (G_OBJECT (cutterfilter), "run-length", 400000000, NULL);


                g_object_set (element, "filter-factory", "vadcustomfilter", NULL);

                g_object_get (G_OBJECT (element), "filter", &vadCustomFilter, NULL);

                bus_handler_id = 0;
                GST_ERROR("PipelineId: constructor %s",pipelineId.c_str());
                Id = pipelineId;
    -->Edit End

            }


            void VADCustomFilterImpl::postConstructor()
            {
                GstBus *bus;

                std::shared_ptr < MediaPipelineImpl > pipe;

                FilterImpl::postConstructor();

                pipe =
                    std::dynamic_pointer_cast <MediaPipelineImpl>
                    (getMediaPipeline());
                g_assert(pipe);

                /* #1. Add cutter filter here */
                create_gst_cutter_filter(pipe);


                bus = gst_pipeline_get_bus(GST_PIPELINE(pipe->getPipeline()));
                g_assert(bus);
                bus_handler_id = register_signal_handler(G_OBJECT(bus),
                    "message",
                    std::function <
                    void(GstElement *,
                    GstMessage *) >
                    (std::bind
                    (&VADCustomFilterImpl::
                    busMessage, this,
                    std::placeholders::_2)),
                    std::dynamic_pointer_cast <
                    VADCustomFilterImpl>
                    (shared_from_this()));


                GST_ERROR("busMessage added successfully.");

                g_object_unref(bus);
            }

            VADCustomFilterImpl::~VADCustomFilterImpl()
            {
                std::shared_ptr < MediaPipelineImpl > pipe;

                if (bus_handler_id > 0)
                {
                    pipe =
                        std::dynamic_pointer_cast <MediaPipelineImpl>
                        (getMediaPipeline());
                    GstBus *bus =
                        gst_pipeline_get_bus(GST_PIPELINE(pipe->getPipeline()));
                    unregister_signal_handler(bus, bus_handler_id);
                    g_object_unref(bus);
                }
            }

            MediaObjectImpl *VADCustomFilterImplFactory::createObject(const boost::
                property_tree::
                ptree &
                config,
                std::
                shared_ptr <
                MediaPipeline
                >
                mediaPipeline,
                const std::string &pipelineId)
                const
            {
                GST_ERROR("Pipeline Id createObject %s", pipelineId.c_str());
                return new VADCustomFilterImpl(config, mediaPipeline, pipelineId.c_str());
            }




            VADCustomFilterImpl::StaticConstructor VADCustomFilterImpl::
                staticConstructor;

            VADCustomFilterImpl::StaticConstructor::StaticConstructor()
            {
                GST_DEBUG_CATEGORY_INIT(GST_CAT_DEFAULT, GST_DEFAULT_NAME, 0,
                    GST_DEFAULT_NAME);
            }
        }/* vadcustomfilter */
    }/* module */
}/* kurento */

в целом я добавил комментарии к вопросам, которые у меня есть в коде.

Я получаю обратный вызов для GstMessageTag, который я напечатал в журнале с помощью gst_structure_get_name(name), но я не получаю обратных вызовов для cutter

Что-то отсутствует / не так в потоке кода?

Изменить: удален способ добавления фильтров плагина с помощью gstreamer, попытка добавить audioconvert cutter на element

но я получаю сообщение об ошибке addIceCandidate:

Req-> {"id":13,"method":"invoke","params":{"object":"ff394885-ff7b-4cd2-ac83-190ab58056c3_kurento.MediaPipeline/4911aa60-27e4-461e-86c0-10532bc30d4f_kurento.WebRtcEndpoint","operation":"addIceCandidate","operationParams":{"candidate":{"sdpMid":"audio","__module__":"kurento","sdpMLineIndex":0,"__type__":"IceCandidate","candidate":"candidate:1226269011 1 udp 2122260223 172.24.9.207 62808 typ host generation 0 ufrag nSC45+9JNTCJm+yr"}},"sessionId":"15daae09-de86-4293-a3de-28f33f2d0b16"},"jsonrpc":"2.0"}


Res {"id":13,"error":{"code":40401,"message":"Error adding candidate","data":{"type":"ICE_ADD_CANDIDATE_ERROR"}},"jsonrpc":"2.0"}

person Sagar Pilkhwal    schedule 11.03.2016    source источник


Ответы (1)


Похоже, что способ создания элементов gstreamer не соответствует ожиданиям Куренто. В основном вы создаете элементы в функции create_gst_cutter_filter, которые не связаны правильно.

Если вы создаете фильтр, все элементы gstreamer (создание элементов и их соединение) должны выполняться в элементе gstreamer, который вы называете vadcustomfilter, этому элементу нужен только один приемник и одна контактная площадка src.

Если вы хотите создать элемент другого типа, как кажется, потому что вы добавляете mulltifilesink, вам необходимо перейти от MediaElement и создать элемент gstreamer, расширяющийся от KmsElement. Вы можете увидеть примеры этого в проекте kms-elements.

Изменить:

Об ошибке, возвращаемой сервером. Кажется, это связано не с проблемой здесь, а с проблемой зависимости. Вернитесь на этот вопрос и проверьте, возникла ли у вас такая же проблема.

person santoscadenas    schedule 11.03.2016
comment
@SagarPilkhwal Да, kms-elements - огромный проект, но это единственное место, где у нас есть примеры плагинов, которые не являются фильтрами. Если вы следуете приведенным здесь инструкциям для плагина gstreamer, вы получите базовый код проекта без opencv. doc-kurento.readthedocs. org / en / stable / mastering /. Но я думаю, это то, что вы уже сделали. - person santoscadenas; 11.03.2016
comment
Какова цель вашего плагина? В зависимости от этого вы должны пойти по тому или иному пути. - person santoscadenas; 11.03.2016
comment
Посмотрите, как делается фильтр zbar. github.com/Kurento/kms- фильтры / blob / master / src / server / - person santoscadenas; 11.03.2016
comment
Возможно, вам не нужно audioconvert, в большинстве случаев agnosticbin может сделать это за вас. - person santoscadenas; 11.03.2016
comment
@SagarPilkhwal Проверьте правку в моем ответе, чтобы убедиться, что это проблема - person santoscadenas; 11.03.2016
comment
Привет, я удалил элемент audiofilter и теперь получаю обратные вызовы для cutter. Также, как использовать multifilesink, будет ли задействован какой-либо особый сценарий при использовании multifilesink - person Sagar Pilkhwal; 11.03.2016
comment
N, у нас нет такого сценария, наиболее похожим мог бы быть диктофон, но есть свои особенности, не знаю, хороший ли это пример. Зачем тебе это? - person santoscadenas; 11.03.2016
comment
Я хочу убрать тишину из потока и сохранить его в нескольких файлах. У меня есть рабочий код gstreamer, который убирает тишину и сохраняет в файл. но мне кажется, что объединить его с куренто будет непростой задачей - person Sagar Pilkhwal; 11.03.2016
comment
Попробуйте использовать предоставленные элементы kurento, это ускорит ваше развитие. Создавать нестандартные элементы всегда сложно. Добавление фильтра kurento GStreamer только с режущим элементом и подключение его к записывающему устройству может сделать эту работу за вас без какого-либо специального плагина. - person santoscadenas; 11.03.2016
comment
хорошо, есть ли какой-то конкретный плагин kurento, который может помочь записать звук, потому что мне нужно перематывать / искать назад конвейер на несколько миллисекунд, когда обнаруживается голос. что я не думаю, что это возможно. Спасибо - person Sagar Pilkhwal; 11.03.2016
comment
Вы правы, куренто не позволяет заниматься поиском по конвейеру. Для этого вам понадобится другой хак, создание собственного рекордера или что-то в этом роде, это непростая задача. Другим более простым вариантом может быть запись файла, а затем его пост-обработка, чтобы удалить тишину с помощью программы, которая у вас уже есть. - person santoscadenas; 11.03.2016
comment
Привет, В примере приложения группового вызова Java, как я могу получить доступ к каждому пользователю mediapipeline. Можно ли раздобыть отдельный трубопровод? когда я печатаю Id медиапроводку подключенного пользователя, я получаю тот же результат user1: b524a269-cef8-4070-99d4-e8895b7e6fb8_kurento.MediaPipeline user2: b524a269-cef8-4070-99d4-e8895b7e6fb8_kurento.MediaPipeline - person Sagar Pilkhwal; 15.03.2016
comment
Вы имеете в виду доступ к конвейеру gstreamer? или Куренто Пайплайн? Если вы получите доступ к WebRtcEndpoint, вы можете получить его родительский объект, который является MediaPipeline. - person santoscadenas; 15.03.2016
comment
Я думаю, что это совершенно другой вопрос, чем исходный, давайте перейдем к новому вопросу. - person santoscadenas; 15.03.2016