4 * Created on: 2009-10-22
10 #include <hildon/hildon.h>
11 #include "resource_utils.h"
13 /****************************************************************************
14 * Simple playing functions
16 /** TODO: Get rid of global variable pipeline */
17 static GstElement *pipeline = NULL;
18 static GList* tracklist = 0;
19 static GList* tracklist_item = 0;
22 GtkWidget* playing_label;
23 guint playing_label_timer = 0;
24 GtkToolButton* play_pause_button;
47 { "player_prev_light.png", "prev", CMD_PREV, NULL },
48 { "player_play_light.png", "play", CMD_PLAY, NULL },
49 { "player_pause_light.png", "pause", CMD_PAUSE, NULL },
50 { "player_stop_light.png", "stop", CMD_STOP, NULL },
51 { "player_next_light.png", "next", CMD_NEXT, NULL }
58 void update_toolbar();
60 static void handle_eos(GstBus * bus, GstMessage * message, gpointer * appdata) {
66 static void handle_error(GstBus * bus, GstMessage * msg, gpointer * appdata) {
72 gst_message_parse_error (msg, &err, &dbg);
73 g_debug("player: ERROR: %s\nDEBUG: %s",err->message,dbg);
75 hildon_banner_show_informationf(NULL,NULL,"Error: %s",err->message);
78 static void handle_buffering(GstBus * bus, GstMessage * msg, gpointer * appdata) {
81 gst_message_parse_buffering (msg, &percent);
84 gchar* text = g_strdup_printf("Buffering %d%%", percent);
85 gtk_label_set_text(GTK_LABEL(playing_label),text);
90 static void handle_any(GstBus * bus, GstMessage * msg, gchar *name) {
91 g_debug("handle_%s",name);
92 if(g_strcmp0(name,"duration")==0) {
95 gst_message_parse_duration(msg, &format, &duration);
96 g_debug("duration %d: %Ld",format,duration);
100 static gboolean handle_timer(gpointer* ptr) {
102 GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
103 gboolean res = gst_element_query(pipeline, query);
107 gst_query_parse_position(query, &format, &cur);
108 int sec = cur / GST_SECOND;
109 gchar *text = g_strdup_printf("%u:%02u:%02u", sec / 60 / 60, (sec / 60) % 60, sec % 60);
110 gtk_label_set_text(GTK_LABEL(playing_label), text);
113 gst_query_unref(query);
118 void play_track(Track* track) {
120 gst_element_set_state(pipeline, GST_STATE_NULL);
121 g_object_unref(GST_OBJECT(pipeline));
125 hildon_banner_show_informationf(NULL,NULL,"Playing %s by %s",track->name,track->artist_name);
128 GstElement *src, *decoder, *sink;
129 pipeline = gst_pipeline_new(NULL);
130 src = gst_element_factory_make("souphttpsrc", NULL);
131 g_object_set(G_OBJECT(src), "location", track->stream, NULL);
132 decoder = gst_element_factory_make("decodebin", NULL);
133 sink = gst_element_factory_make("alsasink", NULL);
134 gst_bin_add_many(GST_BIN(pipeline), src, decoder, sink, NULL);
135 gst_element_link_many(src, decoder, sink, NULL);
137 pipeline = gst_element_factory_make("playbin2", NULL);
138 g_object_set(G_OBJECT(pipeline), "uri", track->stream, NULL);
142 /* setup message handling */
143 GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline));
144 gst_bus_add_signal_watch_full(bus, G_PRIORITY_HIGH);
145 g_signal_connect(bus, "message::error", (GCallback) handle_error, NULL);
146 g_signal_connect(bus, "message::eos", (GCallback) handle_eos, NULL);
147 g_signal_connect(bus, "message::buffering", (GCallback) handle_buffering, NULL);
148 g_signal_connect(bus, "message::duration", (GCallback) handle_any, "duration");
149 gst_object_unref(GST_OBJECT(bus));
151 if(!playing_label_timer) {
152 playing_label_timer = gdk_threads_add_timeout_seconds(1, (GSourceFunc)handle_timer, NULL);
155 g_debug("Playing %s",track->stream);
156 gst_element_set_state(pipeline, GST_STATE_PLAYING);
161 if (tracklist_item->data != track) {
162 tracklist_item = g_list_first(tracklist);
163 while (tracklist_item && tracklist_item->data != track) {
164 tracklist_item = g_list_next(tracklist_item);
170 hildon_banner_show_information(NULL,NULL,"Paused");
172 gst_element_set_state(pipeline,GST_STATE_PAUSED);
179 void resume_track() {
180 gst_element_set_state(pipeline, GST_STATE_PLAYING);
188 hildon_banner_show_information(NULL,NULL,"Stopped");
190 gst_element_set_state(pipeline, GST_STATE_NULL);
191 g_object_unref(GST_OBJECT(pipeline));
200 if (!tracklist_item) return;
202 tracklist_item = g_list_next(tracklist_item);
203 if (!tracklist_item) {
204 tracklist_item = g_list_first(tracklist);
206 play_track(tracklist_item->data);
210 if (!tracklist_item) return;
212 tracklist_item = g_list_previous(tracklist_item);
213 if (!tracklist_item) {
214 tracklist_item = g_list_last(tracklist);
216 play_track(tracklist_item->data);
220 void on_clicked(GtkToolButton *toolbutton, gint cmd) {
228 if (tracklist_item) {
229 play_track(tracklist_item->data);
249 void update_toolbar() {
250 if (state == PLAYING) {
251 gtk_tool_button_set_icon_widget(play_pause_button, toolbar_data[CMD_PAUSE].icon);
252 gtk_tool_button_set_label(play_pause_button, toolbar_data[CMD_PAUSE].label);
253 gtk_widget_show_all(GTK_WIDGET(play_pause_button));
255 else if (state == PAUSED) {
256 gtk_tool_button_set_icon_widget(play_pause_button, toolbar_data[CMD_PLAY].icon);
257 gtk_tool_button_set_label(play_pause_button, toolbar_data[CMD_PLAY].label);
258 gtk_widget_show_all(GTK_WIDGET(play_pause_button));
262 GtkWidget* player_toolbar_create() {
264 GtkToolItem *toolitem;
267 /* Create a toolbar */
268 toolbar = gtk_toolbar_new();
270 /* Add items to the toolbar */
271 for (i = 0; i < G_N_ELEMENTS(toolbar_data); i++) {
272 toolbar_data[i].icon = resource_get_image(toolbar_data[i].image);
273 g_object_ref(toolbar_data[i].icon);
275 if (i != CMD_PAUSE) {
276 toolitem = gtk_tool_button_new(toolbar_data[i].icon, toolbar_data[i].label);
277 g_signal_connect (G_OBJECT (toolitem), "clicked", G_CALLBACK (on_clicked), (gpointer) toolbar_data[i].cmd);
278 gtk_widget_show_all(GTK_WIDGET(toolitem));
279 gtk_toolbar_insert(GTK_TOOLBAR (toolbar), toolitem, pos++);
282 play_pause_button = GTK_TOOL_BUTTON(toolitem);
286 toolitem = gtk_separator_tool_item_new();
287 gtk_tool_item_set_expand(toolitem,TRUE);
288 gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
289 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),toolitem,pos++);
291 playing_label= gtk_label_new("");
292 toolitem = gtk_tool_button_new(NULL, NULL);
293 gtk_widget_set_usize((GtkWidget*)playing_label, 200, -1);
294 gtk_tool_button_set_label_widget(GTK_TOOL_BUTTON(toolitem), playing_label);
295 gtk_toolbar_insert(GTK_TOOLBAR(toolbar),toolitem,pos++);
297 gtk_widget_show_all(GTK_WIDGET(toolbar));
303 void player_set_track_list(GList* track_list) {
304 g_debug("player_set_track_list length:%d",g_list_length(track_list));
307 track_list_free(tracklist);
311 tracklist = track_list;
312 tracklist_item = g_list_first(tracklist);