Add lyrics parser
This commit is contained in:
parent
789b6fca64
commit
b3ac77c4e7
|
@ -61,7 +61,7 @@ if(WIN32)
|
||||||
set_property(SOURCE ../icon.rc APPEND PROPERTY
|
set_property(SOURCE ../icon.rc APPEND PROPERTY
|
||||||
OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/../icon.ico
|
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}
|
add_custom_command( TARGET ${PROJECT_NAME}
|
||||||
COMMAND echo * > ${CMAKE_BINARY_DIR}/.gitignore
|
COMMAND echo * > ${CMAKE_BINARY_DIR}/.gitignore
|
||||||
COMMAND echo **/* > ${CMAKE_BINARY_DIR}/.hgignore)
|
COMMAND echo **/* > ${CMAKE_BINARY_DIR}/.hgignore)
|
||||||
|
|
|
@ -1,7 +1,99 @@
|
||||||
|
#include "MyItem.h"
|
||||||
#include "LyricsParser.h"
|
#include "LyricsParser.h"
|
||||||
|
#include "MyMediaPlayer.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// 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),
|
||||||
|
"<span color=\"red\" size='12pt'>No Lyric File Found!</span>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void get_lyrics(const char *lyrics_file, int time, char *lyric_string);
|
#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);
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
#include "MyItem.h"
|
#include "MyItem.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
// File name and path limits
|
|
||||||
#define name_max_length 256
|
|
||||||
#define path_max_length 4096
|
|
||||||
|
|
||||||
struct _MyItem
|
struct _MyItem
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
// File name and path limits
|
||||||
|
#define name_max_length 256
|
||||||
|
#define path_max_length 4096
|
||||||
|
|
||||||
#define MY_ITEM_TYPE (my_item_get_type())
|
#define MY_ITEM_TYPE (my_item_get_type())
|
||||||
G_DECLARE_FINAL_TYPE(MyItem, my_item, MY, ITEM, GObject)
|
G_DECLARE_FINAL_TYPE(MyItem, my_item, MY, ITEM, GObject)
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,22 @@
|
||||||
#include "MyMediaPlayer.h"
|
#include "MyMediaPlayer.h"
|
||||||
|
#include "LyricsParser.h"
|
||||||
#include "MyItem.h"
|
#include "MyItem.h"
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
struct _MyMediaPlayer
|
struct _MyMediaPlayer
|
||||||
{
|
{
|
||||||
GtkApplicationWindow parent_instance;
|
GtkApplicationWindow parent_instance;
|
||||||
GtkWidget *video, *label_lyrics;
|
GtkWidget *video, *label_lyrics;
|
||||||
|
GtkWidget *ctrl_box;
|
||||||
|
GtkWidget *btn_priv, *btn_play, *btn_next, *btn_stop;
|
||||||
GtkWidget *main_box, *btn_box;
|
GtkWidget *main_box, *btn_box;
|
||||||
GtkWidget *btn_add, *btn_remove;
|
GtkWidget *btn_add, *btn_remove;
|
||||||
GtkWidget *btn_load, *btn_save;
|
GtkWidget *btn_load, *btn_save;
|
||||||
GtkWidget *column_view;
|
GtkWidget *column_view;
|
||||||
GtkWidget *scrolled_window;
|
GtkWidget *scrolled_window;
|
||||||
GListStore *music_store;
|
GListStore *music_store;
|
||||||
|
char current_filename[path_max_length];
|
||||||
|
gboolean music_loaded;
|
||||||
GtkSingleSelection *music_selection;
|
GtkSingleSelection *music_selection;
|
||||||
GtkListItemFactory *filename_factory;
|
GtkListItemFactory *filename_factory;
|
||||||
GtkColumnViewColumn *filename_column;
|
GtkColumnViewColumn *filename_column;
|
||||||
|
@ -77,18 +83,25 @@ static void column_view_activated(GtkColumnView *self, gint position, MyMediaPla
|
||||||
// Play the selected media
|
// Play the selected media
|
||||||
MyItem *item;
|
MyItem *item;
|
||||||
GFile *music_file;
|
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));
|
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)
|
if (music_file != NULL)
|
||||||
{
|
{
|
||||||
|
// Add file to video widget for play
|
||||||
gtk_video_set_file(GTK_VIDEO(player->video), music_file);
|
gtk_video_set_file(GTK_VIDEO(player->video), music_file);
|
||||||
g_object_unref(music_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Check whether media stream has video
|
// Mark the player is ready and update current file name
|
||||||
// if(!gtk_media_stream_has_video(stream)){
|
player->music_loaded = TRUE;
|
||||||
// gtk_widget_set_size_request(player->video, 300, 50);
|
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,
|
static void filename_factory_setup(GtkListItemFactory *factory,
|
||||||
|
@ -116,6 +129,30 @@ static void filename_factory_bind(GtkListItemFactory *factory,
|
||||||
my_item_get_dispname(file_item));
|
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)
|
static void my_media_player_init(MyMediaPlayer *self)
|
||||||
{
|
{
|
||||||
// Initalize window
|
// 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),
|
gtk_column_view_append_column(GTK_COLUMN_VIEW(self->column_view),
|
||||||
self->filename_column);
|
self->filename_column);
|
||||||
|
|
||||||
|
// Add a timer for music playing
|
||||||
|
self->music_loaded = FALSE;
|
||||||
|
g_timeout_add(1, lyric_time_func, self);
|
||||||
|
|
||||||
// Add widgets
|
// Add widgets
|
||||||
gtk_box_append(GTK_BOX(self->main_box), self->video);
|
gtk_box_append(GTK_BOX(self->main_box), self->video);
|
||||||
gtk_box_append(GTK_BOX(self->main_box), self->label_lyrics);
|
gtk_box_append(GTK_BOX(self->main_box), self->label_lyrics);
|
||||||
|
|
|
@ -4,4 +4,12 @@
|
||||||
|
|
||||||
G_DECLARE_FINAL_TYPE(MyMediaPlayer, my_media_player, MYMEDIA, PLAYER, GtkApplicationWindow)
|
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);
|
MyMediaPlayer *my_media_player_new(GtkApplication *app);
|
||||||
|
|
Loading…
Reference in New Issue