I am trying to develop a small music manager using GTK+ and GStreamer. However, I am currently unable to display the stream information (like artist, title, album, etc...) on the GtkTreeView.
I do not know if anyone here has any experience developing software like this. But the idea behind this software is that when you click File -> Open and then choosing a file from the GtkFileChooser, that music file will be imported into the GtkListStore.
Attached with this email is the source code of the program. I think the problem relates to either GstTagList I used or GtkListStore.
Thank you for helping me with this problem. I hope you guys have a good day!
Best regards,
Phong Cao
#include <gtk/gtk.h> #include <gst/gst.h> GtkTreeModel *rmodel; GtkListStore *rliststore; GtkWidget *rtreeview; GtkTreeIter iter; void print_one_tag(const GstTagList *list, const gchar *tag, gpointer user_data) { /* Import the song info (artist, title, album, etc...) into a GtkListStore called "rliststore" */ gint i, num; num = gst_tag_list_get_tag_size(list, tag); for (i = 0; i < num; ++i) { const GValue *val; val = gst_tag_list_get_value_index(list, tag, i); if (tag == "title") { gtk_list_store_set(rliststore, &iter, 1, g_value_get_string(val), -1); } else if (tag == "artist") { gtk_list_store_set(rliststore, &iter, 2, g_value_get_string(val), -1); } else if (tag == "album") { gtk_list_store_set(rliststore, &iter, 3, g_value_get_string(val), -1); } } } void import_media_activated(GtkMenuItem *item, GtkListStore *rliststore) { /* This is the call-back function for the File -> Open GtkMenuItem. It shows the user a GtkFileChooser to choose a music file and then import that file into the GtkListStore called "rliststore" using the print_one_tag function defined above */ GtkWidget *dialog; GSList *fileuris; GstElement *play; GstTagList *tags = NULL; GstMessage *msg; const gchar *tag; dialog = gtk_file_chooser_dialog_new("Import File(s)...", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); gint result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_OK) { fileuris = gtk_file_chooser_get_uris(GTK_FILE_CHOOSER(dialog)); } while (fileuris != NULL) { play = gst_element_factory_make("playbin", "play"); g_object_set(G_OBJECT(play), "uri", fileuris->data, NULL); gst_element_set_state(play, GST_STATE_PAUSED); msg = gst_bus_timed_pop_filtered(GST_ELEMENT_BUS(play), GST_CLOCK_TIME_NONE, GST_MESSAGE_TAG); gst_message_parse_tag(msg, &tags); /* gst_tag_list_foreach(tags, print_one_tag, liststore); */ gtk_list_store_append(rliststore, &iter); gst_tag_list_foreach(tags, print_one_tag, NULL); fileuris = fileuris->next; gst_message_unref(msg); } gtk_widget_destroy(dialog); gst_element_set_state(play, GST_STATE_NULL); gst_object_unref(play); } int main(int argc, char *argv[]) { /* This is the main program */ gtk_init(&argc, &argv); gst_init(&argc, &argv); /* Create (mainwindow) */ GtkWidget *mainwindow; mainwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(mainwindow), "Dingo Music Player"); /* Create the top menubar */ GtkWidget *file, *edit, *view, *playback, *help, *separator; GtkWidget *menubar, *filemenu, *editmenu, *viewmenu, *playmenu, *helpmenu; GtkWidget *importmedia, *importplaylist, *close, *quit; GtkWidget *selectall, *selectnone, *remove, *deldrive, *containfolder, *properties, *preferences; GtkWidget *showbrowser, *fullscreen, *showvideo, *showsub; GtkWidget *play, *stop, *next, *previous, *repeat, *repsingle, *repall, *repmenu, *repoff; GtkWidget *about; GtkAccelGroup *group; group = gtk_accel_group_new(); menubar = gtk_menu_bar_new(); file = gtk_menu_item_new_with_label("File"); edit = gtk_menu_item_new_with_label("Edit"); view = gtk_menu_item_new_with_label("View"); playback = gtk_menu_item_new_with_label("Play"); help = gtk_menu_item_new_with_label("Help"); filemenu = gtk_menu_new(); editmenu = gtk_menu_new(); viewmenu = gtk_menu_new(); playmenu = gtk_menu_new(); helpmenu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), filemenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit), editmenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), viewmenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(playback), playmenu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(help), helpmenu); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), file); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), edit); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), view); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), playback); gtk_menu_shell_append(GTK_MENU_SHELL(menubar), help); /* -- Create File Menu content -- */ importmedia = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, group); importplaylist = gtk_menu_item_new_with_label("Import Playlist..."); close = gtk_image_menu_item_new_from_stock(GTK_STOCK_CLOSE, group); quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, group); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), importmedia); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), importplaylist); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), close); gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), quit); /* -- Create Edit Menu content -- */ selectall = gtk_menu_item_new_with_label("Select All"); selectnone = gtk_menu_item_new_with_label("Select None"); remove = gtk_image_menu_item_new_from_stock(GTK_STOCK_REMOVE, group); deldrive = gtk_menu_item_new_with_label("Delete From Drive"); containfolder = gtk_menu_item_new_with_label("Open Containing Folder"); properties = gtk_image_menu_item_new_from_stock(GTK_STOCK_PROPERTIES, group); preferences = gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, group); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), selectall); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), selectnone); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), remove); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), deldrive); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), containfolder); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), properties); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(editmenu), preferences); /* -- Create View Menu content -- */ showsub = gtk_menu_item_new_with_label("Subtitles"); showvideo = gtk_check_menu_item_new_with_label("Show Video Area"); showbrowser = gtk_check_menu_item_new_with_label("Show Browser"); fullscreen = gtk_check_menu_item_new_with_label("Full Screen"); gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), showsub); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), showbrowser); gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), showvideo); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(viewmenu), fullscreen); /* -- Create Play Menu content -- */ play = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_PLAY, group); stop = gtk_check_menu_item_new_with_label("Stop After Finish"); next = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_NEXT, group); previous = gtk_image_menu_item_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS, group); repeat = gtk_menu_item_new_with_label("Repeat Mode"); repoff = gtk_radio_menu_item_new_with_label(NULL, "Turn Off Repeat"); repsingle = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(repoff), "Repeat Single"); repall = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(repoff), "Repeat All"); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), play); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), stop); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), next); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), previous); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), separator); gtk_menu_shell_append(GTK_MENU_SHELL(playmenu), repeat); repmenu = gtk_menu_new(); gtk_menu_item_set_submenu(GTK_MENU_ITEM(repeat), repmenu); gtk_menu_shell_append(GTK_MENU_SHELL(repmenu), repoff); gtk_menu_shell_append(GTK_MENU_SHELL(repmenu), repsingle); gtk_menu_shell_append(GTK_MENU_SHELL(repmenu), repall); /* -- Create Help Menu content -- */ about = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT, group); gtk_menu_shell_append(GTK_MENU_SHELL(helpmenu), about); /* Create (controlhbox) */ GtkWidget *playbutton, *nextbutton, *prevbutton, *searchbox; GtkWidget *repeatbutton, *fullbutton, *hscale, *seeklabel, *volumebutton; GtkWidget *seekvbox, *controlhbox; GtkAdjustment *progress, *volumeadj; playbutton = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(playbutton), gtk_image_new_from_stock(GTK_STOCK_MEDIA_PLAY, GTK_ICON_SIZE_SMALL_TOOLBAR)); gtk_button_set_relief(GTK_BUTTON(playbutton), GTK_RELIEF_NONE); prevbutton = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(prevbutton), gtk_image_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS, GTK_ICON_SIZE_SMALL_TOOLBAR)); gtk_button_set_relief(GTK_BUTTON(prevbutton), GTK_RELIEF_NONE); nextbutton = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(nextbutton), gtk_image_new_from_stock(GTK_STOCK_MEDIA_NEXT, GTK_ICON_SIZE_SMALL_TOOLBAR)); gtk_button_set_relief(GTK_BUTTON(nextbutton), GTK_RELIEF_NONE); repeatbutton = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(repeatbutton), gtk_image_new_from_stock(GTK_STOCK_REFRESH, GTK_ICON_SIZE_SMALL_TOOLBAR)); gtk_button_set_relief(GTK_BUTTON(repeatbutton), GTK_RELIEF_NONE); fullbutton = gtk_button_new(); gtk_button_set_image(GTK_BUTTON(fullbutton), gtk_image_new_from_stock(GTK_STOCK_FULLSCREEN, GTK_ICON_SIZE_SMALL_TOOLBAR)); gtk_button_set_relief(GTK_BUTTON(fullbutton), GTK_RELIEF_NONE); searchbox = gtk_entry_new(); seeklabel = gtk_label_new("0:00 - 0:00"); gtk_widget_set_size_request(seeklabel, 70, 15); progress = GTK_ADJUSTMENT(gtk_adjustment_new(0.00, 0.00, 0.00, 0.00, 0.00, 0.00)); hscale = gtk_hscale_new(progress); gtk_scale_set_draw_value(GTK_SCALE(hscale), FALSE); gtk_widget_set_size_request(hscale, 200, 20); volumebutton = gtk_volume_button_new(); volumeadj = GTK_ADJUSTMENT(gtk_adjustment_new(0.70, 0.00, 1.00, 0.01, 0.00, 0.00)); gtk_scale_button_set_adjustment(GTK_SCALE_BUTTON(volumebutton), volumeadj); seekvbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(seekvbox), hscale, TRUE, FALSE, 0); gtk_box_pack_start(GTK_BOX(seekvbox), seeklabel, FALSE, FALSE, 0); controlhbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(controlhbox), prevbutton, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(controlhbox), playbutton, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(controlhbox), nextbutton, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(controlhbox), seekvbox, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(controlhbox), volumebutton, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(controlhbox), searchbox, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(controlhbox), fullbutton, FALSE, FALSE, 0); gtk_box_pack_end(GTK_BOX(controlhbox), repeatbutton, FALSE, FALSE, 0); /* Create the left category tree view (lscroll) */ enum { COL_ICON = 0, COL_ACTION, NUM_LCOLS }; GtkCellRenderer *lrenderer; GtkTreeModel *lmodel; GtkTreeViewColumn *lcol; GtkWidget *ltreeview, *lscroll; GtkListStore *lliststore; GtkTreeIter liter; GdkPixbuf *licon; GError *error = NULL; ltreeview = gtk_tree_view_new(); lrenderer = gtk_cell_renderer_pixbuf_new(); lcol = gtk_tree_view_column_new_with_attributes("Icon", lrenderer, "pixbuf", COL_ICON, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(ltreeview), lcol); lrenderer = gtk_cell_renderer_text_new(); lcol = gtk_tree_view_column_new_with_attributes("Actions", lrenderer, "text", COL_ACTION, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(ltreeview), lcol); g_object_set(lcol, "width", 60, "expand", FALSE, NULL); lliststore = gtk_list_store_new(NUM_LCOLS, GDK_TYPE_PIXBUF, G_TYPE_STRING); licon = gdk_pixbuf_new_from_file("now-playing.png", &error); gtk_list_store_append(lliststore, &liter); gtk_list_store_set(lliststore, &liter, COL_ICON, licon, COL_ACTION, "Now Playing", -1); if (error) { g_warning("Could not load icon into tree view"); error = NULL; } licon = gdk_pixbuf_new_from_file("music.png", &error); gtk_list_store_append(lliststore, &liter); gtk_list_store_set(lliststore, &liter, COL_ICON, licon, COL_ACTION, "Music", -1); if (error) { g_warning("Could not load icon into tree view"); error = NULL; } licon = gdk_pixbuf_new_from_file("video.png", &error); gtk_list_store_append(lliststore, &liter); gtk_list_store_set(lliststore, &liter, COL_ICON, licon, COL_ACTION, "Videos", -1); if (error) { g_warning("Could not load icon into tree view"); error = NULL; } licon = gdk_pixbuf_new_from_file("playlist.png", &error); gtk_list_store_append(lliststore, &liter); gtk_list_store_set(lliststore, &liter, COL_ICON, licon, COL_ACTION, "Playlists", -1); if (error) { g_warning("Could not load icon into tree view"); } g_error_free(error); lmodel = GTK_TREE_MODEL(lliststore); gtk_tree_view_set_model(GTK_TREE_VIEW(ltreeview), lmodel); lscroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(lscroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(lscroll), ltreeview); gtk_widget_set_size_request(lscroll, 150, 600); g_object_unref(lmodel); /* Create empty song list (rscroll) */ enum { COL_STATUS = 0, COL_NAME, COL_ARTIST, COL_ALBUM, COL_TIME, NUM_RCOLS }; GtkTreeViewColumn *rcol; GtkCellRenderer *rrenderer; GtkWidget *rscroll; rtreeview = gtk_tree_view_new(); rrenderer = gtk_cell_renderer_pixbuf_new(); rcol = gtk_tree_view_column_new_with_attributes(" ", rrenderer, "pixbuf", COL_STATUS, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(rtreeview), rcol); g_object_set(rcol, "min-width", 24, NULL); rrenderer = gtk_cell_renderer_text_new(); rcol = gtk_tree_view_column_new_with_attributes("Name", rrenderer, "text", COL_NAME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(rtreeview), rcol); g_object_set(rcol, "min-width", 100, "reorderable", TRUE, "resizable", TRUE, "sort-indicator", TRUE, "expand", TRUE, NULL); rrenderer = gtk_cell_renderer_text_new(); rcol = gtk_tree_view_column_new_with_attributes("Artist", rrenderer, "text", COL_ARTIST, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(rtreeview), rcol); g_object_set(rcol, "min-width", 60, "reorderable", TRUE, "resizable", TRUE, "sort-indicator", TRUE, "expand", TRUE, NULL); rrenderer = gtk_cell_renderer_text_new(); rcol = gtk_tree_view_column_new_with_attributes("Album", rrenderer, "text", COL_ALBUM, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(rtreeview), rcol); g_object_set(rcol, "min-width", 60, "reorderable", TRUE, "resizable", TRUE, "sort-indicator", TRUE, "expand", TRUE, NULL); rrenderer = gtk_cell_renderer_text_new(); rcol = gtk_tree_view_column_new_with_attributes("Time", rrenderer, "text", COL_TIME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(rtreeview), rcol); g_object_set(rcol, "min-width", 70, "reorderable", TRUE, "resizable", TRUE, "sort-indicator", TRUE, "expand", FALSE, NULL); rliststore = gtk_list_store_new(NUM_RCOLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); rscroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(rscroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(rscroll), rtreeview); gtk_widget_set_size_request(rscroll, 675, 220); rmodel = GTK_TREE_MODEL(rliststore); gtk_tree_view_set_model(GTK_TREE_VIEW(rtreeview), rmodel); g_object_unref(rmodel); /* Create empty artist list (mscroll) */ GtkCellRenderer *mrenderer; GtkTreeModel *mmodel; GtkTreeViewColumn *mcol; GtkWidget *mtreeview, *mscroll; GtkTreeStore *mtreestore; mtreeview = gtk_tree_view_new(); mrenderer = gtk_cell_renderer_text_new(); mcol = gtk_tree_view_column_new_with_attributes("Lists", mrenderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(mtreeview), mcol); g_object_set(mcol, "min-width", 60, "reorderable", TRUE, "resizable", TRUE, "sort-indicator", TRUE, "width", 80, NULL); mtreestore = gtk_tree_store_new(1, G_TYPE_STRING); mmodel = GTK_TREE_MODEL(mtreestore); gtk_tree_view_set_model(GTK_TREE_VIEW(mtreeview), mmodel); mscroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(mscroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(mscroll), mtreeview); gtk_widget_set_size_request(mscroll, 190, 220); g_object_unref(mmodel); /* Create drawing area (videoarea) to display video */ GtkWidget *videoarea; videoarea = gtk_drawing_area_new(); gtk_widget_set_size_request(videoarea, 870, 375); /* Create bottom info bar (infolabel) */ GtkWidget *infolabel; infolabel = gtk_label_new("0 item - 0.00 minutes - 0.0 MB"); /* Create all the paned and pack widgets in */ GtkWidget *tophpaned, *vpaned, *subhpaned; subhpaned = gtk_hpaned_new(); gtk_paned_pack1(GTK_PANED(subhpaned), mscroll, FALSE, FALSE); gtk_paned_pack2(GTK_PANED(subhpaned), rscroll, TRUE, TRUE); gtk_widget_show_all(subhpaned); vpaned = gtk_vpaned_new(); gtk_paned_pack1(GTK_PANED(vpaned), videoarea, TRUE, TRUE); gtk_paned_pack2(GTK_PANED(vpaned), subhpaned, TRUE, TRUE); gtk_widget_show_all(vpaned); tophpaned = gtk_hpaned_new(); gtk_paned_pack1(GTK_PANED(tophpaned), lscroll, TRUE, TRUE); gtk_paned_pack2(GTK_PANED(tophpaned), vpaned, TRUE, TRUE); gtk_widget_show_all(tophpaned); /* Create topvbox and add paned + controlhbox in */ GtkWidget *topvbox; topvbox = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(topvbox), menubar, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(topvbox), controlhbox, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(topvbox), tophpaned, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(topvbox), infolabel, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(mainwindow), topvbox); gtk_window_add_accel_group(GTK_WINDOW(mainwindow), group); /* Connect Signals */ g_signal_connect(G_OBJECT(importmedia), "activate", G_CALLBACK(import_media_activated), (gpointer) rliststore); /* Show all widgets and run */ gtk_widget_show_all(mainwindow); gtk_main(); return 0; }
_______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list