mp3splt-gtk
|
00001 /********************************************************** 00002 * 00003 * mp3splt-gtk -- utility based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright: (C) 2005-2012 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 gtk_widget_show_all(playlist_box); 00396 00397 _gstreamer_is_running = TRUE; 00398 bus = gst_pipeline_get_bus (GST_PIPELINE (play)); 00399 gst_bus_add_watch(bus, bus_call, NULL); 00400 gst_object_unref(bus); 00401 00402 //add the current filename 00403 const gchar *fname = inputfilename_get(); 00404 GList *song_list = NULL; 00405 song_list = g_list_append(song_list, strdup(fname)); 00406 gstreamer_add_files(song_list); 00407 //TODO: free memory from GList *song_list 00408 } 00409 else 00410 { 00411 enter_threads(); 00412 put_status_message(_(" error: cannot create gstreamer playbin\n")); 00413 exit_threads(); 00414 } 00415 } 00416 00418 void gstreamer_select_last_file() 00419 { 00420 } 00421 00423 void gstreamer_play_last_file() 00424 { 00425 gstreamer_stop(); 00426 gstreamer_play(); 00427 } 00428 00430 void gstreamer_add_files(GList *list) 00431 { 00432 gchar *song = NULL; 00433 gint i = 0; 00434 gchar *uri = NULL; 00435 int len_uri = 20; 00436 00437 if (song_title) 00438 { 00439 song_title = NULL; 00440 } 00441 if (song_artist) 00442 { 00443 song_artist = NULL; 00444 } 00445 00446 if (play) 00447 { 00448 while ((song = g_list_nth_data(list, i)) != NULL) 00449 { 00450 if (song) 00451 { 00452 //add file to playlist 00453 add_playlist_file(song); 00454 len_uri += strlen(song); 00455 uri = malloc(sizeof(char) * len_uri); 00456 g_snprintf(uri,len_uri,"file://%s",song); 00457 g_object_set(G_OBJECT(play), "uri", uri, NULL); 00458 if (uri) 00459 { 00460 g_free(uri); 00461 uri = NULL; 00462 } 00463 } 00464 i++; 00465 } 00466 } 00467 } 00468 00470 void gstreamer_set_volume(gint volume) 00471 { 00472 if (play) 00473 { 00474 //values between 0 and 2 00475 //-documentation says values can be between 0 and 10 00476 g_object_set(G_OBJECT(play), "volume", (double) volume / 100.0 * 2, NULL); 00477 } 00478 } 00479 00481 gint gstreamer_get_volume() 00482 { 00483 if (play) 00484 { 00485 double volume = 0; 00486 //values between 0 and 2 00487 //-documentation says values can be between 0 and 10 00488 g_object_get(G_OBJECT(play), "volume", &volume, NULL); 00489 00490 return (gint) (volume / 2 * 100); 00491 } 00492 else 00493 { 00494 return 0; 00495 } 00496 } 00497 00499 void gstreamer_start_with_songs(GList *list) 00500 { 00501 gstreamer_start(); 00502 gstreamer_add_files(list); 00503 gstreamer_play(); 00504 } 00505 00507 gint gstreamer_is_running() 00508 { 00509 return _gstreamer_is_running; 00510 } 00511 00513 gint gstreamer_is_paused() 00514 { 00515 if (play) 00516 { 00517 GstState state; 00518 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00519 00520 if (state == GST_STATE_PAUSED) 00521 { 00522 return TRUE; 00523 } 00524 else 00525 { 00526 return FALSE; 00527 } 00528 } 00529 else 00530 { 00531 return FALSE; 00532 } 00533 } 00534 00536 void gstreamer_play() 00537 { 00538 if (play) 00539 { 00540 GstState state; 00541 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00542 00543 if (state == GST_STATE_PLAYING) 00544 { 00545 gstreamer_jump(0); 00546 } 00547 else 00548 { 00549 gst_element_set_state(play, GST_STATE_PLAYING); 00550 } 00551 } 00552 } 00553 00555 void gstreamer_stop() 00556 { 00557 if (play) 00558 { 00559 gst_element_set_state(play, GST_STATE_NULL); 00560 } 00561 } 00562 00564 void gstreamer_pause() 00565 { 00566 if (play) 00567 { 00568 GstState state; 00569 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00570 00571 if (state == GST_STATE_PLAYING) 00572 { 00573 gst_element_set_state(play, GST_STATE_PAUSED); 00574 } 00575 else 00576 { 00577 gstreamer_play(); 00578 } 00579 } 00580 } 00581 00583 void gstreamer_next() 00584 { 00585 } 00586 00588 void gstreamer_prev() 00589 { 00590 } 00591 00593 void gstreamer_jump(gint position) 00594 { 00595 if (play) 00596 { 00597 gst_element_seek(play, 00598 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, 00599 GST_SEEK_TYPE_SET, position * GST_MSECOND, 0, 0); 00600 } 00601 } 00602 00604 gint gstreamer_get_total_time() 00605 { 00606 if (play) 00607 { 00608 GstQuery *query = gst_query_new_duration(GST_FORMAT_TIME); 00609 gint time = 0; 00610 00611 if (gst_element_query(play,query)) 00612 { 00613 gint64 total_time; 00614 gst_query_parse_duration (query, NULL, &total_time); 00615 time = (gint) (total_time / GST_MSECOND); 00616 } 00617 00618 gst_query_unref(query); 00619 00620 return time; 00621 } 00622 else 00623 { 00624 return 0; 00625 } 00626 } 00627 00629 gint gstreamer_is_playing() 00630 { 00631 if (play) 00632 { 00633 GstState state; 00634 gst_element_get_state(play, &state, NULL, GST_CLOCK_TIME_NONE); 00635 00636 if ((state == GST_STATE_PLAYING) || (state == GST_STATE_PAUSED)) 00637 { 00638 return TRUE; 00639 } 00640 else 00641 { 00642 return FALSE; 00643 } 00644 } 00645 else 00646 { 00647 return FALSE; 00648 } 00649 } 00650 00652 void gstreamer_quit() 00653 { 00654 if (play) 00655 { 00656 gst_element_set_state(play, GST_STATE_NULL); 00657 } 00658 _gstreamer_is_running = FALSE; 00659 } 00660 00661 #endif 00662