mp3splt-gtk
|
00001 /********************************************************** 00002 * 00003 * mp3splt-gtk -- utility based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright: (C) 2005-2011 Alexandru Munteanu 00007 * Contact: io_fx@yahoo.fr 00008 * 00009 * from BMP to Audacious patch from Roberto Neri - 2007,2008 00010 * 00011 * http://mp3splt.sourceforge.net/ 00012 * 00013 *********************************************************/ 00014 00015 /********************************************************** 00016 * 00017 * This program is free software; you can redistribute it and/or 00018 * modify it under the terms of the GNU General Public License 00019 * as published by the Free Software Foundation; either version 2 00020 * of the License, or (at your option) any later version. 00021 * 00022 * This program is distributed in the hope that it will be useful, 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 * GNU General Public License for more details. 00026 * 00027 * You should have received a copy of the GNU General Public License 00028 * along with this program; if not, write to the Free Software 00029 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00030 * USA. 00031 * 00032 *********************************************************/ 00033 00034 /*!******************************************************* 00035 * \file 00036 * Control the gstreamer framework 00037 * 00038 * this file has functions to control the 'internal' 00039 + gstreamer player 00040 *********************************************************/ 00041 00042 #include <stdlib.h> 00043 #include <gtk/gtk.h> 00044 #include <glib/gi18n.h> 00045 #include <time.h> 00046 #include <unistd.h> 00047 #include <string.h> 00048 00049 #ifndef NO_GSTREAMER 00050 #include <gst/gst.h> 00051 #include "gstreamer_control.h" 00052 #endif 00053 00054 #include "player.h" 00055 #include "main_win.h" 00056 #include "utilities.h" 00057 #include "player_tab.h" 00058 #include "mp3splt-gtk.h" 00059 00060 extern int selected_player; 00061 00062 #ifndef NO_GSTREAMER 00063 00064 const gchar *song_artist = NULL; 00065 const gchar *song_title = NULL; 00066 gint rate = 0; 00067 00068 GstElement *play = NULL; 00069 GstBus *bus = NULL; 00070 gint _gstreamer_is_running = FALSE; 00071 extern GtkWidget *playlist_box; 00072 extern GtkWidget *player_vbox; 00073 00074 extern void add_playlist_file(const gchar *name); 00075 00077 static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) 00078 { 00079 switch (GST_MESSAGE_TYPE(msg)) 00080 { 00081 case GST_MESSAGE_ERROR: 00082 { 00083 gchar *debug; 00084 GError *error; 00085 00086 gst_message_parse_error (msg, &error, &debug); 00087 g_free(debug); 00088 00089 gchar *message = NULL; 00090 if (error->message != NULL) 00091 { 00092 gint malloc_size = strlen(error->message) + 20; 00093 message = malloc(sizeof(char) * malloc_size); 00094 if (message) 00095 { 00096 memset(message,'\0',malloc_size); 00097 g_snprintf(message, malloc_size,_("gstreamer error: %s"),error->message); 00098 00099 enter_threads(); 00100 put_status_message(message); 00101 exit_threads(); 00102 00103 g_free(message); 00104 } 00105 } 00106 g_error_free(error); 00107 break; 00108 } 00109 case GST_MESSAGE_WARNING: 00110 { 00111 gchar *debug; 00112 GError *error; 00113 00114 gst_message_parse_warning(msg, &error, &debug); 00115 g_free(debug); 00116 00117 gchar *message = NULL; 00118 if (error->message != NULL) 00119 { 00120 gint malloc_size = strlen(error->message) + 20; 00121 message = malloc(sizeof(char) * malloc_size); 00122 if (message) 00123 { 00124 memset(message,'\0',malloc_size); 00125 g_snprintf(message, malloc_size,_("Warning: %s"),error->message); 00126 00127 enter_threads(); 00128 put_status_message(message); 00129 exit_threads(); 00130 00131 g_free(message); 00132 } 00133 } 00134 g_error_free (error); 00135 break; 00136 } 00137 case GST_MESSAGE_INFO: 00138 { 00139 gchar *debug; 00140 GError *error; 00141 00142 gst_message_parse_info(msg, &error, &debug); 00143 g_free(debug); 00144 00145 gchar *message = NULL; 00146 if (error->message != NULL) 00147 { 00148 gint malloc_size = strlen(error->message) + 20; 00149 message = malloc(sizeof(char) * malloc_size); 00150 if (message) 00151 { 00152 memset(message,'\0',malloc_size); 00153 g_snprintf(message, malloc_size,_("Info: %s"),error->message); 00154 00155 enter_threads(); 00156 put_status_message(message); 00157 exit_threads(); 00158 00159 g_free(message); 00160 } 00161 } 00162 g_error_free (error); 00163 break; 00164 } 00165 case GST_MESSAGE_TAG: 00166 { 00167 GstTagList *tag_list = NULL; 00168 gst_message_parse_tag(msg, &tag_list); 00169 00170 gint number_of_stream = 0; 00171 g_object_get(play, "current-audio", &number_of_stream, NULL); 00172 00173 //artist 00174 const GValue *val = gst_tag_list_get_value_index(tag_list, GST_TAG_ARTIST, 00175 number_of_stream); 00176 if (val != NULL) 00177 { 00178 song_artist = g_value_get_string(val); 00179 } 00180 00181 //title 00182 val = gst_tag_list_get_value_index(tag_list, GST_TAG_TITLE, number_of_stream); 00183 if (val != NULL) 00184 { 00185 song_title = g_value_get_string(val); 00186 } 00187 00188 //rate (bps) 00189 val = gst_tag_list_get_value_index(tag_list, GST_TAG_BITRATE, number_of_stream); 00190 if (val != NULL) 00191 { 00192 rate = g_value_get_uint(val); 00193 } 00194 00195 break; 00196 } 00197 default: 00198 break; 00199 } 00200 00201 return TRUE; 00202 } 00203 00205 void gstreamer_get_song_infos(gchar *total_infos) 00206 { 00207 if (play) 00208 { 00209 gint freq = 0; 00210 gint nch = 0; 00211 00212 gint number_of_stream = 0; 00213 g_object_get(play, "current-audio", &number_of_stream, NULL); 00214 00215 //get the stream info 00216 GList *streaminfo = NULL; 00217 g_object_get(play, "stream-info", &streaminfo, NULL); 00218 00219 gchar rate_str[32] = { '\0' }; 00220 gchar freq_str[32] = { '\0' }; 00221 gchar nch_str[32] = { '\0' }; 00222 00223 gchar *_Kbps = _("Kbps"); 00224 gchar *_Khz = _("Khz"); 00225 00226 //get the first element of the stream info list 00227 GObject *object = g_list_nth_data(streaminfo, number_of_stream); 00228 if (object) 00229 { 00230 GstObject *obj = NULL; 00231 g_object_get(G_OBJECT(object), "object", &obj, NULL); 00232 00233 //get the caps from the first element 00234 GstCaps *caps = NULL; 00235 g_object_get(obj, "caps", &caps, NULL); 00236 if (caps) 00237 { 00238 //get the structure from the caps 00239 GstStructure *structure = NULL; 00240 structure = gst_caps_get_structure(caps, number_of_stream); 00241 00242 //get the rate and the number of channels from the structure 00243 gst_structure_get_int(structure, "rate", &freq); 00244 gst_structure_get_int(structure, "channels", &nch); 00245 00246 gst_caps_unref(caps); 00247 } 00248 00249 g_snprintf(rate_str,32, "%d", rate/1000); 00250 g_snprintf(freq_str,32, "%d", freq/1000); 00251 00252 if (nch >= 2) 00253 { 00254 snprintf(nch_str, 32, "%s", _("stereo")); 00255 } 00256 else 00257 { 00258 snprintf(nch_str, 32, "%s", _("mono")); 00259 } 00260 } 00261 00262 if (rate != 0) 00263 { 00264 g_snprintf(total_infos,512, 00265 "%s %s %s %s %s", 00266 rate_str,_Kbps,freq_str, _Khz,nch_str); 00267 } 00268 else 00269 { 00270 total_infos[0] = '\0'; 00271 } 00272 } 00273 } 00274 00279 gchar *gstreamer_get_filename() 00280 { 00281 return strdup(inputfilename_get()); 00282 } 00283 00285 gint gstreamer_get_playlist_number() 00286 { 00287 return 1; 00288 } 00289 00294 gchar *gstreamer_get_title_song() 00295 { 00296 if (song_artist || song_title) 00297 { 00298 gint title_size = 20; 00299 00300 if (song_artist) 00301 { 00302 title_size += strlen(song_artist); 00303 } 00304 00305 if (song_title) 00306 { 00307 title_size += strlen(song_title); 00308 } 00309 00310 gchar *title = malloc(sizeof(char) * title_size); 00311 memset(title, title_size, '\0'); 00312 00313 if (song_artist && song_title) 00314 { 00315 g_snprintf(title, title_size, "%s - %s", song_artist, song_title); 00316 } 00317 else if (song_title && !song_artist) 00318 { 00319 g_snprintf(title, title_size, "%s", song_title); 00320 } 00321 else if (song_artist && !song_title) 00322 { 00323 g_snprintf(title, title_size, "%s", song_artist); 00324 } 00325 00326 return title; 00327 } 00328 else 00329 { 00330 gchar *fname = gstreamer_get_filename(); 00331 if (fname != NULL) 00332 { 00333 gchar *file = strrchr(fname, G_DIR_SEPARATOR); 00334 if (file != NULL) 00335 { 00336 gchar *alloced_file = strdup(file+1); 00337 g_free(fname); 00338 fname = NULL; 00339 return alloced_file; 00340 } 00341 else 00342 { 00343 return fname; 00344 } 00345 } 00346 else 00347 { 00348 return strdup("-"); 00349 } 00350 } 00351 } 00352 00354 gint gstreamer_get_time_elapsed() 00355 { 00356 if (play) 00357 { 00358 GstQuery *query = gst_query_new_position(GST_FORMAT_TIME); 00359 gint64 time = 0; 00360 00361 if (gst_element_query(play, query)) 00362 { 00363 gst_query_parse_position(query, NULL, &time); 00364 } 00365 00366 gst_query_unref(query); 00367 00368 return (gint) (time / GST_MSECOND); 00369 } 00370 else 00371 { 00372 return 0; 00373 } 00374 } 00375 00377 void gstreamer_start() 00378 { 00379 if (play) 00380 { 00381 gstreamer_quit(); 00382 gst_object_unref(play); 00383 } 00384 00385 gst_init(NULL, NULL); 00386 00387 #ifdef __WIN32__ 00388 gst_default_registry_add_path("./"); 00389 #endif 00390 00391 play = gst_element_factory_make("playbin", "play"); 00392 //if we have started the player 00393 if (play) 00394 { 00395 if (! container_has_child(GTK_CONTAINER(player_vbox), playlist_box)) 00396 { 00397 gtk_box_pack_start(GTK_BOX(player_vbox), playlist_box, TRUE, TRUE, 0); 00398 } 00399 gtk_widget_show_all(playlist_box); 00400 00401 _gstreamer_is_running = TRUE; 00402 bus = gst_pipeline_get_bus (GST_PIPELINE (play)); 00403 gst_bus_add_watch(bus, bus_call, NULL); 00404 gst_object_unref(bus); 00405 00406 //add the current filename 00407 const gchar *fname = inputfilename_get(); 00408 GList *song_list = NULL; 00409 song_list = g_list_append(song_list, strdup(fname)); 00410 gstreamer_add_files(song_list); 00411 //TODO: free memory from GList *song_list 00412 } 00413 else 00414 { 00415 enter_threads(); 00416 put_status_message(_(" error: cannot create gstreamer playbin\n")); 00417 exit_threads(); 00418 } 00419 } 00420 00422 void gstreamer_select_last_file() 00423 { 00424 } 00425 00427 void gstreamer_play_last_file() 00428 { 00429 gstreamer_stop(); 00430 gstreamer_play(); 00431 } 00432 00434 void gstreamer_add_files(GList *list) 00435 { 00436 gchar *song = NULL; 00437 gint i = 0; 00438 gchar *uri = NULL; 00439 int len_uri = 20; 00440 00441 if (song_title) 00442 { 00443 song_title = NULL; 00444 } 00445 if (song_artist) 00446 { 00447 song_artist = NULL; 00448 } 00449 00450 if (play) 00451 { 00452 while ((song = g_list_nth_data(list, i)) != NULL) 00453 { 00454 if (song) 00455 { 00456 //add file to playlist 00457 add_playlist_file(song); 00458 len_uri += strlen(song); 00459 uri = malloc(sizeof(char) * len_uri); 00460 g_snprintf(uri,len_uri,"file://%s",song); 00461 g_object_set(G_OBJECT(play), "uri", uri, NULL); 00462 if (uri) 00463 { 00464 g_free(uri); 00465 uri = NULL; 00466 } 00467 } 00468 i++; 00469 } 00470 } 00471 } 00472 00474 void gstreamer_set_volume(gint volume) 00475 { 00476 if (play) 00477 { 00478 //values between 0 and 2 00479 //-documentation says values can be between 0 and 10 00480 g_object_set(G_OBJECT(play), "volume", (double) volume / 100.0 * 2, NULL); 00481 } 00482 } 00483 00485 gint gstreamer_get_volume() 00486 { 00487 if (play) 00488 { 00489 double volume = 0; 00490 //values between 0 and 2 00491 //-documentation says values can be between 0 and 10 00492 g_object_get(G_OBJECT(play), "volume", &volume, NULL); 00493 00494 return (gint) (volume / 2 * 100); 00495 } 00496 else 00497 { 00498 return 0; 00499 } 00500 } 00501 00503 void gstreamer_start_with_songs(GList *list) 00504 { 00505 gstreamer_start(); 00506 gstreamer_add_files(list); 00507 gstreamer_play(); 00508 } 00509 00511 gint gstreamer_is_running() 00512 { 00513 return _gstreamer_is_running; 00514 } 00515 00517 gint gstreamer_is_paused() 00518 { 00519 if (play) 00520 { 00521 GstState state; 00522 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00523 00524 if (state == GST_STATE_PAUSED) 00525 { 00526 return TRUE; 00527 } 00528 else 00529 { 00530 return FALSE; 00531 } 00532 } 00533 else 00534 { 00535 return FALSE; 00536 } 00537 } 00538 00540 void gstreamer_play() 00541 { 00542 if (play) 00543 { 00544 GstState state; 00545 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00546 00547 if (state == GST_STATE_PLAYING) 00548 { 00549 gstreamer_jump(0); 00550 } 00551 else 00552 { 00553 gst_element_set_state(play, GST_STATE_PLAYING); 00554 } 00555 } 00556 } 00557 00559 void gstreamer_stop() 00560 { 00561 if (play) 00562 { 00563 gst_element_set_state(play, GST_STATE_NULL); 00564 } 00565 } 00566 00568 void gstreamer_pause() 00569 { 00570 if (play) 00571 { 00572 GstState state; 00573 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00574 00575 if (state == GST_STATE_PLAYING) 00576 { 00577 gst_element_set_state(play, GST_STATE_PAUSED); 00578 } 00579 else 00580 { 00581 gstreamer_play(); 00582 } 00583 } 00584 } 00585 00587 void gstreamer_next() 00588 { 00589 } 00590 00592 void gstreamer_prev() 00593 { 00594 } 00595 00597 void gstreamer_jump(gint position) 00598 { 00599 if (play) 00600 { 00601 gst_element_seek(play, 00602 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 00603 GST_SEEK_TYPE_SET, position * GST_MSECOND, 0, 0); 00604 } 00605 } 00606 00608 gint gstreamer_get_total_time() 00609 { 00610 if (play) 00611 { 00612 GstQuery *query = gst_query_new_duration(GST_FORMAT_TIME); 00613 gint time = 0; 00614 00615 if (gst_element_query(play,query)) 00616 { 00617 gint64 total_time; 00618 gst_query_parse_duration (query, NULL, &total_time); 00619 time = (gint) (total_time / GST_MSECOND); 00620 } 00621 00622 gst_query_unref(query); 00623 00624 return time; 00625 } 00626 else 00627 { 00628 return 0; 00629 } 00630 } 00631 00633 gint gstreamer_is_playing() 00634 { 00635 if (play) 00636 { 00637 GstState state; 00638 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00639 00640 if ((state == GST_STATE_PLAYING) || (state == GST_STATE_PAUSED)) 00641 { 00642 return TRUE; 00643 } 00644 else 00645 { 00646 return FALSE; 00647 } 00648 } 00649 else 00650 { 00651 return FALSE; 00652 } 00653 } 00654 00656 void gstreamer_quit() 00657 { 00658 if (play) 00659 { 00660 gst_element_set_state(play, GST_STATE_NULL); 00661 } 00662 _gstreamer_is_running = FALSE; 00663 00664 gtk_widget_hide(playlist_box); 00665 } 00666 00667 #endif 00668