interdependently seeking of multible filesources in pipeline

spam at feuerundbenzin.tk spam at feuerundbenzin.tk
Sun Dec 17 16:24:50 UTC 2017


Hello,

I want to create a lite sampler application. Where you can 
play,stop,loop multiple sound files.
im currently experimenting with gstreamer and stuck on some point.

this is how my application currently look like:

pipeline:
bin1: filesource1 -> decoder1 -> converter1 ---\
|-> audiomixer -> alsasink
bin2: filesource2 -> decoder2 -> converter2  ---/

i have an audiomixer connected with to file sources. how can i seek the 
2 sources interdependently ?
I can seek the whole pipeline, but seeking the filesources don't work 
(see function play_button_CB in src).

can anybody help ?

Thanks Richard


-----------------------------------------------
#include <gst/gst.h>
#include <gst/gstelement.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include <glib.h>
#define FALSE (0)
#define TRUE (!FALSE)

#include <gtk/gtk.h>

typedef struct
{
     GstElement *pipeline;

     GstElement *file_source;
     GstElement *audio_decoder;
     GstElement *audioconvert;
     GstElement *bin_playback;

     GstElement *file_source2;
     GstElement *audio_decoder2;
     GstElement *audioconvert2;
     GstElement *bin_playback2;

     GstElement *audio_mixer;
     GstElement *alsasink;

     GstElement *visual;
     GstElement *tee;


     GstBus *bus;
     GstMessage *message;

     gchar filelocation[2000];
}playerData;

playerData gstreamerPlayer;


typedef struct
{
     GtkWidget *mainWindow;
     GtkWidget *play_button;

}guiData;

guiData guiElements;

/*
void on_pad_added2 (GstElement *src_element, GstPad *src_pad, gpointer 
data)
{
     g_print ("\nLinking dynamic pad between wavparse and alsasink\n");

     GstElement *sink_element = (GstElement *) data;     // Is alsasink
     GstPad *sink_pad = gst_element_get_static_pad (sink_element, "sink");
     gst_pad_link (src_pad, sink_pad);

     gst_object_unref (sink_pad);
     src_element = NULL;     // Prevent "unused" warning here
}
*/

gboolean player_Create(playerData *data)
{
     data->pipeline = gst_pipeline_new("audio_pipeline");

     if (data->pipeline == NULL)    return FALSE;
     gst_element_set_state (data->pipeline, GST_STATE_NULL);

     data->alsasink = gst_element_factory_make("alsasink", "audiosink");
     data->audio_mixer = 
gst_element_factory_make("audiomixer","audiomixer");

     if ( !data->pipeline || !data->alsasink || !data->audio_mixer)    {
         g_printerr ("\nNot all elements for audio pipeline were 
created\n");
         return FALSE;
     }


     gst_bin_add_many(GST_BIN (data->pipeline), 
data->audio_mixer,data->alsasink,NULL);


     if (gst_element_link_many (data->audio_mixer, data->alsasink, NULL) 
!= TRUE) {
         g_printerr("\nAudio mixer and audio sink element could not 
link\n");
         return FALSE;
     }


}


gboolean player_Add(playerData *data)
{
     data->bin_playback = gst_bin_new ("bin_playback");
     data->bin_playback2 = gst_bin_new ("bin_playback2");




     data->file_source = gst_element_factory_make("filesrc", "filesource");
     data->audioconvert = gst_element_factory_make("audioconvert", 
"audioconverter");

     data->file_source2 = gst_element_factory_make("filesrc", 
"filesource2");
     data->audioconvert2 = gst_element_factory_make("audioconvert", 
"audioconverter2");





     if ( !data->file_source || !data->audioconvert)    {
         g_printerr ("\nNot all elements for audio pipeline were 
created\n");
         return FALSE;
     }

     if ( !data->file_source2 || !data->audioconvert2)    {
         g_printerr ("\nNot all elements for audio pipeline were 
created\n");
         return FALSE;
     }



     g_object_set (G_OBJECT (data->file_source), "location", 
"/home/admin2/Downloads/SampleAudio_0.4mb.mp3", NULL);

     g_object_set (G_OBJECT (data->file_source2), "location", 
"/home/admin2/Downloads/SampleAudio_0.7mb.mp3", NULL);



     data->audio_decoder = gst_element_factory_make("mad", 
"audiomp3decoder");
     if ( !data->audio_decoder)    {
         g_printerr ("\nNot all elements for audio pipeline were 
created\n");
         return FALSE;
     }


     gst_bin_add_many(GST_BIN(data->bin_playback), data->file_source, 
data->audio_decoder, data->audioconvert, NULL);

     if (gst_element_link_many (data->file_source, data->audio_decoder, 
NULL) != TRUE) {
         g_printerr("\nFile source and audio decoder element could not 
link\n");
         return FALSE;
     }

     if (gst_element_link_many (data->audio_decoder, data->audioconvert, 
NULL) != TRUE) {
         g_printerr("\nAudio decoder and audio converter element could 
not link\n");
         return FALSE;
     }

     {
     GstPad *pad;
     pad = gst_element_get_static_pad (data->audioconvert, "src");
     gst_element_add_pad (data->bin_playback, gst_ghost_pad_new ("src", 
pad));
     gst_object_unref (GST_OBJECT (pad));
     }



/*################################################################################*/ 

     data->audio_decoder2 = gst_element_factory_make("mad", 
"audiomp3decoder2");
     if ( !data->audio_decoder2)    {
         g_printerr ("\nNot all elements for audio pipeline were 
created\n");
         return FALSE;
     }

     gst_bin_add_many(GST_BIN(data->bin_playback2), data->file_source2, 
data->audio_decoder2, data->audioconvert2,NULL);

     if (gst_element_link_many (data->file_source2, 
data->audio_decoder2, NULL) != TRUE) {
         g_printerr("\nFile source and audio decoder element could not 
link\n");
         return FALSE;
     }
     if (gst_element_link_many (data->audio_decoder2, 
data->audioconvert2, NULL) != TRUE) {
         g_printerr("\nAudio decoder and audio converter element could 
not link\n");
         return FALSE;
     }

     {
     GstPad *pad;
     pad = gst_element_get_static_pad (data->audioconvert2, "src");
     gst_element_add_pad (data->bin_playback2, gst_ghost_pad_new ("src", 
pad));
     gst_object_unref (GST_OBJECT (pad));
     }



     return TRUE;
}





gboolean player_Start(playerData *data)
{
     gst_bin_add_many(GST_BIN (data->pipeline), data->bin_playback, 
data->bin_playback2, NULL);



     if (gst_element_link_many (data->bin_playback, data->audio_mixer, 
NULL) != TRUE) {
         g_printerr("\nbin_playback and audio mixer element could not 
link\n");
         return FALSE;
     }
     if (gst_element_link_many (data->bin_playback2, data->audio_mixer, 
NULL) != TRUE) {
             g_printerr("\nbin_playback2 and audio mixer element could 
not link\n");
             return FALSE;
     }

     if (gst_element_set_state (data->pipeline, GST_STATE_NULL) != 
GST_STATE_CHANGE_SUCCESS) {
         g_print("\nFailed to set pipeline state to NULL\n");
         return FALSE;
     }

     gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
     while(gst_element_get_state(data->pipeline, NULL, NULL, 
GST_CLOCK_TIME_NONE) != GST_STATE_CHANGE_SUCCESS);
     return TRUE;

}




static gboolean bus_call_CB (GstBus *bus, GstMessage *msg, gpointer    
data) {
     GMainLoop *loop = (GMainLoop *) data;

     switch (GST_MESSAGE_TYPE (msg)) {

         case GST_MESSAGE_EOS:
             g_print ("End of stream\n");
             g_main_loop_quit (loop);
             break;

         case GST_MESSAGE_ERROR:
             {
             gchar  *debug;
             GError *error;

             gst_message_parse_error (msg, &error, &debug);

             g_printerr ("Error: %s\n", error->message);
             g_error_free (error);

             if (debug) {
                 g_printerr ("\nDebug details: %s\n", debug);
                 g_free (debug);
             }

             g_main_loop_quit (loop);
             break;
             }

         default:
             break;
     }

   return TRUE;
}

static void play_button_CB (GtkButton *button, guiData *data) {

     //this works ...
     /*
     if (!gst_element_seek(gstreamerPlayer.pipeline, 1.0, 
GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | 
GST_SEEK_FLAG_SEGMENT,GST_SEEK_TYPE_SET,0,GST_SEEK_TYPE_NONE, 6)) {
         g_print("Seek failed!\n");
     }
     */

     //how to seek file_source independently ???

     //this not ...
     if (!gst_element_seek(gstreamerPlayer.file_source, 1.0, 
GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | 
GST_SEEK_FLAG_SEGMENT,GST_SEEK_TYPE_SET,0,GST_SEEK_TYPE_NONE, 6)) {
         g_print("Seek failed!\n");
     }
}

void create_Gui(guiData *data) {


       data->mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);


       data->play_button = gtk_button_new_from_icon_name 
("media-playback-start", GTK_ICON_SIZE_SMALL_TOOLBAR);
       g_signal_connect (G_OBJECT (data->play_button), "clicked", 
G_CALLBACK (play_button_CB), data);

       GtkWidget *controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
       gtk_box_pack_start (GTK_BOX (controls), data->play_button, FALSE, 
FALSE, 2);
       gtk_container_add (GTK_CONTAINER (data->mainWindow), controls);

       gtk_widget_show_all(data->mainWindow);

}




int main(int argc, char *argv[])
{
     gtk_init_check(&argc, &argv);
     gst_init (&argc, &argv);


     player_Create(&gstreamerPlayer);
     player_Add(&gstreamerPlayer);
     player_Start(&gstreamerPlayer);



     GstBus *bus;
     guint bus_watch_id;
     GMainLoop *loop;
     loop = g_main_loop_new (NULL, FALSE);



     bus = gst_pipeline_get_bus (GST_PIPELINE (gstreamerPlayer.pipeline));
     bus_watch_id = gst_bus_add_watch (bus, bus_call_CB, loop);
     gst_object_unref (bus);







     create_Gui(&guiElements);
     g_main_loop_run (loop);


     gst_element_set_state (gstreamerPlayer.pipeline, GST_STATE_NULL);
     gst_object_unref (GST_OBJECT (gstreamerPlayer.pipeline));
     g_source_remove (bus_watch_id);
     g_main_loop_unref (loop);

     //to more cleanup here
}



More information about the gstreamer-devel mailing list