mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
scripting: add a way to run sub processes as "scripts"
This is just a more convenient way to start IPC client scripts per mpv instance. Does not work on Windows, although it could if the subprocess and IPC parts are implemented (and I guess .exe/.bat suffixes are required). Also untested whether it builds on Windows. A lot of other things are untested too, so don't complain.
This commit is contained in:
@@ -213,10 +213,20 @@ void mp_input_sdl_gamepad_add(struct input_ctx *ictx);
|
||||
|
||||
struct mp_ipc_ctx;
|
||||
struct mp_client_api;
|
||||
struct mpv_handle;
|
||||
|
||||
// Platform specific implementation, provided by ipc-*.c.
|
||||
struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
|
||||
struct mpv_global *global);
|
||||
// Start a thread for the given handle and return a socket in out_fd[0] that
|
||||
// is served by this thread. If the FD is not full-duplex, then out_fd[0] is
|
||||
// the user's read-end, and out_fd[1] the write-end, otherwise out_fd[1] is set
|
||||
// to -1.
|
||||
// returns:
|
||||
// true: out_fd[0] and out_fd[1] are set, ownership of h is transferred
|
||||
// false: out_fd are not touched, caller retains ownership of h
|
||||
bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
|
||||
int out_fd[2]);
|
||||
void mp_uninit_ipc(struct mp_ipc_ctx *ctx);
|
||||
|
||||
// Serialize the given mpv_event structure to JSON. Returns an allocated string.
|
||||
|
||||
@@ -8,6 +8,12 @@ struct mp_ipc_ctx *mp_init_ipc(struct mp_client_api *client_api,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
|
||||
int out_fd[2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void mp_uninit_ipc(struct mp_ipc_ctx *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ struct client_arg {
|
||||
struct mp_log *log;
|
||||
struct mpv_handle *client;
|
||||
|
||||
char *client_name;
|
||||
const char *client_name;
|
||||
int client_fd;
|
||||
bool close_client_fd;
|
||||
|
||||
@@ -215,9 +215,11 @@ done:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client)
|
||||
static bool ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client,
|
||||
bool free_on_init_fail)
|
||||
{
|
||||
client->client = mp_new_client(ctx->client_api, client->client_name);
|
||||
if (!client->client)
|
||||
client->client = mp_new_client(ctx->client_api, client->client_name);
|
||||
if (!client->client)
|
||||
goto err;
|
||||
|
||||
@@ -227,16 +229,19 @@ static void ipc_start_client(struct mp_ipc_ctx *ctx, struct client_arg *client)
|
||||
if (pthread_create(&client_thr, NULL, client_thread, client))
|
||||
goto err;
|
||||
|
||||
return;
|
||||
return true;
|
||||
|
||||
err:
|
||||
if (client->client)
|
||||
mpv_destroy(client->client);
|
||||
if (free_on_init_fail) {
|
||||
if (client->client)
|
||||
mpv_destroy(client->client);
|
||||
|
||||
if (client->close_client_fd)
|
||||
close(client->client_fd);
|
||||
if (client->close_client_fd)
|
||||
close(client->client_fd);
|
||||
}
|
||||
|
||||
talloc_free(client);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, int fd)
|
||||
@@ -246,11 +251,37 @@ static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, int fd)
|
||||
.client_name = talloc_asprintf(client, "ipc-%d", id),
|
||||
.client_fd = fd,
|
||||
.close_client_fd = true,
|
||||
|
||||
.writable = true,
|
||||
};
|
||||
|
||||
ipc_start_client(ctx, client);
|
||||
ipc_start_client(ctx, client, true);
|
||||
}
|
||||
|
||||
bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
|
||||
int out_fd[2])
|
||||
{
|
||||
int pair[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair))
|
||||
return false;
|
||||
|
||||
struct client_arg *client = talloc_ptrtype(NULL, client);
|
||||
*client = (struct client_arg){
|
||||
.client = h,
|
||||
.client_name = mpv_client_name(h),
|
||||
.client_fd = pair[1],
|
||||
.close_client_fd = true,
|
||||
.writable = true,
|
||||
};
|
||||
|
||||
if (!ipc_start_client(ctx, client, false)) {
|
||||
close(pair[0]);
|
||||
close(pair[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
out_fd[0] = pair[0];
|
||||
out_fd[1] = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ipc_start_client_text(struct mp_ipc_ctx *ctx, const char *path)
|
||||
@@ -292,7 +323,7 @@ static void ipc_start_client_text(struct mp_ipc_ctx *ctx, const char *path)
|
||||
.writable = writable,
|
||||
};
|
||||
|
||||
ipc_start_client(ctx, client);
|
||||
ipc_start_client(ctx, client, true);
|
||||
}
|
||||
|
||||
static void *ipc_thread(void *p)
|
||||
|
||||
@@ -335,6 +335,12 @@ static void ipc_start_client_json(struct mp_ipc_ctx *ctx, int id, HANDLE h)
|
||||
ipc_start_client(ctx, client);
|
||||
}
|
||||
|
||||
bool mp_ipc_start_anon_client(struct mp_ipc_ctx *ctx, struct mpv_handle *h,
|
||||
int out_fd[2])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void *ipc_thread(void *p)
|
||||
{
|
||||
// Use PIPE_TYPE_MESSAGE | PIPE_READMODE_BYTE so message framing is
|
||||
|
||||
Reference in New Issue
Block a user