使用gstreramer播放歌曲的顺序是什么? [英] What is the sequence to be followed to play a song using gstreramer?

查看:281
本文介绍了使用gstreramer播放歌曲的顺序是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个基于gstreamer-0.10的音乐播放器。我能够成功打球,但是当我改变管道状态时,我有问题。我已经发布了代码来初始化并启动以下管道:

  void start_gstreamer()
{
gst_init(0,NULL); //调用初始化gstreamer
time_val = 0; //设置为默认值
volume = 1.0; //将卷设置为默认值
player = gst_element_factory_make playbin2,player); //获取管道
equalizer = gst_element_factory_make(equalizer-10bands,equalizer); //获取10band均衡器
convert = gst_element_factory_make(audioconvert 兑换);
sink = gst_element_factory_make(autoaudiosink,audio_sink); //获取音频接收器
如果(!equalizer ||!convert ||!sink)//检查是否已创建元素
{
g_printerr(不是所有的元素都可以被创建。\);
// return -1;
}
// int i = 0;
/ *创建收件箱,添加元素并链接它们* /
bin = gst_bin_new(audio_sink_bin); //获取新bin
gst_bin_add_many(GST_BIN(bin)如果(!(gst_element_link_many(equalizer,convert,sink,NULL)))//链接所有元素
g_print(无法链接所有元素\\\
);
pad = gst_element_get_static_pad(均衡器,sink); //设置均衡器以吸收
ghost_pad = gst_ghost_pad_new(sink,pad); //获取一个鬼垫来吸收
gst_pad_set_active ghost_pad,TRUE);
gst_element_add_pad(bin,ghost_pad); //将垃圾箱添加到bin
gst_object_unref(pad); // unreference pad
gst_element_set_state(player,GST_STATE_READY); //将管道设置为就绪状态
// gst_element_set_state(player,GST_STATE_PAUSED);
/ *配置均衡器* /
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);
/ *将playbin2的音频接收器设置为我们的接收槽* /
g_object_set(GST_OBJECT(player),audio-sink,bin,NULL);
}

上面的代码将初始化gstreamer管道。我正在使用playbin2。

  void start_playbin(char * gargv1)
{
time_t rawtime;
struct tm * timeinfo;
static gboolean i = TRUE;


gchar * uri; //暂时保存路径
gchar * dname; //保存目录名称
time(& rawtime);
timeinfo = localtime(& rawtime);
printf(START:%s\\\
,asctime(timeinfo));

uri =(gchar *)g_malloc(sizeof(file://)+ strlen(gargv1)+ 1); //获取完整路径
strcpy(uri,file: //);
strcat(uri,gargv1); //添加文件路径
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); //设置管道中的播放文件路径
g_print(\\\
\\\
Playing%s\\\
,gargv1);
g_free(uri); //空闲路径
/ *开始播放* /

gst_element_set_state(GST_ELEMENT(player),GST_STATE_READY); //将管道设置为就绪状态
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\\\
,count ++);
i = FALSE;
}
else
play_playbin(); //开始播放
bus = gst_pipeline_get_bus(GST_PIPELINE(player)); //获取总线参考
gst_bus_add_watch GstBusFunc)cb_message,player); //添加要由进程事件监视的总线
g_object_unref(bus); // unference bus

time(& rawtime);
timeinfo = localtime(& rawtime);
printf(AFTER START:%s\\\
,asctime(timeinfo));
}

我不得不使用if(i == TRUE)条件,只是因为管道不会首次更改状态。

  void stop_playbin()
{
if (gst_element_set_state(GST_ELEMENT(player),GST_STATE_NULL)!= GST_STATE_CHANGE_SUCCESS)
g_print(Playbin不能停止\);
// 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 can不被暂停)
// 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( );
// g_assert(gst_element_set_state(GST_ELEMENT(player),GST_STATE_PLAYING)== GST_STATE_CHANGE_SUCCESS);
}

上述功能分别执行播放,暂停和停止功能。问题是,当我将文件的路径发送到函数 start_playbin()在将管道设置好后,无法更改文件的路径。我必须使它
1)准备
2)暂停或播放(不能设置状态)
3)停止
然后播放(设置状态成功)歌曲。 p>

请帮助我。如果我将管道设置为只准备但程序挂起,我不会收到任何错误。可能是什么问题呢?要设置流水线并设置文件的路径是否有特定的顺序?

解决方案

请查看gstreamer随附的示例。几点:




  • 您需要设置管道的状态,以便能够更改uri

  • 状态更改是异步的。请阅读关于GstBus并使用它。在游戏中不要附加到公共汽车上。创建你的播放管道并附加在总线上。然后,您可以去玩PLAYING,公共汽车将通知您播放开始和完成时间(包括其他事情)。



还要考虑使用1.0作为新的应用程序,0.10是处于维护模式。


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?

解决方案

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.

这篇关于使用gstreramer播放歌曲的顺序是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆