Какой последовательности нужно придерживаться, чтобы воспроизвести песню с помощью gstreramer?

Я создаю музыкальный проигрыватель на основе gstreamer-0.10. Я могу успешно играть, но у меня возникают проблемы при изменении состояния конвейера. Я разместил код для инициализации и запуска конвейера ниже:

    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);
}

Приведенный выше код инициализирует конвейер gstreamer. Я использую 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) );
    }

Мне пришлось использовать условие if(i == TRUE) только потому, что конвейер не меняет состояние в первый раз.

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);
}

Вышеупомянутая функция выполняет функции воспроизведения, паузы и остановки соответственно. Проблема в том, что когда я отправляю путь к файлу в функцию start_playbin(), я не могу изменить путь к файлу после установки конвейера только на готовность. Я должен сделать это 1) Готов 2) Пауза или воспроизведение (невозможно установить состояние) 3) остановить, а затем воспроизвести (установить состояние успешно) песню.

Пожалуйста помогите. Я не получаю никаких ошибок, если я устанавливаю конвейер только в состояние готовности, но программа зависает. В чем может быть проблема? Есть ли какая-то конкретная последовательность, которой нужно следовать, чтобы настроить конвейер и указать путь к файлу?


person Harish Wali    schedule 29.08.2013    source источник


Ответы (1)


Посмотрите примеры, поставляемые с gstreamer. Несколько моментов:

  • Вам нужно вернуть конвейер в состояние готовности, чтобы иметь возможность изменить uri.
  • Изменения состояния асинхронны. Пожалуйста, прочитайте о GstBus и используйте его. В частности, не прикрепляйтесь к автобусу после игры. Создайте конвейер playbin и подключите его к шине. Затем вы можете перейти к PLAYING, шина сообщит вам, когда воспроизведение началось и когда закончилось (среди прочего).

Также рассмотрите возможность использования 1.0 для нового приложения, 0.10 находится в режиме обслуживания.

person ensonic    schedule 29.08.2013
comment
Привет, где мы можем найти эти примеры GStreamer? Спасибо. - person Santiago Villafuerte; 11.08.2015
comment
Каждый модуль git имеет поддиректории с тестами/примерами. - person ensonic; 16.08.2015