summaryrefslogtreecommitdiff
path: root/ytdl-storyboard/storyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'ytdl-storyboard/storyboard.c')
-rw-r--r--ytdl-storyboard/storyboard.c125
1 files changed, 114 insertions, 11 deletions
diff --git a/ytdl-storyboard/storyboard.c b/ytdl-storyboard/storyboard.c
index cbc2d9f..ff4ccdf 100644
--- a/ytdl-storyboard/storyboard.c
+++ b/ytdl-storyboard/storyboard.c
@@ -23,12 +23,18 @@ struct plugin{
mpv_handle *m;
struct storyboard *sb;
int64_t osd_remove_time_ns;
+ int64_t osc_check_time_ns;
+ int64_t osc_last_checked_ns;
+ int show_on_seek;
};
enum hooknumber{
HOOK_PRELOADED,
HOOK_UNLOAD
};
+enum observenumber{
+ OBSERVE_OSC,
+};
enum overlay_nums{
OSD_STORYBOARD = 1,
};
@@ -471,9 +477,20 @@ static int plugin_init(struct plugin *self, mpv_handle *h){
self->m = h;
self->sb = NULL;
self->osd_remove_time_ns = 0;
+ self->osc_check_time_ns = 0;
+ self->osc_last_checked_ns = 0;
+ self->show_on_seek = 1;
TRY(mpv_hook_add(self->m, HOOK_PRELOADED, "on_preloaded", 0), "hook_add");
TRY(mpv_hook_add(self->m, HOOK_UNLOAD, "on_unload", 0), "hook_add");
+ TRY(mpv_observe_property(self->m, OBSERVE_OSC,
+ "user-data/osc/seekbar/possec", MPV_FORMAT_NONE),
+ "mpv_observe_property");
+ TRY(mpv_observe_property(self->m, OBSERVE_OSC,
+ "user-data/osc/visible", MPV_FORMAT_NONE), "mpv_observe_property");
+ TRY(mpv_observe_property(self->m, OBSERVE_OSC,
+ "user-data/osc/active-element", MPV_FORMAT_NONE),
+ "mpv_observe_property");
return 0;
}
@@ -551,27 +568,80 @@ static int hook_on_unload(struct plugin *self){
}
return 0;
}
+static int show_storyboard(struct plugin *self, double pos){
+ uint8_t *img;
+ if(storyboard_getimg(self->sb, &img, pos)) return 0;
+ overlay_add(self, OSD_STORYBOARD, 0, 0,
+ img, 0, self->sb->width, self->sb->height, self->sb->width*4,
+ self->sb->width, self->sb->height
+ );
+ return 0;
+}
static int event_on_seek(struct plugin *self){
if(!self->sb) return 0;
- uint8_t *img;
+ if(!self->show_on_seek) return 0;
double pos;
TRY(mpv_get_property(self->m, "time-pos", MPV_FORMAT_DOUBLE, &pos),
"mpv_get_property");
- if(storyboard_getimg(self->sb, &img, pos)) return 0;
- overlay_add(self, OSD_STORYBOARD, 0, 0,
- img, 0, self->sb->width, self->sb->height, self->sb->width*4,
- self->sb->width, self->sb->height
- );
+ Z(show_storyboard(self, pos));
self->osd_remove_time_ns = mpv_get_time_ns(self->m) + 1*1000*1000*1000;
if(self->osd_remove_time_ns == 0) self->osd_remove_time_ns = 1;
return 0;
}
+static int osc_check(struct plugin *self, int64_t now){
+ char *actelem = NULL;
+ self->osc_last_checked_ns = now ? now : -1;
+ if(!self->sb) return 0;
+
+ int visible;
+ if(mpv_get_property(self->m,
+ "user-data/osc/visible", MPV_FORMAT_FLAG, &visible)
+ ) goto stop;
+ if(!visible) goto stop;
+ self->show_on_seek = 0;
+ if(mpv_get_property(self->m,
+ "user-data/osc/active-element", MPV_FORMAT_STRING, &actelem)
+ ) goto stop;
+ if(strcmp(actelem, "\"seekbar\"")) goto stop; // XXX: quoted
+ mpv_free(actelem);
+ double pos;
+ if(mpv_get_property(self->m,
+ "user-data/osc/seekbar/possec", MPV_FORMAT_DOUBLE, &pos)
+ ) goto stop;
+
+ Z(show_storyboard(self, pos));
+
+ return 0;
+stop:
+ mpv_free(actelem);
+ overlay_remove(self, OSD_STORYBOARD);
+ return 0;
+}
+static int event_on_observe_osc(struct plugin *self, mpv_event_property *prop){
+ int64_t now = mpv_get_time_ns(self->m);
+ if(self->osc_last_checked_ns
+ && now - self->osc_last_checked_ns < 20*1000*1000
+ ){
+ if(!self->osc_check_time_ns){
+ self->osc_check_time_ns = now + 20*1000*1000;
+ if(!self->osc_check_time_ns) self->osc_check_time_ns = 1;
+ }
+ }else{
+ self->osc_check_time_ns = 0;
+ Z(osc_check(self, now));
+ }
+ return 0;
+}
static int timeout_handler_osd_remove(struct plugin *self, int64_t now){
overlay_remove(self, OSD_STORYBOARD);
return 0;
}
+static int timeout_handler_osc_check(struct plugin *self, int64_t now){
+ Z(osc_check(self, now));
+ return 0;
+}
static int event_handler(struct plugin *self, const mpv_event *ev){
switch(ev->event_id){
case MPV_EVENT_HOOK:
@@ -591,23 +661,56 @@ static int event_handler(struct plugin *self, const mpv_event *ev){
case MPV_EVENT_SEEK:
Z(event_on_seek(self));
return 0;
+ case MPV_EVENT_PROPERTY_CHANGE:
+ mpv_event_property *prop = ev->data;
+ switch(ev->reply_userdata){
+ case OBSERVE_OSC:
+ Z(event_on_observe_osc(self, prop));
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+ return 0;
default:
return 0;
}
}
static double event_wait_timeout(struct plugin *self){
+ double next = -1;
+ int64_t now = mpv_get_time_ns(self->m);
+
+recheck_osd_remove:
if(self->osd_remove_time_ns){
- int64_t now = mpv_get_time_ns(self->m);
if(self->osd_remove_time_ns <= now){
self->osd_remove_time_ns = 0;
timeout_handler_osd_remove(self, now);
- return event_wait_timeout(self);
+ goto recheck_osd_remove;
}else{
- return (self->osd_remove_time_ns - now) / 1.0e9;
+ double mynext = (self->osd_remove_time_ns - now) / 1.0e9;
+ if(mynext < 0) mynext = 0;
+ if(next >= 0 && mynext < next){
+ next = mynext;
+ }
}
- }else{
- return -1;
}
+
+recheck_osc_check:
+ if(self->osc_check_time_ns){
+ if(self->osc_check_time_ns <= now){
+ self->osc_check_time_ns = 0;
+ timeout_handler_osc_check(self, now);
+ goto recheck_osc_check;
+ }else{
+ double mynext = (self->osc_check_time_ns - now) / 1.0e9;
+ if(mynext < 0) mynext = 0;
+ if(next >= 0 && mynext < next){
+ next = mynext;
+ }
+ }
+ }
+
+ return next;
}
int mpv_open_cplugin(mpv_handle *h){