interdependently seeking of multible filesources in pipeline

Nicolas Dufresne nicolas at ndufresne.ca
Sun Dec 17 18:44:12 UTC 2017


I forgot, but an in the middle option is to split your source pipelines
into seperate pipelines. Then use appsr/appsink to pass the data to the
mixing pipeline. This way you can simply retimestamp and it no longer
matter how you seek the sources.

Le 17 déc. 2017 1:41 PM, "Nicolas Dufresne" <nicolas at ndufresne.ca> a écrit :

>
>
> Le 17 déc. 2017 11:44 AM, <spam at feuerundbenzin.tk> a écrit :
>
> 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 ?
>
>
> For now, your only "easy" option would be to use GStreamer Editing
> Services, a library designed on top of GStreamer to implement non-linear
> audio/video editing applications. Second possibility would be to use it's
> helper plugins, NLE. The hard way is to implement something similar to NLE,
> though that requires strong GStreamer dynamic coding skills, it's not for
> everyone.
>
>
> 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("audi
> omixer","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
> }
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20171217/cbade2a7/attachment-0001.html>


More information about the gstreamer-devel mailing list