diff options
Diffstat (limited to 'ytdl-storyboard/storyboard.c')
-rw-r--r-- | ytdl-storyboard/storyboard.c | 125 |
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){ |