c++ – gstreamer audiomixer command to code converting-ThrowExceptions

Exception or error:

I want to use audiomixer in my application which receives audios from different sources and should play them together in speaker.

my final application should do something like this command:

gst-launch-1.0 audiomixer name=mix ! autoaudiosink autoaudiosrc ! \
audioconvert ! mix. udpsrc port=5001 caps="application/x-rtp" ! queue !\
rtppcmudepay ! mulawdec ! audioconvert ! audioresample ! mix.

I already wrote a code to use tee and queues and know how to work with tee and queues in code based on this code. but I don’t know how to use mixer in my code.

so for simplicity I just want to write a code to work as this command does:

 gst-launch-1.0 audiotestsrc freq=100 ! audiomixer name=mix ! audioconvert ! autoaudiosink autoaudiosrc ! mix.

I didn’t find any useful example to reach this goal, how can I write a C code to do this?

How to solve:

for the second part:

 gst-launch-1.0 audiotestsrc freq=100 ! audiomixer name=mix ! audioconvert ! autoaudiosink autoaudiosrc ! mix.

this code works:

#include <gst/gst.h>
static GMainLoop *loop;
int bus_callback (GstBus *bus, GstMessage *message, gpointer data)
{
    g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message));
    switch (GST_MESSAGE_TYPE (message)) {
    case GST_MESSAGE_ERROR: {
        GError *err;
        gchar *debug;
        gst_message_parse_error (message, &err, &debug);
        g_print ("Error: %s\n", err->message);
        g_error_free (err);
        g_free (debug);
        g_main_loop_quit (loop);
        break;
    }
    case GST_MESSAGE_EOS:
        /* end-of-stream */
        g_main_loop_quit (loop);
        break;
    default:
        /* unhandled message */
        break;
    }
    /* we want to be notified again the next time there is a message
    * on the bus, so returning TRUE (FALSE means we want to stop watching
    * for messages on the bus and our callback should not be called again)
    */
    return TRUE;
}

int main(int argc, char *argv[])
{
    /* Initialize GStreamer */
    gst_init (nullptr, nullptr);
    GstElement *pipeline, *src1,*src2, *sink, *convert1,*convert2,*audiomixer;
    GstPad *conv_pad1, *conv_pad2, *mixer1_sinkpad,*mixer2_sinkpad;
    gint i;
    static GstBus *bus;
    static guint bus_watch_id;
    pipeline = gst_pipeline_new ("pipeline");
    audiomixer = gst_element_factory_make ("adder", "mixer");

    sink = gst_element_factory_make ("autoaudiosink", "sink");
    src1 = gst_element_factory_make ("audiotestsrc", "src1");
    convert1 = gst_element_factory_make ("audioconvert", "convert1");
    src2 = gst_element_factory_make ("autoaudiosrc", "src2");
    convert2 = gst_element_factory_make ("audioconvert", "convert2");
    //g_object_set (sink, "async-handling", TRUE, NULL);


    gst_bin_add_many (GST_BIN (pipeline), audiomixer ,sink, NULL);
    gst_bin_add_many (GST_BIN (pipeline), src1 , convert1 , NULL);
    gst_bin_add_many (GST_BIN (pipeline), src2 , convert2 , NULL);
    gst_element_link (src1, convert1 );
    gst_element_link (src2, convert2 );
    gst_element_link(audiomixer , sink);

    conv_pad1= gst_element_get_static_pad (convert1, "src");
    mixer1_sinkpad = gst_element_get_request_pad (audiomixer, "sink_%u");
    gst_pad_link (conv_pad1, mixer1_sinkpad);
    g_object_unref(mixer1_sinkpad);

    conv_pad2= gst_element_get_static_pad (convert2, "src");
    mixer2_sinkpad = gst_element_get_request_pad (audiomixer, "sink_%u");
    gst_pad_link (conv_pad2, mixer2_sinkpad);
    g_object_unref(mixer2_sinkpad);

    /* adds a watch for new message on our pipeline’s message bus to
    * the default GLib main context, which is the main context that our
    * GLib main loop is attached to below
    */
    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    bus_watch_id = gst_bus_add_watch (bus, bus_callback, NULL);
    gst_object_unref (bus);

    /* Start playing */
    gst_element_set_state (pipeline, GST_STATE_PLAYING);


    loop = g_main_loop_new (NULL, FALSE);

    g_main_loop_run (loop);
    g_object_unref(conv_pad1);
    g_object_unref(conv_pad2);
    gst_element_set_state (pipeline, GST_STATE_NULL);
    g_source_remove (bus_watch_id);
}

Leave a Reply

Your email address will not be published. Required fields are marked *