summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-03-21 19:31:58 +0100
committerwm4 <wm4@nowhere>2020-03-21 19:33:48 +0100
commit218d6643e940dde2a01260cf8def70efc100cd43 (patch)
treef7ce9e059456eeaa3e33b08d8fa96512573c6a99
parent7e885a3bc3af4df93681b6e760a34e59e2f47ef7 (diff)
downloadmpv-218d6643e940dde2a01260cf8def70efc100cd43.tar.bz2
mpv-218d6643e940dde2a01260cf8def70efc100cd43.tar.xz
client API, lua, ipc: unify event struct return
Both Lua and the JSON IPC code need to convert the mpv_event struct (and everything it points to) to Lua tables or JSON. I was getting sick of having to make the same changes to Lua and IPC. Do what has been done everywhere else, and let the core handle this by going through mpv_node (which is supposed to serve both Lua tables and JSON, and potentially other scripting language backends). Expose it as new libmpv API function. The new API is still a bit "rough" and support for other event types might be added in the future. This silently adds support for the playlist_entry_id fields to both Lua and JSON IPC. There is a small API change for Lua; I don't think this matters, so I didn't care about compatibility. The new code in client.c is mashed up from the Lua and the IPC code. The manpage additions are moved from the Lua docs, and made slightly more "general". Some danger for unintended regressions both in Lua and IPC. Also damn these node functions suck, expect crashes due to UB. Not sure why this became more code instead of less compared to before (according to the diff stat), even though some code duplication across Lua and IPC was removed. Software development sucks.
-rw-r--r--DOCS/client-api-changes.rst1
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/input.rst144
-rw-r--r--DOCS/man/lua.rst111
-rw-r--r--input/ipc.c108
-rw-r--r--libmpv/client.h25
-rw-r--r--libmpv/mpv.def1
-rw-r--r--player/client.c100
-rw-r--r--player/lua.c61
9 files changed, 294 insertions, 259 deletions
diff --git a/DOCS/client-api-changes.rst b/DOCS/client-api-changes.rst
index 9a224c9f5b..2ccbc24e76 100644
--- a/DOCS/client-api-changes.rst
+++ b/DOCS/client-api-changes.rst
@@ -35,6 +35,7 @@ API changes
--- mpv 0.33.0 ---
1.108 - Deprecate MPV_EVENT_IDLE
- add mpv_event_start_file, mpv_event_end_file.playlist_entry_id
+ - add mpv_event_to_node()
1.107 - Remove the deprecated qthelper.hpp. This was obviously not part of the
libmpv API, only an "additionally" provided helper, thus this is not
considered an API change. If you are maintaining a project that relies
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 15be443190..d35164f718 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -54,6 +54,8 @@ Interface changes
Using the "playlist-play-index" command is recommended instead.
- add "playlist-play-index" command
- add playlist-current-pos, playlist-playing-pos properties
+ - Lua end-file events do not set the "error" field anymore, use "file_error"
+ instead.
--- mpv 0.32.0 ---
- change behavior when using legacy option syntax with options that start
with two dashes (``--`` instead of a ``-``). Now, using the recommended
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 60e024ebc9..a4567be3aa 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -1275,6 +1275,150 @@ Input Commands that are Possibly Subject to Change
Undocumented commands: ``ao-reload`` (experimental/internal).
+List of events
+~~~~~~~~~~~~~~
+
+This is a partial list of events. This section describes what
+``mpv_event_to_node()`` returns, and which is what scripting APIs and the JSON
+IPC sees. Note that the C API has separate C-level declarations with
+``mpv_event``, which may be slightly different.
+
+All events can have the following fields:
+
+``event``
+ Name as the event (as returned by ``mpv_event_name()``).
+
+``error``
+ Set to an error string (as returned by ``mpv_error_string()``). This field
+ is missing if no error happened, or the event type does not report error.
+ Most events leave this unset.
+
+This list uses the event name field value, and the C API symbol in brackets:
+
+``start-file`` (``MPV_EVENT_START_FILE``)
+ Happens right before a new file is loaded. When you receive this, the
+ player is loading the file (or possibly already done with it).
+
+ This has the following fields:
+
+ ``playlist_entry_id``
+ Playlist entry ID of the file being loaded now.
+
+``end-file`` (``MPV_EVENT_END_FILE``)
+ Happens after a file was unloaded. Typically, the player will load the
+ next file right away, or quit if this was the last file.
+
+ The event has the following fields:
+
+ ``reason``
+ Has one of these values:
+
+ ``eof``
+ The file has ended. This can (but doesn't have to) include
+ incomplete files or broken network connections under
+ circumstances.
+
+ ``stop``
+ Playback was ended by a command.
+
+ ``quit``
+ Playback was ended by sending the quit command.
+
+ ``error``
+ An error happened. In this case, an ``error`` field is present with
+ the error string.
+
+ ``redirect``
+ Happens with playlists and similar. Details see
+ ``MPV_END_FILE_REASON_REDIRECT`` in the C API.
+
+ ``unknown``
+ Unknown. Normally doesn't happen, unless the Lua API is out of sync
+ with the C API. (Likewise, it could happen that your script gets
+ reason strings that did not exist yet at the time your script was
+ written.)
+
+ ``playlist_entry_id``
+ Playlist entry ID of the file that was being played or attempted to be
+ played. This has the same value as the ``playlist_entry_id`` field in the
+ corresponding ``start-file`` event.
+
+ ``file_error``
+ Set to mpv error string describing the approximate reason why playback
+ failed. Unset if no error known. (In Lua scripting, this value was set
+ on the ``error`` field directly before mpv 0.33.0. Now the ``error``
+ field always indicates success, i.e. is not set.)
+
+``file-loaded`` (``MPV_EVENT_FILE_LOADED``)
+ Happens after a file was loaded and begins playback.
+
+``seek`` (``MPV_EVENT_SEEK``)
+ Happens on seeking. (This might include cases when the player seeks
+ internally, even without user interaction. This includes e.g. segment
+ changes when playing ordered chapters Matroska files.)
+
+``playback-restart`` (``MPV_EVENT_PLAYBACK_RESTART``)
+ Start of playback after seek or after file was loaded.
+
+``shutdown`` (``MPV_EVENT_SHUTDOWN``)
+ Sent when the player quits, and the script should terminate. Normally
+ handled automatically. See `Details on the script initialization and lifecycle`_.
+
+``log-message`` (``MPV_EVENT_LOG_MESSAGE``)
+ Receives messages enabled with ``mpv_request_log_messages()`` (Lua:
+ ``mp.enable_messages``).
+
+ This contains, in addition to the default event fields, the following
+ fields:
+
+ ``prefix``
+ The module prefix, identifies the sender of the message. This is what
+ the terminal player puts in front of the message text when using the
+ ``--v`` option, and is also what is used for ``--msg-level``.
+
+ ``level``
+ The log level as string. See ``msg.log`` for possible log level names.
+ Note that later versions of mpv might add new levels or remove
+ (undocumented) existing ones.
+
+ ``text``
+ The log message. The text will end with a newline character. Sometimes
+ it can contain multiple lines.
+
+ Keep in mind that these messages are meant to be hints for humans. You
+ should not parse them, and prefix/level/text of messages might change
+ any time.
+
+``hook``
+ The event has the following fields:
+
+ ``hook_id``
+ ID to pass to ``mpv_hook_continue()``. The Lua scripting wrapper
+ provides a better API around this with ``mp.add_hook()``.
+
+``get-property-reply`` (``MPV_EVENT_GET_PROPERTY_REPLY``)
+ Undocumented.
+
+``set-property-reply`` (``MPV_EVENT_SET_PROPERTY_REPLY``)
+ Undocumented.
+
+``command-reply`` (``MPV_EVENT_COMMAND_REPLY``)
+ Undocumented.
+
+``client-message`` (``MPV_EVENT_CLIENT_MESSAGE``)
+ Undocumented.
+
+``video-reconfig`` (``MPV_EVENT_VIDEO_RECONFIG``)
+ Happens on video output or filter reconfig.
+
+``audio-reconfig`` (``MPV_EVENT_AUDIO_RECONFIG``)
+ Happens on audio output or filter reconfig.
+
+The following events also happen, but are deprecated: ``tracks-changed``,
+``track-switched``, ``pause``, ``unpause``, ``metadata-update``, ``idle``,
+``tick``, ``chapter-change``. Use ``mpv_observe_property()``
+(Lua: ``mp.observe_property()``) instead.
+
Hooks
~~~~~
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst
index 339ec60dd1..b256d7bf2d 100644
--- a/DOCS/man/lua.rst
+++ b/DOCS/man/lua.rst
@@ -871,116 +871,7 @@ Example:
mp.register_event("file-loaded", my_fn)
-
-
-List of events
---------------
-
-``start-file``
- Happens right before a new file is loaded. When you receive this, the
- player is loading the file (or possibly already done with it).
-
-``end-file``
- Happens after a file was unloaded. Typically, the player will load the
- next file right away, or quit if this was the last file.
-
- The event has the ``reason`` field, which takes one of these values:
-
- ``eof``
- The file has ended. This can (but doesn't have to) include
- incomplete files or broken network connections under
- circumstances.
-
- ``stop``
- Playback was ended by a command.
-
- ``quit``
- Playback was ended by sending the quit command.
-
- ``error``
- An error happened. In this case, an ``error`` field is present with
- the error string.
-
- ``redirect``
- Happens with playlists and similar. Details see
- ``MPV_END_FILE_REASON_REDIRECT`` in the C API.
-
- ``unknown``
- Unknown. Normally doesn't happen, unless the Lua API is out of sync
- with the C API. (Likewise, it could happen that your script gets
- reason strings that did not exist yet at the time your script was
- written.)
-
-``file-loaded``
- Happens after a file was loaded and begins playback.
-
-``seek``
- Happens on seeking. (This might include cases when the player seeks
- internally, even without user interaction. This includes e.g. segment
- changes when playing ordered chapters Matroska files.)
-
-``playback-restart``
- Start of playback after seek or after file was loaded.
-
-``idle``
- Idle mode is entered. This happens when playback ended, and the player was
- started with ``--idle`` or ``--force-window``. This mode is implicitly ended
- when the ``start-file`` or ``shutdown`` events happen.
-
-``tick``
- Called after a video frame was displayed. This is a hack, and you should
- avoid using it. Use timers instead and maybe watch pausing/unpausing events
- to avoid wasting CPU when the player is paused. This is deprecated.
-
-``shutdown``
- Sent when the player quits, and the script should terminate. Normally
- handled automatically. See `Details on the script initialization and lifecycle`_.
-
-``log-message``
- Receives messages enabled with ``mp.enable_messages``. The message data
- is contained in the table passed as first parameter to the event handler.
- The table contains, in addition to the default event fields, the following
- fields:
-
- ``prefix``
- The module prefix, identifies the sender of the message. This is what
- the terminal player puts in front of the message text when using the
- ``--v`` option, and is also what is used for ``--msg-level``.
-
- ``level``
- The log level as string. See ``msg.log`` for possible log level names.
- Note that later versions of mpv might add new levels or remove
- (undocumented) existing ones.
-
- ``text``
- The log message. The text will end with a newline character. Sometimes
- it can contain multiple lines.
-
- Keep in mind that these messages are meant to be hints for humans. You
- should not parse them, and prefix/level/text of messages might change
- any time.
-
-``get-property-reply``
- Undocumented (not useful for Lua scripts).
-
-``set-property-reply``
- Undocumented (not useful for Lua scripts).
-
-``command-reply``
- Undocumented (not useful for Lua scripts).
-
-``client-message``
- Undocumented (used internally).
-
-``video-reconfig``
- Happens on video output or filter reconfig.
-
-``audio-reconfig``
- Happens on audio output or filter reconfig.
-
-The following events also happen, but are deprecated: ``tracks-changed``,
-``track-switched``, ``pause``, ``unpause``, ``metadata-update``,
-``chapter-change``. Use ``mp.observe_property()`` instead.
+For the existing event types, see `List of events`_.
Extras
------
diff --git a/input/ipc.c b/input/ipc.c
index 188b863338..1b35afc0ed 100644
--- a/input/ipc.c
+++ b/input/ipc.c
@@ -37,28 +37,6 @@ static mpv_node *mpv_node_array_get(mpv_node *src, int index)
return &src->u.list->values[index];
}
-static void mpv_node_array_add(void *ta_parent, mpv_node *src, mpv_node *val)
-{
- if (src->format != MPV_FORMAT_NODE_ARRAY)
- return;
-
- if (!src->u.list)
- src->u.list = talloc_zero(ta_parent, mpv_node_list);
-
- MP_TARRAY_GROW(src->u.list, src->u.list->values, src->u.list->num);
-
- static const struct m_option type = { .type = CONF_TYPE_NODE };
- m_option_get_node(&type, ta_parent, &src->u.list->values[src->u.list->num], val);
-
- src->u.list->num++;
-}
-
-static void mpv_node_array_add_string(void *ta_parent, mpv_node *src, const char *val)
-{
- mpv_node val_node = {.format = MPV_FORMAT_STRING, .u.string = (char *)val};
- mpv_node_array_add(ta_parent, src, &val_node);
-}
-
static void mpv_node_map_add(void *ta_parent, mpv_node *src, const char *key, mpv_node *val)
{
if (src->format != MPV_FORMAT_NODE_MAP)
@@ -84,25 +62,12 @@ static void mpv_node_map_add_null(void *ta_parent, mpv_node *src, const char *ke
mpv_node_map_add(ta_parent, src, key, &val_node);
}
-static void mpv_node_map_add_flag(void *ta_parent, mpv_node *src, const char *key, bool val)
-{
- mpv_node val_node = {.format = MPV_FORMAT_FLAG, .u.flag = val};
-
- mpv_node_map_add(ta_parent, src, key, &val_node);
-}
-
static void mpv_node_map_add_int64(void *ta_parent, mpv_node *src, const char *key, int64_t val)
{
mpv_node val_node = {.format = MPV_FORMAT_INT64, .u.int64 = val};
mpv_node_map_add(ta_parent, src, key, &val_node);
}
-static void mpv_node_map_add_double(void *ta_parent, mpv_node *src, const char *key, double val)
-{
- mpv_node val_node = {.format = MPV_FORMAT_DOUBLE, .u.double_ = val};
- mpv_node_map_add(ta_parent, src, key, &val_node);
-}
-
static void mpv_node_map_add_string(void *ta_parent, mpv_node *src, const char *key, const char *val)
{
mpv_node val_node = {.format = MPV_FORMAT_STRING, .u.string = (char*)val};
@@ -124,74 +89,19 @@ static void mpv_format_command_reply(void *ta_parent, mpv_event *event,
mpv_node_map_add(ta_parent, dst, "data", &cmd->result);
}
-static void mpv_event_to_node(void *ta_parent, mpv_event *event, mpv_node *dst)
-{
- if (event->event_id == MPV_EVENT_COMMAND_REPLY) {
- mpv_format_command_reply(ta_parent, event, dst);
- return;
- }
-
- mpv_node_map_add_string(ta_parent, dst, "event", mpv_event_name(event->event_id));
-
- if (event->reply_userdata)
- mpv_node_map_add_int64(ta_parent, dst, "id", event->reply_userdata);
-
- if (event->error < 0)
- mpv_node_map_add_string(ta_parent, dst, "error", mpv_error_string(event->error));
-
- switch (event->event_id) {
- case MPV_EVENT_LOG_MESSAGE: {
- mpv_event_log_message *msg = event->data;
-
- mpv_node_map_add_string(ta_parent, dst, "prefix", msg->prefix);
- mpv_node_map_add_string(ta_parent, dst, "level", msg->level);
- mpv_node_map_add_string(ta_parent, dst, "text", msg->text);
-
- break;
- }
-
- case MPV_EVENT_CLIENT_MESSAGE: {
- mpv_event_client_message *msg = event->data;
-
- mpv_node args_node = {.format = MPV_FORMAT_NODE_ARRAY, .u.list = NULL};
- for (int n = 0; n < msg->num_args; n++)
- mpv_node_array_add_string(ta_parent, &args_node, msg->args[n]);
- mpv_node_map_add(ta_parent, dst, "args", &args_node);
- break;
- }
-
- case MPV_EVENT_PROPERTY_CHANGE: {
- mpv_event_property *prop = event->data;
-
- mpv_node_map_add_string(ta_parent, dst, "name", prop->name);
-
- switch (prop->format) {
- case MPV_FORMAT_NODE:
- mpv_node_map_add(ta_parent, dst, "data", prop->data);
- break;
- case MPV_FORMAT_DOUBLE:
- mpv_node_map_add_double(ta_parent, dst, "data", *(double *)prop->data);
- break;
- case MPV_FORMAT_FLAG:
- mpv_node_map_add_flag(ta_parent, dst, "data", *(int *)prop->data);
- break;
- case MPV_FORMAT_STRING:
- mpv_node_map_add_string(ta_parent, dst, "data", *(char **)prop->data);
- break;
- default:
- mpv_node_map_add_null(ta_parent, dst, "data");
- }
- break;
- }
- }
-}
-
char *mp_json_encode_event(mpv_event *event)
{
void *ta_parent = talloc_new(NULL);
- mpv_node event_node = {.format = MPV_FORMAT_NODE_MAP, .u.list = NULL};
- mpv_event_to_node(ta_parent, event, &event_node);
+ struct mpv_node event_node;
+ if (event->event_id == MPV_EVENT_COMMAND_REPLY) {
+ event_node = (mpv_node){.format = MPV_FORMAT_NODE_MAP, .u.list = NULL};
+ mpv_format_command_reply(ta_parent, event, &event_node);
+ } else {
+ mpv_event_to_node(&event_node, event);
+ // Abuse mpv_event_to_node() internals.
+ talloc_steal(ta_parent, node_get_alloc(&event_node));
+ }
char *output = talloc_strdup(NULL, "");
json_write(&output, &event_node);
diff --git a/libmpv/client.h b/libmpv/client.h
index ef9ba0d423..e57f727846 100644
--- a/libmpv/client.h
+++ b/libmpv/client.h
@@ -1718,6 +1718,31 @@ typedef struct mpv_event {
} mpv_event;
/**
+ * Convert the given src event to a mpv_node, and set *dst to the result. *dst
+ * is set to a MPV_FORMAT_NODE_MAP, with fields for corresponding mpv_event and
+ * mpv_event.data/mpv_event_* fields.
+ *
+ * The exact details are not completely documented out of laziness. A start
+ * is located in the "Events" section of the manpage.
+ *
+ * *dst may point to newly allocated memory, or pointers in mpv_event. You must
+ * copy the entire mpv_node if you want to reference it after mpv_event becomes
+ * invalid (such as making a new mpv_wait_event() call, or destroying the
+ * mpv_handle from which it was returned). Call mpv_free_node_contents() to free
+ * any memory allocations made by this API function.
+ *
+ * Safe to be called from mpv render API threads.
+ *
+ * @param dst Target. This is not read and fully overwritten. Must be released
+ * with mpv_free_node_contents(). Do not write to pointers returned
+ * by it. (On error, this may be left as an empty node.)
+ * @param src The source event. Not modified (it's not const due to the author's
+ * prejudice of the C version of const).
+ * @return error code (MPV_ERROR_NOMEM only, if at all)
+ */
+int mpv_event_to_node(mpv_node *dst, mpv_event *src);
+
+/**
* Enable or disable the given event.
*
* Some events are enabled by default. Some events can't be disabled.
diff --git a/libmpv/mpv.def b/libmpv/mpv.def
index a2c6fd1ac9..6e20a668de 100644
--- a/libmpv/mpv.def
+++ b/libmpv/mpv.def
@@ -13,6 +13,7 @@ mpv_create_weak_client
mpv_destroy
mpv_detach_destroy
mpv_error_string
+mpv_event_to_node
mpv_event_name
mpv_free
mpv_free_node_contents
diff --git a/player/client.c b/player/client.c
index f9f8cd48f6..396c623cea 100644
--- a/player/client.c
+++ b/player/client.c
@@ -676,6 +676,9 @@ static void dup_event_data(struct mpv_event *ev)
ev->data = msg;
break;
}
+ case MPV_EVENT_START_FILE:
+ ev->data = talloc_memdup(NULL, ev->data, sizeof(mpv_event_start_file));
+ break;
case MPV_EVENT_END_FILE:
ev->data = talloc_memdup(NULL, ev->data, sizeof(mpv_event_end_file));
break;
@@ -1910,6 +1913,103 @@ unsigned long mpv_client_api_version(void)
return MPV_CLIENT_API_VERSION;
}
+int mpv_event_to_node(mpv_node *dst, mpv_event *event)
+{
+ *dst = (mpv_node){0};
+
+ node_init(dst, MPV_FORMAT_NODE_MAP, NULL);
+ node_map_add_string(dst, "event", mpv_event_name(event->event_id));
+
+ if (event->error < 0)
+ node_map_add_string(dst, "error", mpv_error_string(event->error));
+
+ switch (event->event_id) {
+
+ case MPV_EVENT_START_FILE: {
+ mpv_event_start_file *esf = event->data;
+
+ node_map_add_int64(dst, "playlist_entry_id", esf->playlist_entry_id);
+ break;
+ }
+
+ case MPV_EVENT_END_FILE: {
+ mpv_event_end_file *eef = event->data;
+
+ const char *reason;
+ switch (eef->reason) {
+ case MPV_END_FILE_REASON_EOF: reason = "eof"; break;
+ case MPV_END_FILE_REASON_STOP: reason = "stop"; break;
+ case MPV_END_FILE_REASON_QUIT: reason = "quit"; break;
+ case MPV_END_FILE_REASON_ERROR: reason = "error"; break;
+ case MPV_END_FILE_REASON_REDIRECT: reason = "redirect"; break;
+ default:
+ reason = "unknown";
+ }
+ node_map_add_string(dst, "reason", reason);
+
+ node_map_add_int64(dst, "playlist_entry_id", eef->playlist_entry_id);
+
+ if (eef->reason == MPV_END_FILE_REASON_ERROR)
+ node_map_add_string(dst, "file_error", mpv_error_string(eef->error));
+ break;
+ }
+
+ case MPV_EVENT_LOG_MESSAGE: {
+ mpv_event_log_message *msg = event->data;
+
+ node_map_add_string(dst, "prefix", msg->prefix);
+ node_map_add_string(dst, "level", msg->level);
+ node_map_add_string(dst, "text", msg->text);
+ break;
+ }
+
+ case MPV_EVENT_CLIENT_MESSAGE: {
+ mpv_event_client_message *msg = event->data;
+
+ struct mpv_node *args = node_map_add(dst, "args", MPV_FORMAT_NODE_ARRAY);
+ for (int n = 0; n < msg->num_args; n++) {
+ struct mpv_node *sn = node_array_add(args, MPV_FORMAT_NONE);
+ sn->format = MPV_FORMAT_STRING;
+ sn->u.string = (char *)msg->args[n];
+ }
+ break;
+ }
+
+ case MPV_EVENT_PROPERTY_CHANGE: {
+ mpv_event_property *prop = event->data;
+
+ node_map_add_string(dst, "name", prop->name);
+
+ switch (prop->format) {
+ case MPV_FORMAT_NODE:
+ *node_map_add(dst, "data", MPV_FORMAT_NONE) =
+ *(struct mpv_node *)prop->data;
+ break;
+ case MPV_FORMAT_DOUBLE:
+ node_map_add_double(dst, "data", *(double *)prop->data);
+ break;
+ case MPV_FORMAT_FLAG:
+ node_map_add_flag(dst, "data", *(int *)prop->data);
+ break;
+ case MPV_FORMAT_STRING:
+ node_map_add_string(dst, "data", *(char **)prop->data);
+ break;
+ default: ;
+ }
+ break;
+ }
+
+ case MPV_EVENT_HOOK: {
+ mpv_event_hook *hook = event->data;
+
+ node_map_add_int64(dst, "hook_id", hook->id);
+ break;
+ }
+
+ }
+ return 0;
+}
+
static const char *const err_table[] = {
[-MPV_ERROR_SUCCESS] = "success",
[-MPV_ERROR_EVENT_QUEUE_FULL] = "event queue full",
diff --git a/player/lua.c b/player/lua.c
index 13a368f7c5..aa0b071eb5 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -519,50 +519,6 @@ static int script_wait_event(lua_State *L)
}
switch (event->event_id) {
- case MPV_EVENT_LOG_MESSAGE: {
- mpv_event_log_message *msg = event->data;
-
- lua_pushstring(L, msg->prefix); // event s
- lua_setfield(L, -2, "prefix"); // event
- lua_pushstring(L, msg->level); // event s
- lua_setfield(L, -2, "level"); // event
- lua_pushstring(L, msg->text); // event s
- lua_setfield(L, -2, "text"); // event
- break;
- }
- case MPV_EVENT_CLIENT_MESSAGE: {
- mpv_event_client_message *msg = event->data;
-
- lua_newtable(L); // event args
- for (int n = 0; n < msg->num_args; n++) {
- lua_pushinteger(L, n + 1); // event args N
- lua_pushstring(L, msg->args[n]); // event args N val
- lua_settable(L, -3); // event args
- }
- lua_setfield(L, -2, "args"); // event
- break;
- }
- case MPV_EVENT_END_FILE: {
- mpv_event_end_file *eef = event->data;
- const char *reason;
- switch (eef->reason) {
- case MPV_END_FILE_REASON_EOF: reason = "eof"; break;
- case MPV_END_FILE_REASON_STOP: reason = "stop"; break;
- case MPV_END_FILE_REASON_QUIT: reason = "quit"; break;
- case MPV_END_FILE_REASON_ERROR: reason = "error"; break;
- case MPV_END_FILE_REASON_REDIRECT: reason = "redirect"; break;
- default:
- reason = "unknown";
- }
- lua_pushstring(L, reason); // event reason
- lua_setfield(L, -2, "reason"); // event
-
- if (eef->reason == MPV_END_FILE_REASON_ERROR) {
- lua_pushstring(L, mpv_error_string(eef->error)); // event error
- lua_setfield(L, -2, "error"); // event
- }
- break;
- }
case MPV_EVENT_PROPERTY_CHANGE: {
mpv_event_property *prop = event->data;
lua_pushstring(L, prop->name);
@@ -586,12 +542,6 @@ static int script_wait_event(lua_State *L)
lua_setfield(L, -2, "data");
break;
}
- case MPV_EVENT_HOOK: {
- mpv_event_hook *hook = event->data;
- lua_pushinteger(L, hook->id);
- lua_setfield(L, -2, "hook_id");
- break;
- }
case MPV_EVENT_COMMAND_REPLY: {
mpv_event_command *cmd = event->data;
pushnode(L, &cmd->result);
@@ -599,6 +549,17 @@ static int script_wait_event(lua_State *L)
break;
}
default: ;
+ struct mpv_node rn;
+ mpv_event_to_node(&rn, event);
+
+ assert(rn.format == MPV_FORMAT_NODE_MAP);
+ mpv_node_list *list = rn.u.list;
+ for (int n = 0; n < list->num; n++) {
+ pushnode(L, &list->values[n]);
+ lua_setfield(L, -2, list->keys[n]);
+ }
+
+ mpv_free_node_contents(&rn);
}
// return event