diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index 8472da4ff2..ae0d23a884 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -86,6 +86,10 @@ Interface changes has been added to the manpage describing some conflicting behavior between options and properties) - implement changing sub-speed during playback + - make many previously fixed options changeable at runtime (for example + --terminal, --osc, --ytdl, can all be enable/disabled after + mpv_initialize() - this can be extended to other still fixed options + on user requests) --- mpv 0.20.0 --- - add --image-display-duration option - this also means that image duration is not influenced by --mf-fps anymore in the general case (this is an diff --git a/options/m_option.h b/options/m_option.h index 74af6b732e..20b671df4e 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -385,7 +385,8 @@ struct m_option { #define UPDATE_RENDERER (1 << 15) // mainly vo_opengl options #define UPDATE_VIDEOPOS (1 << 16) // video position (panscan etc.) #define UPDATE_OSD (1 << 17) // related to OSD rendering -#define UPDATE_OPT_LAST (1 << 17) +#define UPDATE_BUILTIN_SCRIPTS (1 << 18) // osc/ytdl +#define UPDATE_OPT_LAST (1 << 18) // All bits between _FIRST and _LAST (inclusive) #define UPDATE_OPTS_MASK \ diff --git a/options/options.c b/options/options.c index df2888f5f9..533dda244c 100644 --- a/options/options.c +++ b/options/options.c @@ -282,8 +282,8 @@ const m_option_t mp_opts[] = { #if HAVE_LUA OPT_STRINGLIST("script", script_files, CONF_GLOBAL | M_OPT_FILE), OPT_KEYVALUELIST("script-opts", script_opts, 0), - OPT_FLAG("osc", lua_load_osc, CONF_GLOBAL), - OPT_FLAG("ytdl", lua_load_ytdl, CONF_GLOBAL), + OPT_FLAG("osc", lua_load_osc, UPDATE_BUILTIN_SCRIPTS), + OPT_FLAG("ytdl", lua_load_ytdl, UPDATE_BUILTIN_SCRIPTS), OPT_STRING("ytdl-format", lua_ytdl_format, 0), OPT_KEYVALUELIST("ytdl-raw-options", lua_ytdl_raw_options, 0), OPT_FLAG("load-scripts", auto_load_scripts, CONF_GLOBAL), diff --git a/player/command.c b/player/command.c index d6c0f9cf08..d5d95602a6 100644 --- a/player/command.c +++ b/player/command.c @@ -5603,6 +5603,9 @@ void mp_option_change_callback(void *ctx, struct m_config_option *co, int flags) osd_changed(mpctx->osd); mp_wakeup_core(mpctx); } + + if (flags & UPDATE_BUILTIN_SCRIPTS) + mp_load_builtin_scripts(mpctx); } void mp_notify_property(struct MPContext *mpctx, const char *property) diff --git a/player/core.h b/player/core.h index df2df834fa..d67a9d62ad 100644 --- a/player/core.h +++ b/player/core.h @@ -549,6 +549,7 @@ struct mp_scripting { int (*load)(struct mpv_handle *client, const char *filename); }; void mp_load_scripts(struct MPContext *mpctx); +void mp_load_builtin_scripts(struct MPContext *mpctx); // sub.c void reset_subtitle_state(struct MPContext *mpctx); diff --git a/player/scripting.c b/player/scripting.c index afa567ca6a..b6ba69ac07 100644 --- a/player/scripting.c +++ b/player/scripting.c @@ -176,13 +176,41 @@ static char **list_script_files(void *talloc_ctx, char *path) return files; } +static void load_builtin_script(struct MPContext *mpctx, bool enable, + const char *fname) +{ + void *tmp = talloc_new(NULL); + // (The name doesn't have to match if there were conflicts with other + // scripts, so this is on best-effort basis.) + char *name = script_name_from_filename(tmp, fname); + if (enable != mp_client_exists(mpctx, name)) { + if (enable) { + mp_load_script(mpctx, fname); + } else { + // Try to unload it by sending a shutdown event. Wait until it has + // terminated, or re-enabling the script could be racy (because it'd + // recognize a still-terminating script as "loaded"). + while (mp_client_exists(mpctx, name)) { + if (mp_client_send_event(mpctx, name, MPV_EVENT_SHUTDOWN, NULL) < 0) + break; + mp_idle(mpctx); + } + mp_wakeup_core(mpctx); // avoid lost wakeups during waiting + } + } + talloc_free(tmp); +} + +void mp_load_builtin_scripts(struct MPContext *mpctx) +{ + load_builtin_script(mpctx, mpctx->opts->lua_load_osc, "@osc.lua"); + load_builtin_script(mpctx, mpctx->opts->lua_load_ytdl, "@ytdl_hook.lua"); +} + void mp_load_scripts(struct MPContext *mpctx) { // Load scripts from options - if (mpctx->opts->lua_load_osc) - mp_load_script(mpctx, "@osc.lua"); - if (mpctx->opts->lua_load_ytdl) - mp_load_script(mpctx, "@ytdl_hook.lua"); + mp_load_builtin_scripts(mpctx); char **files = mpctx->opts->script_files; for (int n = 0; files && files[n]; n++) { if (files[n][0])