歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 基於Gstreamer和Gtk的一個簡單的MP3播放器

基於Gstreamer和Gtk的一個簡單的MP3播放器

日期:2017/3/1 10:29:54   编辑:Linux編程

安裝Gstreamer插件,配置好環境

相關閱讀:一個基於Gstreamer的Linux下的簡單媒體播放器 http://www.linuxidc.com/Linux/2012-02/54980.htm

代碼如下:

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

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

[plain]
  1. ./myplayer

運行結果如圖:

Copyright © Linux教程網 All Rights Reserved