Guest

Alvin Delagon

By: a guest on Apr 12th, 2009  |  syntax: C  |  size: 5.28 KB  |  hits: 195  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. /*
  2.  * File: gstplayer.c
  3.  * Author: Alvin Delagon
  4.  * Summary: gstreamer based mp3 player with GTK+ frontend
  5.  */
  6.  
  7. #include <gtk/gtk.h>
  8. #include <glade/glade.h>
  9. #include <gst/gst.h>
  10.  
  11. GstElement *pipeline, *filesrc, *mad, *audioconvert, *alsasink;
  12. GtkListStore *store;
  13.  
  14. enum
  15.   {
  16.     COL_NAME = 0,
  17.     NUM_COLS
  18.   };
  19.  
  20. static gboolean
  21. cb_bus_messages (GstBus *bus, GstMessage *message, gpointer data)
  22. {
  23.   switch (GST_MESSAGE_TYPE (message))
  24.     {
  25.     case GST_MESSAGE_ERROR:
  26.       {
  27.         GError *err;
  28.         gchar *debug;
  29.         gst_message_parse_error (message, &err, &debug);
  30.         g_print ("Got Bus Error: %s\n", err->message);
  31.         g_error_free (err);
  32.         g_free (debug);
  33.         gtk_main_quit ();
  34.         break;
  35.       }
  36.     case GST_MESSAGE_TAG:
  37.       {
  38.         /* For some reasons, this is not working properly */
  39.         GstTagList *tags;
  40.         gchar *artist;
  41.         gst_message_parse_tag (message, &tags);
  42.         gst_tag_list_get_string (tags, GST_TAG_ARTIST, &artist);
  43.         g_print ("File Tags:\n");
  44.         g_print ("Title: %s\n", artist);
  45.         break;
  46.       }
  47.     case GST_MESSAGE_EOS:
  48.       {
  49.         g_print ("End-of-stream. Playing next file...\n");
  50.         break;
  51.       }
  52.     default:
  53.       break;
  54.     }
  55.   return TRUE;
  56. }
  57.  
  58. void cb_add (GtkWidget *widget, GtkWidget *list)
  59. {
  60.   GtkWindow *window;
  61.   GtkWidget *dialog;
  62.   dialog = gtk_file_chooser_dialog_new ("Add Item To Playlist",
  63.                                         window,
  64.                                         GTK_FILE_CHOOSER_ACTION_OPEN,
  65.                                         GTK_STOCK_CANCEL,
  66.                                         GTK_RESPONSE_CANCEL,
  67.                                         GTK_STOCK_ADD,
  68.                                         GTK_RESPONSE_ACCEPT,
  69.                                         NULL);
  70.   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
  71.     {
  72.       gchar *filename;
  73.       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
  74.       GtkTreeModel *model;
  75.       GtkTreeIter iter;
  76.       gtk_tree_view_set_model (GTK_TREE_VIEW (list), NULL);
  77.       gtk_list_store_append (store, &iter);
  78.       gtk_list_store_set (store, &iter, COL_NAME, filename, -1);
  79.       model = GTK_TREE_MODEL (store);
  80.       gtk_tree_view_set_model (GTK_TREE_VIEW (list), model);
  81.       gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
  82.       g_object_set (filesrc, "location", filename, NULL);
  83.       gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
  84.       g_free (filename);
  85.     }
  86.   gtk_widget_destroy (dialog);
  87. }
  88.  
  89. void cb_row_activated (GtkWidget *widget, gpointer gdata)
  90. {
  91.   g_print ("I Was activated!\n");
  92. }
  93.  
  94. void cb_exit (GtkWidget *widget, gpointer gdata)
  95. {
  96.   gtk_main_quit ();
  97. }
  98.  
  99. static GtkWidget *
  100. init_playlist (GladeXML *ui)
  101. {
  102.   GtkCellRenderer *renderer;
  103.   GtkWidget *view;
  104.   view = glade_xml_get_widget (ui, "PlayList");
  105.   renderer = gtk_cell_renderer_text_new ();
  106.   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view),
  107.                                               -1,
  108.                                               "Playlist",
  109.                                               renderer,
  110.                                               "text", COL_NAME,
  111.                                               NULL);
  112.   store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING, G_TYPE_UINT);
  113.   gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (store));
  114.   return (view);
  115. }
  116.  
  117. int main (int argc, char *argv[])
  118. {
  119.   GladeXML *ui;
  120.   GtkWidget *widget;
  121.   GtkWidget *playlist;
  122.   GstBus *bus;
  123.   gst_init (&argc, &argv); // gst_init should be called first before gtk_init
  124.   gtk_init (&argc, &argv);
  125.   ui = glade_xml_new ("data/gstplayer.glade", NULL, NULL);
  126.   playlist = init_playlist (ui);
  127.                                                
  128.   filesrc = gst_element_factory_make ("filesrc", "source");
  129.   mad = gst_element_factory_make ("mad", "decoder");
  130.   audioconvert = gst_element_factory_make ("audioconvert", "converter");
  131.   alsasink = gst_element_factory_make ("alsasink", "sink");
  132.   if (!filesrc || !mad || !audioconvert || !alsasink)
  133.     {
  134.       g_print ("Failed to create 1 element");
  135.       return -1;
  136.     }  
  137.   pipeline = gst_pipeline_new ("mp3-pipeline");
  138.   gst_bin_add_many (GST_BIN (pipeline), filesrc, mad, audioconvert, alsasink, NULL);
  139.   if (!gst_element_link_many (filesrc, mad, audioconvert, alsasink, NULL))
  140.     g_warning ("Failed to link elements!\n");
  141.  
  142.   /* GTK+ Signal connectors */
  143.   widget = glade_xml_get_widget (ui, "MainWindow");
  144.   g_signal_connect (G_OBJECT (widget),
  145.                     "delete_event",
  146.                     G_CALLBACK (cb_exit),
  147.                     NULL);
  148.   widget = glade_xml_get_widget (ui, "AddButton");
  149.   g_signal_connect (G_OBJECT (widget),
  150.                     "clicked",
  151.                     G_CALLBACK (cb_add),
  152.                     playlist);
  153.   g_signal_connect (G_OBJECT (playlist),
  154.                     "row-activated",
  155.                     G_CALLBACK (cb_row_activated),
  156.                     NULL);
  157.  
  158.   /* GStreamer Signal connectors */
  159.   bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
  160.   gst_bus_add_signal_watch (bus);
  161.   gst_bus_add_watch (bus, cb_bus_messages, NULL);
  162.   g_object_unref (bus);
  163.  
  164.   gtk_main ();
  165.   return 0;
  166. }