基于Gstreamer和Gtk的一个简单的MP3播放器

来源:互联网 发布:阿里云国际代购 编辑:程序博客网 时间:2024/05/30 23:26

安装Gstreamer插件,配置好环境,代码如下:

/*myplayer.c*/#include <gtk/gtk.h>#include <gst/gst.h>#include <signal.h>#include <string.h>GstElement *pipeline, *source,*decoder,*sink;GMainLoop *loop = NULL;  //暂停恢复开关按钮回调void toggle_button_callback(GtkWidget *widget,gpointer data){    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))    {gst_element_set_state(pipeline,GST_STATE_PAUSED);GstStateChangeReturn statechange;statechange = gst_element_set_state(pipeline, GST_STATE_PAUSED);g_print("Pause\n");    }    else    {g_print("pause was pressed\n");gst_element_set_state(pipeline,GST_STATE_PLAYING);g_print("恢复播放\n");    }}//play回调void callback_play(GtkWidget *widget,gpointer data){    if(!GST_IS_ELEMENT(pipeline))    {pipeline = gst_pipeline_new ("gst-player");source = gst_element_factory_make("filesrc","file-source");decoder = gst_element_factory_make("mad","mad-decoder");sink = gst_element_factory_make("autoaudiosink","audio-output");    }    g_print("play was pressed\n");    gst_element_set_state(pipeline,GST_STATE_PLAYING);    g_print("Running\n");    g_main_loop_run(loop);}//stop回调void callback_stop(GtkWidget *widget,gpointer data){    GtkWidget *tgbt=data;    g_print("stop was pressed\n");    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tgbt), FALSE);    gst_element_set_state(pipeline,GST_STATE_NULL);    g_main_loop_quit(loop); //退出循环// gst_object_unref(GST_OBJECT(pipeline));//不用销毁管道    g_print("Deleting pipeline\n");    g_print("stop\n");    }//关闭回调void delete_event(GtkWidget *widget,GdkEvent *event,gpointer data){       if(GST_IS_ELEMENT(pipeline))    {    g_main_loop_quit(loop);        gst_element_set_state(pipeline,GST_STATE_NULL);    }    gtk_main_quit();    g_print("quit was pressed\n");    g_print("quit\n");}//菜单基本回调static void print_hello(GtkWidget *w,gpointer data){    g_message("Hello\n");}GtkWidget *FileSelection;GtkWidget *ok_button;char str[100];//文件选择窗口回调//Openvoid OpenFile(GtkWidget *FileSelection,gpointer data){//先关闭文件    gst_element_set_state(pipeline,GST_STATE_NULL);    g_main_loop_quit(loop);     GtkWidget *widget =(GtkWidget*)data;    g_print("%s\n",gtk_file_selection_get_filename(GTK_FILE_SELECTION(widget)));    strcpy(str,gtk_file_selection_get_filename(GTK_FILE_SELECTION(widget)));    gtk_widget_destroy(widget);    g_object_set (G_OBJECT (source),"location",(char*)str,NULL);     g_print("fileselection was pressed\n");}//Cancelvoid callback_fileselection_cancel(GtkWidget *FileSelection,gpointer data){    GtkWidget * widget = (GtkWidget*)data;    gtk_widget_destroy(widget);    g_print("fileselection cancel was pressed\n");    g_print("fileselection quit\n");}//文件选择构件void button_event(GtkWidget *widget,gpointer *data){    FileSelection=gtk_file_selection_new("select file");    gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSelection),"*.mp3");    g_signal_connect(G_OBJECT(((GtkFileSelection*)FileSelection)->ok_button),"clicked",G_CALLBACK(OpenFile),FileSelection);    g_signal_connect(G_OBJECT(((GtkFileSelection*)FileSelection)->cancel_button),"clicked",G_CALLBACK(callback_fileselection_cancel),FileSelection);    gtk_widget_show(FileSelection);}//MENUstatic GtkItemFactoryEntry menu_items[]={    {"/_File",    NULL,    NULL,0,"<Branch>"},    {"/File/_Open","<control>O",   button_event,0,NULL},    {"/File/_Quit","<control>Q",   delete_event,0,NULL},    {"/_Help",    NULL,    NULL,0,"<Branch>"},    {"/_Help/About",NULL,    NULL,0,NULL},};void get_main_menu(GtkWidget *window,GtkWidget **menubar){    GtkItemFactory *item_factory;    GtkAccelGroup *accel_group;    gint nmenu_items=sizeof(menu_items)/sizeof(menu_items[0]);    accel_group=gtk_accel_group_new();    item_factory=gtk_item_factory_new(GTK_TYPE_MENU_BAR,"<main>",accel_group);    gtk_item_factory_create_items(item_factory,nmenu_items,menu_items,NULL);    gtk_window_add_accel_group(GTK_WINDOW(window),accel_group);    if(menubar)*menubar=gtk_item_factory_get_widget(item_factory,"<main>");}static gboolean bus_call(GstBus *bus,GstMessage *msg,gpointer data){    GMainLoop *loop=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 *err;    gst_message_parse_error(msg,&err,&debug);    g_free(debug);    g_print("Error: %s\n",err->message);    g_error_free(err);    g_main_loop_quit(loop);    break;}default:    break;    }    return TRUE;}static void new_pad(GstElement *element,GstPad *pad,gpointer data){    GstPad *sinkpad;    g_print ("Dynamic pad created,linking parser/decoder\n");    sinkpad=gst_element_get_pad(decoder,"sink");    gst_pad_link(pad,sinkpad);    gst_object_unref(sinkpad);}int main(int argc,char *argv[]){    GtkWidget *window;    GtkWidget *button;    GtkWidget *table;    GtkWidget *toggle_button;       gtk_init(&argc,&argv);    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);    gtk_window_set_title(GTK_WINDOW(window),"MP3 Player");    gtk_widget_set_size_request(GTK_WIDGET(window),300,60);    g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL);      //menu创建    GtkWidget *main_vbox;    GtkWidget *menubar;    main_vbox=gtk_vbox_new(FALSE,1);    gtk_container_add(GTK_CONTAINER(window),main_vbox);        get_main_menu(window,&menubar);    gtk_box_pack_start(GTK_BOX(main_vbox),menubar,FALSE,TRUE,0);    gtk_widget_show(menubar);    gtk_widget_show(main_vbox);          table = gtk_hbox_new(0, 3);gtk_box_pack_start_defaults(GTK_BOX(main_vbox), table);     gtk_widget_set_size_request(GTK_WIDGET(table),300,30);      button=gtk_button_new_with_label("播放");    g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback_play),(gpointer)"播放");    gtk_box_pack_start_defaults(GTK_BOX(table), button);    gtk_widget_show(button);            toggle_button=gtk_toggle_button_new_with_label("暂停/恢复");    g_signal_connect(G_OBJECT(toggle_button),"clicked",G_CALLBACK(toggle_button_callback),(gpointer)"暂停/恢复");   gtk_box_pack_start_defaults(GTK_BOX(table), toggle_button);    gtk_widget_show(toggle_button);    button=gtk_button_new_with_label("停止");    g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback_stop),(gpointer)toggle_button);    gtk_box_pack_start_defaults(GTK_BOX(table), button);    gtk_widget_show(button);    gtk_widget_show(table);    gtk_widget_show(window);//gst部分    GstBus *bus;//初始化    gst_init (&argc,&argv);    loop=g_main_loop_new(NULL,FALSE);/*//检查输入    if(argc!=2)    {g_print("Usage: %s<Mp3/Vorbis filename>\n",argv[0]);return -1;    } */   //创建元件    pipeline = gst_pipeline_new("audio-player");    source = gst_element_factory_make("filesrc","file-source");    decoder = gst_element_factory_make("mad","mad-decoder");sink = gst_element_factory_make("autoaudiosink","audio-output");//gst_element_factory_make("alsasink","alsa-output");       //异常处理   if(!pipeline||!source||!decoder||!sink)    {g_print("One element could not be created\n");return -1;    }    //得到 管道的消息总线    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));    //添加消息监视器    gst_bus_add_watch(bus,bus_call,loop);    gst_object_unref(bus);    //把组件添加到管道中.管道是一个特殊的组件,可以更好的让数据流动    gst_bin_add_many(GST_BIN(pipeline),source,decoder,sink,NULL);    //依次连接组件    gst_element_link_many(source,decoder,sink,NULL);        //开始播放    g_print("Running\n");                     g_signal_connect(decoder,"pad_added",G_CALLBACK(new_pad),NULL);        gtk_main();    return 0;}

终端里编译:

gcc -o myplayer myplayer.c `pkg-config --cflags --libs gtk+-2.0` `pkg-config --cflags --libs gstreamer-0.10`

运行:

 ./myplayer

运行结果如图: