add subtitle support into rage on cmdline as well as automatic

This commit is contained in:
Carsten Haitzler 2014-08-23 19:29:10 +09:00
parent 143db13878
commit c2472804f9
9 changed files with 165 additions and 53 deletions

10
README
View File

@ -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
View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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");

View File

@ -13,7 +13,7 @@ static void
_ready(Evas_Object *obj)
{
int w = 1, h = 1;
if (evas_object_data_get(obj, "ready")) return;
evas_object_data_set(obj, "ready", obj);
video_position_set(obj, video_length_get(obj) / 2.0);
@ -25,7 +25,7 @@ static void
_bring(Evas_Object *obj)
{
Evas_Coord x, y, w, h, px, py;
evas_object_geometry_get(obj, &x, &y, &w, &h);
evas_object_geometry_get(bx, &px, &py, NULL, NULL);
elm_scroller_region_bring_in(sc, x - px, y - py, w, h);
@ -56,7 +56,7 @@ _cb_pos_eval(void *data)
{
Evas_Object *obj = data;
Evas_Coord x, y, w, h, vx, vy, vw, vh;
evas_object_geometry_get(obj, &x, &y, &w, &h);
evas_output_viewport_get(evas_object_evas_get(obj), &vx, &vy, &vw, &vh);
if (ELM_RECTS_INTERSECT(x, y, w, h, vx, vy, vw, vh))
@ -64,11 +64,12 @@ _cb_pos_eval(void *data)
if (!evas_object_data_get(obj, "active"))
{
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");
@ -124,7 +125,7 @@ _sel(Evas_Object *obj)
Eina_List *items = elm_box_children_get(bx);
Eina_List *l;
Evas_Object *o;
EINA_LIST_FOREACH(items, l, o)
{
if (evas_object_data_get(o, "selected"))
@ -150,18 +151,19 @@ _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;
elm_coords_finger_size_adjust(1, &sz, 1, &sz);
evas_object_geometry_get(win, NULL, NULL, &w, &h);
w = w / 8;
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);
@ -171,19 +173,17 @@ _fill_box(Evas_Object *win)
evas_object_size_hint_align_set(o, -1.0, 0.5);
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);
elm_object_part_content_set(base, "rage.sizer", o);
evas_object_data_set(base, "sizer", o);
evas_object_size_hint_min_set(o, w, h);
o = video_add(win);
video_art_set(o, EINA_TRUE);
evas_object_data_set(o, "base", base);
@ -193,18 +193,18 @@ _fill_box(Evas_Object *win)
video_lowquality_set(o, EINA_TRUE);
evas_object_smart_callback_add(o, "opened", _cb_opened, win);
evas_object_smart_callback_add(o, "length", _cb_length, win);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOVE, _cb_vid_move, 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);
elm_box_pack_end(bx, base);
evas_object_show(base);
if (l == inf->file_cur)
{
evas_object_data_set(base, "selected", base);
@ -219,7 +219,7 @@ void
win_list_show(Evas_Object *win)
{
Inf *inf = evas_object_data_get(win, "inf");
if (tb) return;
tb = elm_table_add(win);
evas_object_show(tb);
@ -237,20 +237,20 @@ win_list_show(Evas_Object *win)
elm_scroller_content_min_limit(sc, EINA_TRUE, EINA_FALSE);
elm_table_pack(tb, sc, 0, 0, 1, 1);
evas_object_show(sc);
bx = elm_box_add(win);
elm_object_focus_allow_set(bx, EINA_FALSE);
evas_object_size_hint_weight_set(bx, 1.0, 0.0);
evas_object_size_hint_align_set(bx, -1.0, 0.0);
elm_box_homogeneous_set(bx, EINA_TRUE);
_fill_box(win);
elm_object_content_set(sc, bx);
evas_object_show(bx);
elm_object_part_content_set(inf->lay, "rage.list", tb);
elm_layout_signal_emit(inf->lay, "list,state,visible", "rage");
}
@ -267,7 +267,7 @@ void
win_list_hide(Evas_Object *win)
{
Inf *inf = evas_object_data_get(win, "inf");
if (!tb) return;
if (bring_timer) ecore_timer_del(bring_timer);
bring_timer = NULL;
@ -291,7 +291,7 @@ win_list_sel_update(Evas_Object *win)
Eina_List *items = elm_box_children_get(bx);
Eina_List *l;
Evas_Object *o;
EINA_LIST_FOREACH(items, l, o)
{
if (inf->file_cur == evas_object_data_get(o, "list"))
@ -312,7 +312,7 @@ win_list_size_update(Evas_Object *win)
Eina_List *l;
Evas_Object *o;
Evas_Coord w, h, sz = 0;
elm_coords_finger_size_adjust(1, &sz, 1, &sz);
evas_object_geometry_get(win, NULL, NULL, &w, &h);
w = w / 8;

View File

@ -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);
}

View File

@ -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);