mirror of https://github.com/mpv-player/mpv
js: reimplement subprocess using the subprocess command (match 548ef078
)
Semantics changes are the same as at 548ef078
.
Also, the previous C implementation returnd a string for the `stdout`
value, but stdout of the subprocess command is MPV_FORMAT_BYTE_ARRAY
which js previously didn't support, so support it too (at pushnode)
by returning it as a string - the same as the lua code does.
This commit is contained in:
parent
5b5f776900
commit
fea39b5a6b
|
@ -920,31 +920,8 @@ static void script_get_user_path(js_State *J, void *af)
|
|||
js_pushstring(J, mp_get_user_path(af, jctx(J)->mpctx->global, path));
|
||||
}
|
||||
|
||||
struct subprocess_cb_ctx {
|
||||
struct mp_log *log;
|
||||
void *talloc_ctx;
|
||||
int64_t max_size;
|
||||
bstr output;
|
||||
bstr err;
|
||||
};
|
||||
|
||||
static void subprocess_stdout(void *p, char *data, size_t size)
|
||||
{
|
||||
struct subprocess_cb_ctx *ctx = p;
|
||||
if (ctx->output.len < ctx->max_size)
|
||||
bstr_xappend(ctx->talloc_ctx, &ctx->output, (bstr){data, size});
|
||||
}
|
||||
|
||||
static void subprocess_stderr(void *p, char *data, size_t size)
|
||||
{
|
||||
struct subprocess_cb_ctx *ctx = p;
|
||||
if (ctx->err.len < ctx->max_size)
|
||||
bstr_xappend(ctx->talloc_ctx, &ctx->err, (bstr){data, size});
|
||||
MP_INFO(ctx, "%.*s", (int)size, data);
|
||||
}
|
||||
|
||||
// args: client invocation args object. TODO: use common backend for js/lua
|
||||
static void af_subprocess_common(js_State *J, int detach, void *af)
|
||||
// args: client invocation args object
|
||||
static void script_subprocess_detached(js_State *J, void *af)
|
||||
{
|
||||
struct script_ctx *ctx = jctx(J);
|
||||
if (!js_isobject(J, 1))
|
||||
|
@ -969,52 +946,8 @@ static void af_subprocess_common(js_State *J, int detach, void *af)
|
|||
}
|
||||
args[num_args] = NULL;
|
||||
|
||||
if (detach) {
|
||||
mp_subprocess_detached(ctx->log, args);
|
||||
push_success(J);
|
||||
return;
|
||||
}
|
||||
|
||||
struct mp_cancel *cancel = NULL;
|
||||
if (js_hasproperty(J, 1, "cancellable") ? js_toboolean(J, -1) : true)
|
||||
cancel = ctx->mpctx->playback_abort;
|
||||
|
||||
int64_t max_size = js_hasproperty(J, 1, "max_size") ? js_tointeger(J, -1)
|
||||
: 16 * 1024 * 1024;
|
||||
struct subprocess_cb_ctx cb_ctx = {
|
||||
.log = ctx->log,
|
||||
.talloc_ctx = af,
|
||||
.max_size = max_size,
|
||||
};
|
||||
|
||||
char *error = NULL;
|
||||
int status = mp_subprocess(args, cancel, &cb_ctx, subprocess_stdout,
|
||||
subprocess_stderr, &error);
|
||||
|
||||
js_newobject(J); // res
|
||||
if (error) {
|
||||
js_pushstring(J, error); // res e
|
||||
js_setproperty(J, -2, "error"); // res
|
||||
}
|
||||
js_pushnumber(J, status); // res s
|
||||
js_setproperty(J, -2, "status"); // res
|
||||
js_pushlstring(J, cb_ctx.output.start, cb_ctx.output.len); // res d
|
||||
js_setproperty(J, -2, "stdout"); // res
|
||||
js_pushlstring(J, cb_ctx.err.start, cb_ctx.err.len);
|
||||
js_setproperty(J, -2, "stderr");
|
||||
js_pushboolean(J, status == MP_SUBPROCESS_EKILLED_BY_US); // res b
|
||||
js_setproperty(J, -2, "killed_by_us"); // res
|
||||
}
|
||||
|
||||
// args: client invocation args object (same also for _detached)
|
||||
static void script_subprocess(js_State *J, void *af)
|
||||
{
|
||||
af_subprocess_common(J, 0, af);
|
||||
}
|
||||
|
||||
static void script_subprocess_detached(js_State *J, void *af)
|
||||
{
|
||||
af_subprocess_common(J, 1, af);
|
||||
mp_subprocess_detached(ctx->log, args);
|
||||
push_success(J);
|
||||
}
|
||||
|
||||
// args: none
|
||||
|
@ -1084,6 +1017,9 @@ static void pushnode(js_State *J, mpv_node *node)
|
|||
case MPV_FORMAT_INT64: js_pushnumber(J, node->u.int64); break;
|
||||
case MPV_FORMAT_DOUBLE: js_pushnumber(J, node->u.double_); break;
|
||||
case MPV_FORMAT_FLAG: js_pushboolean(J, node->u.flag); break;
|
||||
case MPV_FORMAT_BYTE_ARRAY:
|
||||
js_pushlstring(J, node->u.ba->data, node->u.ba->size);
|
||||
break;
|
||||
case MPV_FORMAT_NODE_ARRAY:
|
||||
js_newarray(J);
|
||||
len = node->u.list->num;
|
||||
|
@ -1360,7 +1296,6 @@ static const struct fn_entry utils_fns[] = {
|
|||
FN_ENTRY(split_path, 1),
|
||||
AF_ENTRY(join_path, 2),
|
||||
AF_ENTRY(get_user_path, 1),
|
||||
AF_ENTRY(subprocess, 1),
|
||||
AF_ENTRY(subprocess_detached, 1),
|
||||
FN_ENTRY(getpid, 0),
|
||||
|
||||
|
|
|
@ -538,6 +538,20 @@ mp.osd_message = function osd_message(text, duration) {
|
|||
mp.commandv("show_text", text, Math.round(1000 * (duration || -1)));
|
||||
}
|
||||
|
||||
mp.utils.subprocess = function subprocess(t) {
|
||||
var cmd = { name: "subprocess", capture_stdout: true };
|
||||
var new_names = { cancellable: "playback_only", max_size: "capture_size" };
|
||||
for (var k in t)
|
||||
cmd[new_names[k] || k] = t[k];
|
||||
|
||||
var rv = mp.command_native(cmd);
|
||||
if (mp.last_error()) /* typically on missing/incorrect args */
|
||||
rv = { error_string: mp.last_error(), status: -1 };
|
||||
if (rv.error_string)
|
||||
rv.error = rv.error_string;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// ----- dump: like print, but expands objects/arrays recursively -----
|
||||
function replacer(k, v) {
|
||||
var t = typeof v;
|
||||
|
|
Loading…
Reference in New Issue