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


安装Gstreamer插件,配置好环境

相关阅读:一个基于Gstreamer的Linux下的简单媒体播放器

代码如下:

[cpp]
  1. /*myplayer.c*/  
  2. #include <gtk/gtk.h>   
  3. #include <gst/gst.h>   
  4. #include <signal.h>   
  5. #include <string.h>   
  6.   
  7. GstElement *pipeline, *source,*decoder,*sink;  
  8. GMainLoop *loop = NULL;    
  9.   
  10. //暂停恢复开关按钮回调   
  11. void toggle_button_callback(GtkWidget *widget,gpointer data)  
  12. {  
  13.     if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))  
  14.     {  
  15.     gst_element_set_state(pipeline,GST_STATE_PAUSED);  
  16.     GstStateChangeReturn statechange;  
  17.     statechange = gst_element_set_state(pipeline, GST_STATE_PAUSED);  
  18.     g_print("Pause\n");  
  19.     }  
  20.     else  
  21.     {  
  22.     g_print("pause was pressed\n");  
  23.     gst_element_set_state(pipeline,GST_STATE_PLAYING);  
  24.     g_print("恢复播放\n");  
  25.     }  
  26. }  
  27.   
  28. //play回调   
  29. void callback_play(GtkWidget *widget,gpointer data)  
  30. {  
  31.     if(!GST_IS_ELEMENT(pipeline))  
  32.     {  
  33.     pipeline = gst_pipeline_new ("gst-player");  
  34.     source = gst_element_factory_make("filesrc","file-source");   
  35.     decoder = gst_element_factory_make("mad","mad-decoder");  
  36.     sink = gst_element_factory_make("autoaudiosink","audio-output");  
  37.     }  
  38.     g_print("play was pressed\n");  
  39.     gst_element_set_state(pipeline,GST_STATE_PLAYING);  
  40.     g_print("Running\n");  
  41.     g_main_loop_run(loop);  
  42. }  
  43.   
  44. //stop回调   
  45. void callback_stop(GtkWidget *widget,gpointer data)  
  46. {  
  47.     GtkWidget *tgbt=data;  
  48.     g_print("stop was pressed\n");  
  49.     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tgbt), FALSE);  
  50.   
  51.     gst_element_set_state(pipeline,GST_STATE_NULL);  
  52.     g_main_loop_quit(loop); //退出循环   
  53.     // gst_object_unref(GST_OBJECT(pipeline));//不用销毁管道   
  54.     g_print("Deleting pipeline\n");  
  55.     g_print("stop\n");      
  56. }  
  57.   
  58. //关闭回调   
  59. void delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)  
  60. {     
  61.     if(GST_IS_ELEMENT(pipeline))  
  62.     {  
  63.     g_main_loop_quit(loop);  
  64.         gst_element_set_state(pipeline,GST_STATE_NULL);  
  65.     }  
  66.     gtk_main_quit();  
  67.     g_print("quit was pressed\n");  
  68.     g_print("quit\n");  
  69. }  
  70.   
  71. //菜单基本回调   
  72. static void print_hello(GtkWidget *w,gpointer data)  
  73. {  
  74.     g_message("Hello\n");  
  75. }  
  76.   
  77. GtkWidget *FileSelection;  
  78. GtkWidget *ok_button;  
  79.   
  80. char str[100];  
  81.   
  82. //文件选择窗口回调   
  83. //Open   
  84. void OpenFile(GtkWidget *FileSelection,gpointer data)  
  85. {  
  86. //先关闭文件   
  87.     gst_element_set_state(pipeline,GST_STATE_NULL);  
  88.     g_main_loop_quit(loop);   
  89.   
  90.     GtkWidget *widget =(GtkWidget*)data;  
  91.     g_print("%s\n",gtk_file_selection_get_filename(GTK_FILE_SELECTION(widget)));  
  92.   
  93.     strcpy(str,gtk_file_selection_get_filename(GTK_FILE_SELECTION(widget)));  
  94.     gtk_widget_destroy(widget);  
  95.     g_object_set (G_OBJECT (source),"location",(char*)str,NULL);   
  96.     g_print("fileselection was pressed\n");  
  97. }  
  98. //Cancel   
  99. void callback_fileselection_cancel(GtkWidget *FileSelection,gpointer data)  
  100. {  
  101.     GtkWidget * widget = (GtkWidget*)data;  
  102.     gtk_widget_destroy(widget);  
  103.     g_print("fileselection cancel was pressed\n");  
  104.     g_print("fileselection quit\n");  
  105. }  
  106.   
  107. //文件选择构件   
  108. void button_event(GtkWidget *widget,gpointer *data)  
  109. {  
  110.     FileSelection=gtk_file_selection_new("select file");  
  111.     gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSelection),"*.mp3");  
  112.     g_signal_connect(G_OBJECT(((GtkFileSelection*)FileSelection)->ok_button),"clicked",G_CALLBACK(OpenFile),FileSelection);  
  113.     g_signal_connect(G_OBJECT(((GtkFileSelection*)FileSelection)->cancel_button),"clicked",G_CALLBACK(callback_fileselection_cancel),FileSelection);               
  114.     gtk_widget_show(FileSelection);  
  115. }  
  116.   
  117. //MENU   
  118. static GtkItemFactoryEntry menu_items[]={  
  119.     {   "/_File",       NULL,           NULL,0,"<Branch>"},  
  120.     {   "/File/_Open",  "<control>O",   button_event,0,NULL},  
  121.     {   "/File/_Quit",  "<control>Q",   delete_event,0,NULL},  
  122.     {   "/_Help",       NULL,           NULL,0,"<Branch>"},  
  123.     {   "/_Help/About", NULL,           NULL,0,NULL},  
  124. };  
  125.   
  126. void get_main_menu(GtkWidget *window,GtkWidget **menubar)  
  127. {  
  128.     GtkItemFactory *item_factory;  
  129.     GtkAccelGroup *accel_group;  
  130.     gint nmenu_items=sizeof(menu_items)/sizeof(menu_items[0]);  
  131.     accel_group=gtk_accel_group_new();  
  132.     item_factory=gtk_item_factory_new(GTK_TYPE_MENU_BAR,"<main>",accel_group);  
  133.     gtk_item_factory_create_items(item_factory,nmenu_items,menu_items,NULL);  
  134.     gtk_window_add_accel_group(GTK_WINDOW(window),accel_group);  
  135.     if(menubar)  
  136.     *menubar=gtk_item_factory_get_widget(item_factory,"<main>");  
  137. }  
  138.   
  139. static gboolean bus_call(GstBus *bus,GstMessage *msg,gpointer data)  
  140. {  
  141.     GMainLoop *loop=data;  
  142.     switch (GST_MESSAGE_TYPE(msg))  
  143.     {  
  144.     case GST_MESSAGE_EOS:  
  145.         g_print("End-of_stream\n");  
  146.         g_main_loop_quit(loop);  
  147.         break;  
  148.     case GST_MESSAGE_ERROR:  
  149.     {  
  150.         gchar *debug;  
  151.         GError *err;  
  152.         gst_message_parse_error(msg,&err,&debug);  
  153.         g_free(debug);  
  154.         g_print("Error: %s\n",err->message);  
  155.         g_error_free(err);  
  156.         g_main_loop_quit(loop);  
  157.         break;  
  158.     }  
  159.     default:  
  160.         break;  
  161.     }  
  162.     return TRUE;  
  163. }  
  164.   
  165. static void new_pad(GstElement *element,GstPad *pad,gpointer data)  
  166. {  
  167.     GstPad *sinkpad;  
  168.     g_print ("Dynamic pad created,linking parser/decoder\n");  
  169.     sinkpad=gst_element_get_pad(decoder,"sink");  
  170.     gst_pad_link(pad,sinkpad);  
  171.     gst_object_unref(sinkpad);  
  172. }  
  173.   
  174. int main(int argc,char *argv[])  
  175. {  
  176.     GtkWidget *window;  
  177.     GtkWidget *button;  
  178.     GtkWidget *table;  
  179.     GtkWidget *toggle_button;  
  180.      
  181.     gtk_init(&argc,&argv);  
  182.   
  183.     window=gtk_window_new(GTK_WINDOW_TOPLEVEL);  
  184.     gtk_window_set_title(GTK_WINDOW(window),"MP3 Player");  
  185.     gtk_widget_set_size_request(GTK_WIDGET(window),300,60);  
  186.     g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(delete_event),NULL);        
  187.   
  188.     //menu创建   
  189.     GtkWidget *main_vbox;  
  190.     GtkWidget *menubar;  
  191.     main_vbox=gtk_vbox_new(FALSE,1);  
  192.     gtk_container_add(GTK_CONTAINER(window),main_vbox);  
  193.       
  194.     get_main_menu(window,&menubar);  
  195.     gtk_box_pack_start(GTK_BOX(main_vbox),menubar,FALSE,TRUE,0);  
  196.     gtk_widget_show(menubar);  
  197.     gtk_widget_show(main_vbox);     
  198.      
  199.     table = gtk_hbox_new(0, 3);  
  200.     gtk_box_pack_start_defaults(GTK_BOX(main_vbox), table);       
  201.     gtk_widget_set_size_request(GTK_WIDGET(table),300,30);    
  202.   
  203.     button=gtk_button_new_with_label("播放");  
  204.     g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback_play),(gpointer)"播放");  
  205.     gtk_box_pack_start_defaults(GTK_BOX(table), button);  
  206.     gtk_widget_show(button);  
  207.           
  208.     toggle_button=gtk_toggle_button_new_with_label("暂停/恢复");  
  209.     g_signal_connect(G_OBJECT(toggle_button),"clicked",G_CALLBACK(toggle_button_callback),(gpointer)"暂停/恢复");  
  210.     gtk_box_pack_start_defaults(GTK_BOX(table), toggle_button);  
  211.     gtk_widget_show(toggle_button);  
  212.   
  213.     button=gtk_button_new_with_label("停止");  
  214.     g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback_stop),(gpointer)toggle_button);  
  215.     gtk_box_pack_start_defaults(GTK_BOX(table), button);  
  216.     gtk_widget_show(button);  
  217.   
  218.     gtk_widget_show(table);  
  219.     gtk_widget_show(window);  
  220.   
  221.     //gst部分   
  222.     GstBus *bus;  
  223.   
  224.     //初始化   
  225.     gst_init (&argc,&argv);  
  226.     loop=g_main_loop_new(NULL,FALSE);  
  227. /* 
  228. //检查输入 
  229.     if(argc!=2) 
  230.     { 
  231.     g_print("Usage: %s<Mp3/Vorbis filename>\n",argv[0]); 
  232.     return -1; 
  233.     } 
  234.  */     
  235.     //创建元件   
  236.     pipeline = gst_pipeline_new("audio-player");  
  237.     source = gst_element_factory_make("filesrc","file-source");  
  238.     decoder = gst_element_factory_make("mad","mad-decoder");  
  239.     sink = gst_element_factory_make("autoaudiosink","audio-output");  
  240.     //gst_element_factory_make("alsasink","alsa-output");   
  241.          
  242.     //异常处理   
  243.    if(!pipeline||!source||!decoder||!sink)  
  244.     {  
  245.     g_print("One element could not be created\n");  
  246.     return -1;  
  247.     }  
  248.       
  249.     //得到 管道的消息总线   
  250.     bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));  
  251.     //添加消息监视器 www.bkjia.com  
  252.     gst_bus_add_watch(bus,bus_call,loop);  
  253.     gst_object_unref(bus);  
  254.     //把组件添加到管道中.管道是一个特殊的组件,可以更好的让数据流动   
  255.     gst_bin_add_many(GST_BIN(pipeline),source,decoder,sink,NULL);  
  256.     //依次连接组件   
  257.     gst_element_link_many(source,decoder,sink,NULL);  
  258.       
  259.     //开始播放   
  260.     g_print("Running\n");                   
  261.     g_signal_connect(decoder,"pad_added",G_CALLBACK(new_pad),NULL);  
  262.       
  263.     gtk_main();  
  264.     return 0;  
  265. }  
终端里编译:

[plain]
  1. gcc -o myplayer myplayer.c `pkg-config --cflags --libs gtk+-2.0` `pkg-config --cflags --libs gstreamer-0.10`  
运行:

[plain]
  1. ./myplayer  

运行结果如图:

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

相关内容