add subtitle support into rage on cmdline as well as automatic
This commit is contained in:
parent
143db13878
commit
c2472804f9
10
README
10
README
|
@ -22,6 +22,16 @@ You can tell it what media/video engine in emotion to ue via -e:
|
|||
rage -e xine dvd:/
|
||||
rage -e gstreamer1 blah.mp3
|
||||
|
||||
You can also specify subtitle files with -sub:
|
||||
|
||||
rage file.mp4 -sub mysubs.srt
|
||||
|
||||
This depends on video engine support to display them, so it may not
|
||||
work. Also rage will use a srt or sub format file if found,
|
||||
automatically. If the filename is video.mp4 or video.avi, video.mov
|
||||
etc. then rage looks for video.srt or video.sub and automatically will
|
||||
use it.
|
||||
|
||||
If you DND files onto its window, they are added to the playlist.
|
||||
Mouse over the right of the window brings up the playlist. Mouse over
|
||||
the position bar at the bottom, if it's a video, brings up a video
|
||||
|
|
1
TODO
1
TODO
|
@ -7,7 +7,6 @@
|
|||
* spu channel list/selection
|
||||
* video channel list/selection
|
||||
* handle non-seekable content (eg streams)
|
||||
* add subtitle file cmdline
|
||||
* loop all option
|
||||
* show busy anim until opened cb or failure
|
||||
* thumbnail picker show all thumbs for video in a grid to select position
|
||||
|
|
|
@ -27,11 +27,11 @@ elm_main(int argc, char **argv)
|
|||
{
|
||||
Evas_Object *win;
|
||||
char buf[4096];
|
||||
const char *f;
|
||||
Eina_List *list = NULL;
|
||||
int i;
|
||||
Inf *inf;
|
||||
Config *config;
|
||||
Winvid_Entry *vid = NULL;
|
||||
|
||||
elm_need_efreet();
|
||||
config_init();
|
||||
|
@ -60,8 +60,23 @@ elm_main(int argc, char **argv)
|
|||
config->emotion_engine = eina_stringshare_add(argv[i]);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[i], "-sub"))
|
||||
{
|
||||
if (i < (argc - 1))
|
||||
{
|
||||
i++;
|
||||
if (vid) eina_stringshare_replace(&(vid->sub), argv[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
list = eina_list_append(list, eina_stringshare_add(argv[i]));
|
||||
{
|
||||
vid = calloc(1, sizeof(Winvid_Entry));
|
||||
if (vid)
|
||||
{
|
||||
vid->file = eina_stringshare_add(argv[i]);
|
||||
list = eina_list_append(list, vid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
|
||||
|
@ -84,11 +99,18 @@ elm_main(int argc, char **argv)
|
|||
}
|
||||
|
||||
evas_object_event_callback_add(win, EVAS_CALLBACK_RESIZE, _cb_resize, NULL);
|
||||
evas_object_resize(win, 320, 200);
|
||||
evas_object_resize(win,
|
||||
320 * elm_config_scale_get(),
|
||||
200 * elm_config_scale_get());
|
||||
|
||||
win_video_init(win);
|
||||
win_video_file_list_set(win, list);
|
||||
EINA_LIST_FREE(list, f) eina_stringshare_del(f);
|
||||
EINA_LIST_FREE(list, vid)
|
||||
{
|
||||
if (vid->file) eina_stringshare_del(vid->file);
|
||||
if (vid->sub) eina_stringshare_del(vid->sub);
|
||||
free(vid);
|
||||
}
|
||||
|
||||
inf = evas_object_data_get(win, "inf");
|
||||
if (argc <= 1)
|
||||
|
|
|
@ -570,6 +570,14 @@ video_file_get(Evas_Object *obj)
|
|||
return sd->file;
|
||||
}
|
||||
|
||||
void
|
||||
video_sub_file_set(Evas_Object *obj, const char *file)
|
||||
{
|
||||
Video *sd = evas_object_smart_data_get(obj);
|
||||
if (!sd) return;
|
||||
emotion_object_video_subtitle_file_set(sd->o_vid, file);
|
||||
}
|
||||
|
||||
void
|
||||
video_mute_set(Evas_Object *obj, Eina_Bool mute)
|
||||
{
|
||||
|
@ -955,6 +963,45 @@ video_meta_album_get(Evas_Object *obj)
|
|||
return emotion_object_meta_info_get(sd->o_vid, EMOTION_META_INFO_TRACK_ALBUM);
|
||||
}
|
||||
|
||||
void
|
||||
video_file_autosub_set(Evas_Object *obj, const char *file, const char *sub)
|
||||
{
|
||||
if ((file) && (!sub))
|
||||
{
|
||||
const char *subtypes[] =
|
||||
{
|
||||
".srt",
|
||||
".SRT",
|
||||
".sub",
|
||||
".SUB",
|
||||
NULL
|
||||
};
|
||||
char *sub = alloca(strlen(file) + 1 + 16);
|
||||
char *p;
|
||||
int i;
|
||||
Eina_Bool found = EINA_FALSE;
|
||||
|
||||
strcpy(sub, file);
|
||||
p = strchr(sub, '.');
|
||||
if (p)
|
||||
{
|
||||
for (i = 0; subtypes[i]; i++)
|
||||
{
|
||||
strcpy(p, subtypes[i]);
|
||||
if (ecore_file_exists(sub))
|
||||
{
|
||||
video_sub_file_set(obj, sub);
|
||||
found = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) video_sub_file_set(obj, NULL);
|
||||
}
|
||||
else video_sub_file_set(obj, sub);
|
||||
video_file_set(obj, file);
|
||||
}
|
||||
|
||||
// emotion_object_seekable_get
|
||||
// emotion_object_play_speed_set
|
||||
// emotion_object_play_speed_get
|
||||
|
@ -962,7 +1009,6 @@ video_meta_album_get(Evas_Object *obj)
|
|||
// emotion_object_buffer_size_get
|
||||
// emotion_object_video_mute_set
|
||||
// emotion_object_video_mute_get
|
||||
// emotion_object_video_subtitle_file_set
|
||||
// emotion_object_spu_mute_set
|
||||
// emotion_object_spu_mute_get
|
||||
// emotion_object_progress_info_get
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
Evas_Object *video_add(Evas_Object *parent);
|
||||
void video_file_set(Evas_Object *obj, const char *file);
|
||||
const char *video_file_get(Evas_Object *obj);
|
||||
void video_sub_file_set(Evas_Object *obj, const char *file);
|
||||
void video_mute_set(Evas_Object *obj, Eina_Bool mute);
|
||||
Eina_Bool video_mute_get(Evas_Object *obj);
|
||||
void video_play_set(Evas_Object *obj, Eina_Bool play);
|
||||
|
@ -51,5 +52,6 @@ Eina_Bool video_lowquality_get(Evas_Object *obj);
|
|||
const char *video_meta_title_get(Evas_Object *obj);
|
||||
const char *video_meta_artist_get(Evas_Object *obj);
|
||||
const char *video_meta_album_get(Evas_Object *obj);
|
||||
void video_file_autosub_set(Evas_Object *obj, const char *file, const char *sub);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,13 +32,18 @@ static void
|
|||
_cb_win_del(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *ev EINA_UNUSED)
|
||||
{
|
||||
Inf *inf = evas_object_data_get(obj, "inf");
|
||||
const char *f;
|
||||
Winvid_Entry *vid;
|
||||
|
||||
if (inf->next_job) ecore_job_del(inf->next_job);
|
||||
if (inf->show_timeout) ecore_timer_del(inf->show_timeout);
|
||||
if (inf->drag_anim) ecore_animator_del(inf->drag_anim);
|
||||
if (inf->mouse_idle_timeout) ecore_timer_del(inf->mouse_idle_timeout);
|
||||
EINA_LIST_FREE(inf->file_list, f) eina_stringshare_del(f);
|
||||
EINA_LIST_FREE(inf->file_list, vid)
|
||||
{
|
||||
if (vid->file) eina_stringshare_del(vid->file);
|
||||
if (vid->sub) eina_stringshare_del(vid->sub);
|
||||
free(vid);
|
||||
}
|
||||
evas_object_data_del(obj, "inf");
|
||||
free(inf);
|
||||
}
|
||||
|
@ -156,11 +161,11 @@ win_do_next(Evas_Object *win)
|
|||
}
|
||||
|
||||
static void
|
||||
_restart_vid(Evas_Object *win, Evas_Object *lay, Evas_Object *vid, const char *file)
|
||||
_restart_vid(Evas_Object *win, Evas_Object *lay, Evas_Object *vid, const char *file, const char *sub)
|
||||
{
|
||||
video_position_set(vid, 0.0);
|
||||
video_play_set(vid, EINA_FALSE);
|
||||
video_file_set(vid, file);
|
||||
video_file_autosub_set(vid, file, sub);
|
||||
video_position_set(vid, 0.0);
|
||||
video_play_set(vid, EINA_TRUE);
|
||||
elm_layout_signal_emit(lay, "action,newvid", "rage");
|
||||
|
@ -172,7 +177,8 @@ void
|
|||
win_video_restart(Evas_Object *win)
|
||||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
_restart_vid(win, inf->lay, inf->vid, inf->file_cur->data);
|
||||
Winvid_Entry *vid = inf->file_cur->data;
|
||||
_restart_vid(win, inf->lay, inf->vid, vid->file, vid->sub);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -180,6 +186,7 @@ win_video_next(Evas_Object *win)
|
|||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Eina_List *l;
|
||||
Winvid_Entry *vid;
|
||||
|
||||
if (!inf->file_list) return;
|
||||
if (!inf->file_cur) l = inf->file_list;
|
||||
|
@ -190,7 +197,8 @@ win_video_next(Evas_Object *win)
|
|||
return;
|
||||
}
|
||||
inf->file_cur = l;
|
||||
_restart_vid(win, inf->lay, inf->vid, l->data);
|
||||
vid = l->data;
|
||||
_restart_vid(win, inf->lay, inf->vid, vid->file, vid->sub);
|
||||
win_list_sel_update(win);
|
||||
}
|
||||
|
||||
|
@ -199,13 +207,15 @@ win_video_prev(Evas_Object *win)
|
|||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Eina_List *l;
|
||||
Winvid_Entry *vid;
|
||||
|
||||
if (!inf->file_list) return;
|
||||
if (!inf->file_cur) l = eina_list_last(inf->file_list);
|
||||
else l = inf->file_cur->prev;
|
||||
if (!l) return;
|
||||
inf->file_cur = l;
|
||||
_restart_vid(win, inf->lay, inf->vid, l->data);
|
||||
vid = l->data;
|
||||
_restart_vid(win, inf->lay, inf->vid, vid->file, vid->sub);
|
||||
win_list_sel_update(win);
|
||||
}
|
||||
|
||||
|
@ -214,11 +224,13 @@ win_video_first(Evas_Object *win)
|
|||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Eina_List *l;
|
||||
Winvid_Entry *vid;
|
||||
|
||||
if (!inf->file_list) return;
|
||||
l = inf->file_list;
|
||||
inf->file_cur = l;
|
||||
_restart_vid(win, inf->lay, inf->vid, l->data);
|
||||
vid = l->data;
|
||||
_restart_vid(win, inf->lay, inf->vid, vid->file, vid->sub);
|
||||
win_list_sel_update(win);
|
||||
}
|
||||
|
||||
|
@ -227,12 +239,14 @@ win_video_last(Evas_Object *win)
|
|||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Eina_List *l;
|
||||
Winvid_Entry *vid;
|
||||
|
||||
if (!inf->file_list) return;
|
||||
l = eina_list_last(inf->file_list);
|
||||
if (!l) return;
|
||||
inf->file_cur = l;
|
||||
_restart_vid(win, inf->lay, inf->vid, l->data);
|
||||
vid = l->data;
|
||||
_restart_vid(win, inf->lay, inf->vid, vid->file, vid->sub);
|
||||
win_list_sel_update(win);
|
||||
}
|
||||
|
||||
|
@ -343,13 +357,15 @@ win_title_update(Evas_Object *win)
|
|||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
const char *file, *s;
|
||||
char buf[4096];
|
||||
Winvid_Entry *vid;
|
||||
|
||||
if (!inf->file_cur)
|
||||
{
|
||||
elm_win_title_set(win, "Rage");
|
||||
return;
|
||||
}
|
||||
file = inf->file_cur->data;
|
||||
vid = inf->file_cur->data;
|
||||
file = vid->file;
|
||||
if (!file)
|
||||
{
|
||||
elm_win_title_set(win, "Rage");
|
||||
|
|
|
@ -66,9 +66,10 @@ _cb_pos_eval(void *data)
|
|||
const char *f;
|
||||
|
||||
f = evas_object_data_get(obj, "file");
|
||||
video_file_autosub_set(obj, f, NULL);
|
||||
video_mute_set(obj, EINA_TRUE);
|
||||
video_play_set(obj, EINA_TRUE);
|
||||
video_loop_set(obj, EINA_TRUE);
|
||||
video_file_set(obj, f);
|
||||
evas_object_data_set(obj, "active", obj);
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +78,7 @@ _cb_pos_eval(void *data)
|
|||
if (evas_object_data_get(obj, "active"))
|
||||
{
|
||||
video_play_set(obj, EINA_FALSE);
|
||||
video_file_set(obj, NULL);
|
||||
video_file_autosub_set(obj, NULL, NULL);
|
||||
video_position_set(obj, 0.0);
|
||||
evas_object_data_del(obj, "active");
|
||||
evas_object_data_del(obj, "ready");
|
||||
|
@ -150,7 +151,8 @@ _fill_box(Evas_Object *win)
|
|||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Eina_List *l;
|
||||
const char *f, *s;
|
||||
Winvid_Entry *vid;
|
||||
const char *s;
|
||||
Evas_Object *o, *base, *rect;
|
||||
char buf[4096];
|
||||
Evas_Coord w, h, sz = 0;
|
||||
|
@ -161,7 +163,7 @@ _fill_box(Evas_Object *win)
|
|||
h = h / 8;
|
||||
if (w < sz) w = sz;
|
||||
if (h < sz) h = sz;
|
||||
EINA_LIST_FOREACH(inf->file_list, l, f)
|
||||
EINA_LIST_FOREACH(inf->file_list, l, vid)
|
||||
{
|
||||
base = o = elm_layout_add(win);
|
||||
elm_object_focus_allow_set(o, EINA_FALSE);
|
||||
|
@ -172,11 +174,9 @@ _fill_box(Evas_Object *win)
|
|||
elm_layout_signal_callback_add(o, "rage,selected", "rage", _cb_selected, win);
|
||||
evas_object_data_set(o, "list", l);
|
||||
|
||||
s = ecore_file_file_get(f);
|
||||
if ((s) && (s[0] != 0))
|
||||
elm_object_part_text_set(o, "rage.title", s);
|
||||
else
|
||||
elm_object_part_text_set(o, "rage.title", f);
|
||||
s = ecore_file_file_get(vid->file);
|
||||
if ((s) && (s[0] != 0)) elm_object_part_text_set(o, "rage.title", s);
|
||||
else elm_object_part_text_set(o, "rage.title", vid->file);
|
||||
|
||||
rect = o = evas_object_rectangle_add(evas_object_evas_get(win));
|
||||
evas_object_color_set(rect, 0, 0, 0, 0);
|
||||
|
@ -198,7 +198,7 @@ _fill_box(Evas_Object *win)
|
|||
evas_object_event_callback_add(o, EVAS_CALLBACK_RESIZE, _cb_vid_resize, win);
|
||||
evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _cb_vid_del, win);
|
||||
|
||||
evas_object_data_set(o, "file", f);
|
||||
evas_object_data_set(o, "file", vid->file);
|
||||
elm_object_part_content_set(base, "rage.content", o);
|
||||
evas_object_show(o);
|
||||
|
||||
|
|
|
@ -208,11 +208,19 @@ win_video_file_list_set(Evas_Object *win, Eina_List *list)
|
|||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Eina_List *l, *list2 = NULL;
|
||||
const char *f;
|
||||
Winvid_Entry *vid;
|
||||
|
||||
EINA_LIST_FOREACH(list, l, f)
|
||||
EINA_LIST_FOREACH(list, l, vid)
|
||||
{
|
||||
list2 = eina_list_append(list2, eina_stringshare_add(f));
|
||||
Winvid_Entry *vid2;
|
||||
|
||||
vid2 = calloc(1, sizeof(Winvid_Entry));
|
||||
if (vid2)
|
||||
{
|
||||
if (vid->file) vid2->file = eina_stringshare_add(vid->file);
|
||||
if (vid->sub) vid2->sub = eina_stringshare_add(vid->sub);
|
||||
list2 = eina_list_append(list2, vid2);
|
||||
}
|
||||
}
|
||||
inf->file_list = list2;
|
||||
win_video_next(win);
|
||||
|
@ -222,9 +230,12 @@ void
|
|||
win_video_insert(Evas_Object *win, const char *file)
|
||||
{
|
||||
Inf *inf = evas_object_data_get(win, "inf");
|
||||
Winvid_Entry *vid;
|
||||
|
||||
inf->file_list = eina_list_append_relative_list
|
||||
(inf->file_list, eina_stringshare_add(file), inf->file_cur);
|
||||
vid = calloc(1, sizeof(Winvid_Entry));
|
||||
vid->file = eina_stringshare_add(file);
|
||||
inf->file_list = eina_list_append_relative_list(inf->file_list, vid,
|
||||
inf->file_cur);
|
||||
evas_object_data_set(win, "file_list", inf->file_list);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#ifndef _WINVID_H__
|
||||
#define _WINVID_H__ 1
|
||||
|
||||
typedef struct _Winvid_Entry
|
||||
{
|
||||
const char *file;
|
||||
const char *sub;
|
||||
} Winvid_Entry;
|
||||
|
||||
void win_video_init(Evas_Object *win);
|
||||
void win_video_file_list_set(Evas_Object *win, Eina_List *list);
|
||||
void win_video_insert(Evas_Object *win, const char *file);
|
||||
|
|
Loading…
Reference in New Issue