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