diff --git a/Gtk4/gtk154_mediaplayer3/CMakeLists.txt b/Gtk4/gtk154_mediaplayer3/CMakeLists.txt index f9aff53..bfe2ccc 100644 --- a/Gtk4/gtk154_mediaplayer3/CMakeLists.txt +++ b/Gtk4/gtk154_mediaplayer3/CMakeLists.txt @@ -61,7 +61,7 @@ if(WIN32) set_property(SOURCE ../icon.rc APPEND PROPERTY OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/../icon.ico ) - add_executable(${PROJECT_NAME} WIN32 ${app_WINRC} ${SOURCE_FILE}) + add_executable(${PROJECT_NAME} ${app_WINRC} ${SOURCE_FILE}) add_custom_command( TARGET ${PROJECT_NAME} COMMAND echo * > ${CMAKE_BINARY_DIR}/.gitignore COMMAND echo **/* > ${CMAKE_BINARY_DIR}/.hgignore) diff --git a/Gtk4/gtk154_mediaplayer3/src/LyricsParser.cpp b/Gtk4/gtk154_mediaplayer3/src/LyricsParser.cpp index 42b8405..bfcf766 100644 --- a/Gtk4/gtk154_mediaplayer3/src/LyricsParser.cpp +++ b/Gtk4/gtk154_mediaplayer3/src/LyricsParser.cpp @@ -1,7 +1,99 @@ +#include "MyItem.h" #include "LyricsParser.h" +#include "MyMediaPlayer.h" #include +#include -void get_lyrics(const char *lyrics_file, int time, char *lyric_string) +#define lyrics_max_length 1024 + +static FILE *lyrics_file = NULL; + +void update_lyrics(MyMediaPlayer *player) { + // Get position between filename and extension + int point_pos; + char *current_filename = my_media_player_get_filename(player); + for(int i = strlen(current_filename) - 1; i > 0; i--) + { + if(current_filename[i] == '.'){ + point_pos = i; + break; + } + } -} \ No newline at end of file + // Get Lyrics file name + char lyric_filename[path_max_length]; + strncpy(lyric_filename, current_filename, point_pos); + strncat(lyric_filename, ".lrc", 4); + + // Open the lyrics file + lyrics_file = fopen(lyric_filename, "r"); +} + +static void get_lyrics(gint64 curr_time, gboolean playing, MyMediaPlayer *player) +{ + char lyrics_line[lyrics_max_length]; + static gboolean line_read = FALSE; + gint64 lyric_time = 0; + // Get lyrics data + if(lyrics_file != NULL) + { + if(playing && !line_read) + { + // Get lyrics time + fgets(lyrics_line, lyrics_max_length, lyrics_file); + gint64 lyric_min = (lyrics_line[1] - '0') * 10 + + (lyrics_line[2] - '0'); + gint64 lyric_sec = (lyrics_line[4] - '0') * 10 + + (lyrics_line[5] - '0'); + lyric_time = (lyrics_line[7] - '0') * 100 + + (lyrics_line[8] - '0') * 10 + + (lyrics_line[9] - '0') + + lyric_sec * 1000 + + lyric_min * 1000 * 60; + g_print("%lld\n", lyric_time); + line_read = TRUE; + } + }else{ + gtk_label_set_markup(my_media_player_get_lyrics_widget(player), + "No Lyric File Found!"); + } +} + +static void get_media_stream_status(GtkMediaStream *stream) +{ + if(gtk_media_stream_get_ended(stream)) + { + fclose(lyrics_file); + g_print("Media ended"); + } +} + +gboolean lyric_time_func(gpointer data) +{ + MyMediaPlayer *player = MYMEDIA_PLAYER(data); + // if music is loaded, try to get timestamp + if (my_media_player_get_music_loaded(player)) + { + // Get media stream + GtkMediaStream *stream; + stream = gtk_video_get_media_stream(GTK_VIDEO( + my_media_player_get_video_widget(player))); + + // only get timestamp when media stream vaild + if (GTK_IS_MEDIA_STREAM(stream)) + { + // get timestamp + gint64 timestamp = gtk_media_stream_get_timestamp(stream); + gint64 timestamp_ms = timestamp / 1000; + gboolean media_playing = gtk_media_stream_get_playing(stream); + + // Update lyrics + get_lyrics(timestamp_ms, media_playing, player); + + // Check whether media stopped + get_media_stream_status(stream); + } + } + return TRUE; +} diff --git a/Gtk4/gtk154_mediaplayer3/src/LyricsParser.h b/Gtk4/gtk154_mediaplayer3/src/LyricsParser.h index 4f3706c..a117f41 100644 --- a/Gtk4/gtk154_mediaplayer3/src/LyricsParser.h +++ b/Gtk4/gtk154_mediaplayer3/src/LyricsParser.h @@ -1,3 +1,9 @@ #pragma once -void get_lyrics(const char *lyrics_file, int time, char *lyric_string); \ No newline at end of file +#include "MyMediaPlayer.h" + +// Timeout function for music played time +gboolean lyric_time_func(gpointer data); + +// Update lyrics file when a music will play +void update_lyrics(MyMediaPlayer *player); diff --git a/Gtk4/gtk154_mediaplayer3/src/MyItem.cpp b/Gtk4/gtk154_mediaplayer3/src/MyItem.cpp index 3df1d13..e0ddb5a 100644 --- a/Gtk4/gtk154_mediaplayer3/src/MyItem.cpp +++ b/Gtk4/gtk154_mediaplayer3/src/MyItem.cpp @@ -1,8 +1,5 @@ #include "MyItem.h" #include -// File name and path limits -#define name_max_length 256 -#define path_max_length 4096 struct _MyItem { diff --git a/Gtk4/gtk154_mediaplayer3/src/MyItem.h b/Gtk4/gtk154_mediaplayer3/src/MyItem.h index 5d1723d..41e00f6 100644 --- a/Gtk4/gtk154_mediaplayer3/src/MyItem.h +++ b/Gtk4/gtk154_mediaplayer3/src/MyItem.h @@ -2,6 +2,10 @@ #include +// File name and path limits +#define name_max_length 256 +#define path_max_length 4096 + #define MY_ITEM_TYPE (my_item_get_type()) G_DECLARE_FINAL_TYPE(MyItem, my_item, MY, ITEM, GObject) diff --git a/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.cpp b/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.cpp index 76daf2b..e1f6cba 100644 --- a/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.cpp +++ b/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.cpp @@ -1,16 +1,22 @@ #include "MyMediaPlayer.h" +#include "LyricsParser.h" #include "MyItem.h" +#include struct _MyMediaPlayer { GtkApplicationWindow parent_instance; GtkWidget *video, *label_lyrics; + GtkWidget *ctrl_box; + GtkWidget *btn_priv, *btn_play, *btn_next, *btn_stop; GtkWidget *main_box, *btn_box; GtkWidget *btn_add, *btn_remove; GtkWidget *btn_load, *btn_save; GtkWidget *column_view; GtkWidget *scrolled_window; GListStore *music_store; + char current_filename[path_max_length]; + gboolean music_loaded; GtkSingleSelection *music_selection; GtkListItemFactory *filename_factory; GtkColumnViewColumn *filename_column; @@ -77,18 +83,25 @@ static void column_view_activated(GtkColumnView *self, gint position, MyMediaPla // Play the selected media MyItem *item; GFile *music_file; + const char *file_name; + + // Get selection and open the music file item = MY_ITEM(gtk_single_selection_get_selected_item(player->music_selection)); - music_file = g_file_new_for_path(my_item_get_filename(item)); + file_name = my_item_get_filename(item); + music_file = g_file_new_for_path(file_name); if (music_file != NULL) { + // Add file to video widget for play gtk_video_set_file(GTK_VIDEO(player->video), music_file); - g_object_unref(music_file); - } - // // Check whether media stream has video - // if(!gtk_media_stream_has_video(stream)){ - // gtk_widget_set_size_request(player->video, 300, 50); - // } + // Mark the player is ready and update current file name + player->music_loaded = TRUE; + strncpy(player->current_filename, file_name, strlen(file_name)); + g_object_unref(music_file); + + // Update lyrics file + update_lyrics(player); + } } static void filename_factory_setup(GtkListItemFactory *factory, @@ -116,6 +129,30 @@ static void filename_factory_bind(GtkListItemFactory *factory, my_item_get_dispname(file_item)); } +gboolean my_media_player_get_music_loaded(MyMediaPlayer *self) +{ + // Get whether music is loaded + return self->music_loaded; +} + +GtkWidget *my_media_player_get_video_widget(MyMediaPlayer *self) +{ + // Get video widget + return self->video; +} + +GtkLabel *my_media_player_get_lyrics_widget(MyMediaPlayer *self) +{ + // Get Label for lyrics + return GTK_LABEL(self->label_lyrics); +} + +char *my_media_player_get_filename(MyMediaPlayer *self) +{ + // Get file name + return self->current_filename; +} + static void my_media_player_init(MyMediaPlayer *self) { // Initalize window @@ -163,6 +200,10 @@ static void my_media_player_init(MyMediaPlayer *self) gtk_column_view_append_column(GTK_COLUMN_VIEW(self->column_view), self->filename_column); + // Add a timer for music playing + self->music_loaded = FALSE; + g_timeout_add(1, lyric_time_func, self); + // Add widgets gtk_box_append(GTK_BOX(self->main_box), self->video); gtk_box_append(GTK_BOX(self->main_box), self->label_lyrics); diff --git a/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.h b/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.h index addaefc..d5c5b5f 100644 --- a/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.h +++ b/Gtk4/gtk154_mediaplayer3/src/MyMediaPlayer.h @@ -4,4 +4,12 @@ G_DECLARE_FINAL_TYPE(MyMediaPlayer, my_media_player, MYMEDIA, PLAYER, GtkApplicationWindow) +gboolean my_media_player_get_music_loaded(MyMediaPlayer *self); + +GtkWidget *my_media_player_get_video_widget(MyMediaPlayer *self); + +GtkLabel *my_media_player_get_lyrics_widget(MyMediaPlayer *self); + +char *my_media_player_get_filename(MyMediaPlayer *self); + MyMediaPlayer *my_media_player_new(GtkApplication *app);