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