What is the sequence to be followed to play a song using gstreramer?

匿名 (未验证) 提交于 2019-12-03 09:19:38

问题:

I am building a music player based on gstreamer-0.10. I am able to play the successfully , but I have issues when I change the state of the pipeline. I have posted the code to initialize and start the pipeline below :

    void start_gstreamer() {     gst_init(0,NULL);//call to initialise gstreamer     time_val=0;//set to default value     volume = 1.0;//set volume to default value     player = gst_element_factory_make ("playbin2", "player");//get pipeline     equalizer = gst_element_factory_make ("equalizer-10bands", "equalizer");//get the 10band equalizer     convert = gst_element_factory_make ("audioconvert", "convert");     sink = gst_element_factory_make ("autoaudiosink", "audio_sink");//get the audio-sink     if (!equalizer || !convert || !sink)//check is all elements were created     {         g_printerr ("Not all elements could be created.\n");         //return -1;     }     //int i=0;     /* Create the sink bin, add the elements and link them */     bin = gst_bin_new ("audio_sink_bin");//get new bin     gst_bin_add_many (GST_BIN (bin), equalizer, convert, sink, NULL);//add elements to bin     if(!(gst_element_link_many (equalizer, convert, sink, NULL)))//link all elements         g_print("Could not link all elements\n");     pad = gst_element_get_static_pad (equalizer, "sink");//set equalizer to sink     ghost_pad = gst_ghost_pad_new ("sink", pad);//get a ghost pad to sink     gst_pad_set_active (ghost_pad, TRUE);     gst_element_add_pad (bin, ghost_pad);//add ghost pad to the bin     gst_object_unref (pad);//unreference pad     gst_element_set_state (player, GST_STATE_READY);//set pipeline to ready state     //gst_element_set_state (player, GST_STATE_PAUSED);     /* Configure the equalizer */     g_object_set (G_OBJECT (equalizer), "band0",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band1",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band2",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band3",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band4",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band5",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band6",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band7",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band8",(gdouble) 0.0, NULL);     g_object_set (G_OBJECT (equalizer), "band9",(gdouble) 0.0, NULL);     /* Set playbin2's audio sink to be our sink bin */     g_object_set (GST_OBJECT (player), "audio-sink", bin, NULL); }

The above code will initialize the gstreamer pipeline. I am using playbin2.

void start_playbin (char *gargv1) {     time_t rawtime;     struct tm * timeinfo;     static gboolean i=TRUE;       gchar* uri;//to hold the path temporarily     gchar* dname;//to hold the directory name     time ( &rawtime );     timeinfo = localtime ( &rawtime );     printf ( "START:%s\n", asctime (timeinfo) );      uri = (gchar *)g_malloc( sizeof("file://") + strlen(gargv1) + 1);//get complete path     strcpy(uri,"file://");     strcat(uri,gargv1);//add path with the file path     dname = g_uri_escape_string(uri,G_URI_RESERVED_CHARS_ALLOWED_IN_PATH,TRUE);      g_free(uri);     uri = dname;      g_object_set(player,"uri",uri,NULL);//set file path for playback in the pipeline     g_print("\n\nPlaying %s\n", gargv1);     g_free(uri);//free path     /* start playback */      gst_element_set_state (GST_ELEMENT (player), GST_STATE_READY);//set pipeline to ready state     if(i==TRUE)     {         unsigned int count=0;         while(gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING)!=GST_STATE_CHANGE_SUCCESS);         //g_print("here:%d\n",count++);         i=FALSE;         }     else         play_playbin();//start playback     bus = gst_pipeline_get_bus(GST_PIPELINE(player));//get bus reference     gst_bus_add_watch(bus,(GstBusFunc)cb_message,player);//add bus to be monitored by  process events     g_object_unref(bus);//unreference bus      time ( &rawtime );     timeinfo = localtime ( &rawtime );     printf ( "AFTER START:%s\n", asctime (timeinfo) );     }

I had to use the if(i == TRUE) condition just because the pipeline doesn't change the state for the first time.

void stop_playbin() {     if(gst_element_set_state (GST_ELEMENT (player), GST_STATE_NULL)!=GST_STATE_CHANGE_SUCCESS)         g_print("Playbin could not be stopped\n");     //g_assert(gst_element_set_state (GST_ELEMENT (player),GST_STATE_NULL)==GST_STATE_CHANGE_SUCCESS); }  void pause_playbin() {     if(gst_element_set_state (GST_ELEMENT (player), GST_STATE_PAUSED)!=GST_STATE_CHANGE_SUCCESS)         g_print("Playbin could not be paused\n");     //g_assert(gst_element_set_state (GST_ELEMENT (player), GST_STATE_PAUSED)==GST_STATE_CHANGE_SUCCESS);

}

void play_playbin() {       if(gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING)!=GST_STATE_CHANGE_SUCCESS)         g_print("Playbin could not be played\n");     //g_assert(gst_element_set_state (GST_ELEMENT (player),GST_STATE_PLAYING)==GST_STATE_CHANGE_SUCCESS); }

The above function perform play,pause and Stop function respectively. The problem is, when I send the path of the file to the function start_playbin() I cannot change the path of the file after setting the pipeline only to ready. I have to make it 1) Ready 2)Pause or Play(cannot set state) 3)stop and then Play(set state success) the song.

Please help me. I don't get any errors if I set the pipeline to only ready but the program hangs. What could be the problem? Is there any specific sequence to be followed to setup a pipeline and set the path of the file?

回答1:

Please look at the examples shipped with gstreamer. A few points:

  • You need to set the state of the pipeline back to ready to be able to change the uri
  • State-changes are asynchronous. Please read about The GstBus and make use of it. In particullar don't attach to the bus after playing. Create your playbin pipeline and attach to the bus. Then you can go to PLAYING, the bus will inform you about when the playback started and when in finished (among other things).

Also consider using 1.0 for a new application, 0.10 is in maintenance mode.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!