summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-05-17 20:10:39 +0200
committerwm4 <wm4@nowhere>2018-05-24 19:56:34 +0200
commit332907e1d7225ae39565d462aac5c45c3a5cad97 (patch)
tree5c4ab4f6e8d5bb262b3cb9cdeee724eff7c4a890
parentd36b85cfdf4714a0498aec2a1f548ce0467e4fe3 (diff)
downloadmpv-332907e1d7225ae39565d462aac5c45c3a5cad97.tar.bz2
mpv-332907e1d7225ae39565d462aac5c45c3a5cad97.tar.xz
command: give named arguments to almost all commands
Before this change, only 1 command or so had named arguments. There is no reason why other commands can't have them, except that it's a bit of work to add them. Commands with variable number of arguments are inherently incompatible to named arguments, such as the "run" command. They still have dummy names, but obviously you can't assign multiple values to a single named argument (unless the argument has an array type, which would be something different). For now, disallow using named argument APIs with these commands. This might change later. 2 commands are adjusted to not need a separate default value by changing flag constants. (The numeric values are C only and can't be set by users.) Make the command syntax in the manpage more consistent. Now none of the allowed choice/flag names are in the command header, and all arguments are shown with their proper name and quoted with <...>. Some places in the manpage and the client.h doxygen are updated to reflect that most commands support named arguments. In addition, try to improve the documentation of the syntax and need for escaping etc. as well. (Or actually most uses of the word "argument" should be "parameter".)
-rw-r--r--DOCS/interface-changes.rst3
-rw-r--r--DOCS/man/input.rst249
-rw-r--r--input/cmd.c7
-rw-r--r--libmpv/client.h4
-rw-r--r--player/command.c395
5 files changed, 409 insertions, 249 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 4afe18ae60..49c9bda9ba 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -106,6 +106,9 @@ Interface changes
- ipc: require that "request_id" fields are integers. Other types are still
accepted for compatibility, but this will stop in the future. Also, if no
request_id is provided, 0 will be assumed.
+ - mpv_command_node() and mp.command_native() now support named arguments
+ (see manpage). If you want to use them, use a new version of the manpage
+ as reference, which lists the definitive names.
--- mpv 0.28.0 ---
- rename --hwdec=mediacodec option to mediacodec-copy, to reflect
conventions followed by other hardware video decoding APIs
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 4b5ebffd0f..d2c92d7476 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -41,10 +41,10 @@ commands they're bound to on the OSD, instead of executing the commands::
(Only closing the window will make **mpv** exit, pressing normal keys will
merely display the binding, even if mapped to quit.)
-General Input Command Syntax
-----------------------------
+input.conf syntax
+-----------------
-``[Shift+][Ctrl+][Alt+][Meta+]<key> [{<section>}] [<prefixes>] <command> (<argument>)* [; <command>]``
+``[Shift+][Ctrl+][Alt+][Meta+]<key> [{<section>}] <command> ( ; <command> )*``
Note that by default, the right Alt key can be used to create special
characters, and thus does not register as a modifier. The option
@@ -59,9 +59,9 @@ character), or a symbolic name (as printed by ``--input-keylist``).
``<section>`` (braced with ``{`` and ``}``) is the input section for this
command.
-Arguments are separated by whitespace. This applies even to string arguments.
-For this reason, string arguments should be quoted with ``"``. Inside quotes,
-C-style escaping can be used.
+``<command>`` is the command itself. It consists of the command name and
+multiple (or none) commands, all separated by whitespace. String arguments
+need to be quoted with ``"``. Details see ``Flat command syntax``.
You can bind multiple commands to one key. For example:
@@ -78,25 +78,89 @@ that matches, and the multi-key command will never be called. Intermediate keys
can be remapped to ``ignore`` in order to avoid this issue. The maximum number
of (non-modifier) keys for combinations is currently 4.
+Flat command syntax
+-------------------
+
+This is the syntax used in input.conf, and referred to "input.conf syntax" in
+a number of other places.
+
+``<command> ::= [<prefixes>] <command_name> (<argument>)*``
+``<argument> ::= (<string> | " <quoted_string> " )``
+
+``command_name`` is an unquoted string with the command name itself. See
+`List of Input Commands`_ for a list.
+
+Arguments are separated by whitespace. This applies even to string arguments.
+For this reason, string arguments should be quoted with ``"``. If a string
+argument contains spaces or certain special characters, quoting and possibly
+escaping is mandatory, or the command cannot be parsed correctly.
+
+Inside quotes, C-style escaping can be used. JSON escapes according to RFC 8259,
+minus surrogate pair escapes, should be a safe subset that can be used.
+
+Commands specified as arrays
+----------------------------
+
+This applies to certain APIs, such as ``mp.commandv()`` or
+``mp.command_native()`` (with array parameters) in Lua scripting, or
+``mpv_command()`` or ``mpv_command_node()`` (with MPV_FORMAT_NODE_ARRAY) in the
+C libmpv client API.
+
+The command as well as all arguments are passed as a single array. Similar to
+the `Flat command syntax`_, you can first pass prefixes as strings (each as
+separate array item), then the command name as string, and then each argument
+as string or a native value.
+
+Since these APIs pass arguments as separate strings or native values, they do
+not expect quotes, and do support escaping. Technically, there is the input.conf
+parser, which first splits the command string into arguments, and then invokes
+argument parsers for each argument. The input.conf parser normally handles
+quotes and escaping. The array command APIs mentioned above pass strings
+directly to the argument parsers, or can sidestep them by the ability to pass
+non-string values.
+
+Sometimes commands have string arguments, that in turn are actually parsed by
+other components (e.g. filter strings with ``vf add``) - in these cases, you
+you would have to double-escape in input.conf, but not with the array APIs.
+
+For complex commands, consider using `Named arguments`_ instead, which should
+give slightly more compatibility. Some commands do not support named arguments
+and inherently take an array, though.
+
Named arguments
---------------
-Some commands support named arguments (most currently don't). Named arguments
-cannot be used with the "flat" input.conf syntax shown above, but require using
-e.g. ``mp.command_native()`` in Lua scripting, or e.g. ``mpv_command_node()``
-with the libmpv API. Some commands ask you to only use named arguments (because
-the command order is not guaranteed), which means you can't use them as
-key bindings in input.conf at all.
+This applies to certain APIs, such as ``mp.command_native()`` (with tables that
+have string keys) in Lua scripting, or ``mpv_command_node()`` (with
+MPV_FORMAT_NODE_MAP) in the C libmpv client API.
+
+Like with array commands, quoting and escaping is inherently not needed in the
+normal case.
+
+The name of each command is defined in each command description in the
+`List of Input Commands`_.
+
+Some commands do not support named arguments (e.g. ``run`` command). You need
+to use APIs that pass arguments as arrays.
+
+Named arguments are not supported in the "flat" input.conf syntax, which means
+you cannot use them for key bindings in input.conf at all.
List of Input Commands
----------------------
+Commands with parameters have the parameter name enclosed in ``<`` / ``>``.
+Don't add those to the actual command. Optional arguments are enclosed in
+``[`` / ``]``. If you don't pass them, they will be set to a default value.
+
+Remember to quote string arguments in input.conf (see `Flat command syntax`_).
+
``ignore``
Use this to "block" keys that should be unbound, and do nothing. Useful for
disabling default bindings, without disabling all bindings with
``--no-input-default-bindings``.
-``seek <seconds> [relative|absolute|absolute-percent|relative-percent|exact|keyframes]``
+``seek <target> [<flags>]``
Change the playback position. By default, seeks by a relative amount of
seconds.
@@ -124,7 +188,7 @@ List of Input Commands
3rd parameter (essentially using a space instead of ``+``). The 3rd
parameter is still parsed, but is considered deprecated.
-``revert-seek [mode]``
+``revert-seek [<flags>]``
Undoes the ``seek`` command, and some other commands that seek (but not
necessarily all of them). Calling this command once will jump to the
playback position before the seek. Calling it a second time undoes the
@@ -154,22 +218,24 @@ List of Input Commands
This does not work with audio-only playback.
-``set <property> "<value>"``
- Set the given property to the given value.
+``set <name> <value>``
+ Set the given property or option to the given value.
-``add <property> [<value>]``
- Add the given value to the property. On overflow or underflow, clamp the
- property to the maximum. If ``<value>`` is omitted, assume ``1``.
+``add <name> [<value>]``
+ Add the given value to the property or option. On overflow or underflow,
+ clamp the property to the maximum. If ``<value>`` is omitted, assume ``1``.
-``cycle <property> [up|down]``
- Cycle the given property. ``up`` and ``down`` set the cycle direction. On
- overflow, set the property back to the minimum, on underflow set it to the
- maximum. If ``up`` or ``down`` is omitted, assume ``up``.
+``cycle <name> [<value>]``
+ Cycle the given property or option. The second argument can be ``up`` or
+ ``down`` to set the cycle direction. On overflow, set the property back to
+ the minimum, on underflow set it to the maximum. If ``up`` or ``down`` is
+ omitted, assume ``up``.
-``multiply <property> <factor>``
- Multiplies the value of a property with the numeric factor.
+``multiply <name> <value>``
+ Similar to ``add``, but multiplies the property or option with the numeric
+ value.
-``screenshot [subtitles|video|window|single|each-frame]``
+``screenshot <flags>``
Take a screenshot.
Multiple flags are available (some can be combined with ``+``):
@@ -201,36 +267,41 @@ List of Input Commands
normal standalone commands, this is always asynchronous, and the flag has
no effect. (This behavior changed with mpv 0.29.0.)
-``screenshot-to-file "<filename>" [subtitles|video|window]``
+``screenshot-to-file <filename> <flags>``
Take a screenshot and save it to a given file. The format of the file will
be guessed by the extension (and ``--screenshot-format`` is ignored - the
behavior when the extension is missing or unknown is arbitrary).
- The second argument is like the first argument to ``screenshot``.
+ The second argument is like the first argument to ``screenshot`` and
+ supports ``subtitles``, ``video``, ``window``.
If the file already exists, it's overwritten.
Like all input command parameters, the filename is subject to property
expansion as described in `Property Expansion`_.
-``playlist-next [weak|force]``
+``playlist-next <flags>``
Go to the next entry on the playlist.
+ First argument:
+
weak (default)
If the last file on the playlist is currently played, do nothing.
force
Terminate playback if there are no more files on the playlist.
-``playlist-prev [weak|force]``
+``playlist-prev <flags>``
Go to the previous entry on the playlist.
+ First argument:
+
weak (default)
If the first file on the playlist is currently played, do nothing.
force
Terminate playback if the first file is being played.
-``loadfile "<file>" [replace|append|append-play [options]]``
- Load the given file and play it.
+``loadfile <url> [<flags> [<options>]]``
+ Load the given file or URL and play it.
Second argument:
@@ -248,13 +319,20 @@ List of Input Commands
Not all options can be changed this way. Some options require a restart
of the player.
-``loadlist "<playlist>" [replace|append]``
- Load the given playlist file (like ``--playlist``).
+``loadlist <url> [<flags>]``
+ Load the given playlist file or URL (like ``--playlist``).
+
+ Second argument:
+
+ <replace> (default)
+ Stop playback and replace the internal playlist with the new one.
+ <append>
+ Append the new playlist at the end of the current internal playlist.
``playlist-clear``
Clear the playlist, except the currently played file.
-``playlist-remove current|<index>``
+``playlist-remove <index>``
Remove the playlist entry at the given index. Index values start counting
with 0. The special value ``current`` removes the current entry. Note that
removing the current entry also stops playback and starts playing the next
@@ -271,12 +349,14 @@ List of Input Commands
Shuffle the playlist. This is similar to what is done on start if the
``--shuffle`` option is used.
-``run "command" "arg1" "arg2" ...``
+``run <command> [<arg1> [<arg2> [...]]]``
Run the given command. Unlike in MPlayer/mplayer2 and earlier versions of
mpv (0.2.x and older), this doesn't call the shell. Instead, the command
is run directly, with each argument passed separately. Each argument is
- expanded like in `Property Expansion`_. Note that there is a static limit
- of (as of this writing) 9 arguments (this limit could be raised on demand).
+ expanded like in `Property Expansion`_.
+
+ This command has a variable number of arguments, and cannot be used with
+ named arguments.
The program is run in a detached way. mpv doesn't wait until the command
is completed, but continues playback right after spawning it.
@@ -376,15 +456,15 @@ List of Input Commands
will seek to the previous position on start. The (optional) argument is
exactly as in the ``quit`` command.
-``sub-add "<file>" [<flags> [<title> [<lang>]]]``
- Load the given subtitle file. It is selected as current subtitle after
- loading.
+``sub-add <url> [<flags> [<title> [<lang>]]]``
+ Load the given subtitle file or stream. By default, it is selected as
+ current subtitle after loading.
- The ``flags`` args is one of the following values:
+ The ``flags`` argument is one of the following values:
<select>
- Select the subtitle immediately.
+ Select the subtitle immediately (default).
<auto>
@@ -427,11 +507,11 @@ List of Input Commands
events that have already been displayed, or are within a short prefetch
range.
-``print-text "<string>"``
+``print-text <text>``
Print text to stdout. The string can contain properties (see
- `Property Expansion`_).
+ `Property Expansion`_). Take care to put the argument in quotes.
-``show-text "<string>" [<duration>|- [<level>]]``
+``show-text <text> [<duration> [<level>]]``
Show text on the OSD. The string can contain properties, which are expanded
as described in `Property Expansion`_. This can be used to show playback
time, filename, and so on.
@@ -443,7 +523,7 @@ List of Input Commands
<level>
The minimum OSD level to show the text at (see ``--osd-level``).
-``expand-text "<string>"``
+``expand-text <string>``
Property-expand the argument and return the expanded string. This can be
used only through the client API or from a script using
``mp.command_native``. (see `Property Expansion`_).
@@ -461,7 +541,7 @@ List of Input Commands
essentially like ``quit``. Useful for the client API: playback can be
stopped without terminating the player.
-``mouse <x> <y> [<button> [single|double]]``
+``mouse <x> <y> [<button> [<mode>]]``
Send a mouse event with given coordinate (``<x>``, ``<y>``).
Second argument:
@@ -478,24 +558,24 @@ List of Input Commands
<double>
The mouse event represents double-click.
-``keypress <key_name>``
+``keypress <name>``
Send a key event through mpv's input handler, triggering whatever
- behavior is configured to that key. ``key_name`` uses the ``input.conf``
+ behavior is configured to that key. ``name`` uses the ``input.conf``
naming scheme for keys and modifiers. Useful for the client API: key events
can be sent to libmpv to handle internally.
-``keydown <key_name>``
+``keydown <name>``
Similar to ``keypress``, but sets the ``KEYDOWN`` flag so that if the key is
bound to a repeatable command, it will be run repeatedly with mpv's key
repeat timing until the ``keyup`` command is called.
-``keyup [<key_name>]``
+``keyup [<name>]``
Set the ``KEYUP`` flag, stopping any repeated behavior that had been
- triggered. ``key_name`` is optional. If ``key_name`` is not given or is an
+ triggered. ``name`` is optional. If ``name`` is not given or is an
empty string, ``KEYUP`` will be set on all keys. Otherwise, ``KEYUP`` will
- only be set on the key specified by ``key_name``.
+ only be set on the key specified by ``name``.
-``audio-add "<file>" [<flags> [<title> [<lang>]]]``
+``audio-add <url> [<flags> [<title> [<lang>]]]``
Load the given audio file. See ``sub-add`` command.
``audio-remove [<id>]``
@@ -523,21 +603,21 @@ List of Input Commands
Input Commands that are Possibly Subject to Change
--------------------------------------------------
-``af set|add|toggle|del|clr "filter1=params,filter2,..."``
+``af <operation> <value>``
Change audio filter chain. See ``vf`` command.
-``vf set|add|toggle|del|clr "filter1=params,filter2,..."``
+``vf <operation> <value>``
Change video filter chain.
The first argument decides what happens:
- set
+ <set>
Overwrite the previous filter chain with the new one.
- add
+ <add>
Append the new filter chain to the previous one.
- toggle
+ <toggle>
Check if the given filter (with the exact parameters) is already
in the video chain. If yes, remove the filter. If no, add the filter.
(If several filters are passed to the command, this is done for
@@ -547,14 +627,14 @@ Input Commands that are Possibly Subject to Change
without filter name and parameters as filter entry. This toggles the
enable/disable flag.
- del
+ <del>
Remove the given filters from the video chain. Unlike in the other
cases, the second parameter is a comma separated list of filter names
or integer indexes. ``0`` would denote the first filter. Negative
indexes start from the last filter, and ``-1`` denotes the last
filter.
- clr
+ <clr>
Remove all filters. Note that like the other sub-commands, this does
not control automatically inserted filters.
@@ -593,18 +673,21 @@ Input Commands that are Possibly Subject to Change
"disabled" flag for the filter with the label ``deband`` when the
``a`` key is hit.
-``cycle-values ["!reverse"] <property> "<value1>" "<value2>" ...``
+``cycle-values [<"!reverse">] <property> <value1> [<value2> [...]]``
Cycle through a list of values. Each invocation of the command will set the
given property to the next value in the list. The command will use the
current value of the property/option, and use it to determine the current
position in the list of values. Once it has found it, it will set the
next value in the list (wrapping around to the first item if needed).
+ This command has a variable number of arguments, and cannot be used with
+ named arguments.
+
The special argument ``!reverse`` can be used to cycle the value list in
reverse. The only advantage is that you don't need to reverse the value
list yourself when adding a second key binding for cycling backwards.
-``enable-section "<section>" [flags]``
+``enable-section <name> [<flags>]``
Enable all key bindings in the named input section.
The enabled input sections form a stack. Bindings in sections on the top of
@@ -626,10 +709,10 @@ Input Commands that are Possibly Subject to Change
<allow-vo-dragging>
Same.
-``disable-section "<section>"``
+``disable-section <name>``
Disable the named input section. Undoes ``enable-section``.
-``define-section "<section>" "<contents>" [default|force]``
+``define-section <name> <contents> [<flags>]``
Create a named input section, or replace the contents of an already existing
input section. The ``contents`` parameter uses the same syntax as the
``input.conf`` file (except that using the section syntax in it is not
@@ -657,7 +740,7 @@ Input Commands that are Possibly Subject to Change
information about the key state. The special key name ``unmapped`` can be
used to match any unmapped key.
-``overlay-add <id> <x> <y> "<file>" <offset> "<fmt>" <w> <h> <stride>``
+``overlay-add <id> <x> <y> <file> <offset> <fmt> <w> <h> <stride>``
Add an OSD overlay sourced from raw data. This might be useful for scripts
and applications controlling mpv, and which want to display things on top
of the video window.
@@ -668,6 +751,9 @@ Input Commands that are Possibly Subject to Change
anamorphic video (such as DVD), ``osd-par`` should be read as well, and the
overlay should be aspect-compensated.
+ This has the following named arguments. The order of them is not guaranteed,
+ so you should always call them with named arguments, see `Named arguments`_.
+
``id`` is an integer between 0 and 63 identifying the overlay element. The
ID can be used to add multiple overlay parts, update a part by using this
command with an already existing ID, or to remove a part with
@@ -725,18 +811,24 @@ Input Commands that are Possibly Subject to Change
Remove an overlay added with ``overlay-add`` and the same ID. Does nothing
if no overlay with this ID exists.
-``script-message "<arg1>" "<arg2>" ...``
+``script-message [<arg1> [<arg2> [...]]]``
Send a message to all clients, and pass it the following list of arguments.
What this message means, how many arguments it takes, and what the arguments
mean is fully up to the receiver and the sender. Every client receives the
message, so be careful about name clashes (or use ``script-message-to``).
-``script-message-to "<target>" "<arg1>" "<arg2>" ...``
+ This command has a variable number of arguments, and cannot be used with
+ named arguments.
+
+``script-message-to <target> [<arg1> [<arg2> [...]]]``
Same as ``script-message``, but send it only to the client named
``<target>``. Each client (scripts etc.) has a unique name. For example,
Lua scripts can get their name via ``mp.get_script_name()``.
-``script-binding "<name>"``
+ This command has a variable number of arguments, and cannot be used with
+ named arguments.
+
+``script-binding <name>``
Invoke a script-provided key binding. This can be used to remap key
bindings provided by external Lua scripts.
@@ -773,7 +865,7 @@ Input Commands that are Possibly Subject to Change
unseekable streams that are going out of sync.
This command might be changed or removed in the future.
-``screenshot-raw [subtitles|video|window]``
+``screenshot-raw [<flags>]``
Return a screenshot in memory. This can be used only through the client
API. The MPV_FORMAT_NODE_MAP returned by this command has the ``w``, ``h``,
``stride`` fields set to obvious contents. The ``format`` field is set to
@@ -783,7 +875,10 @@ Input Commands that are Possibly Subject to Change
is freed as soon as the result mpv_node is freed. As usual with client API
semantics, you are not allowed to write to the image data.
-``vf-command "<label>" "<cmd>" "<args>"``
+ The ``flags`` argument is like the first argument to ``screenshot`` and
+ supports ``subtitles``, ``video``, ``window``.
+
+``vf-command <label> <command> <argument>``
Send a command to the filter with the given ``<label>``. Use ``all`` to send
it to all filters at once. The command and argument string is filter
specific. Currently, this only works with the ``lavfi`` filter - see
@@ -792,10 +887,10 @@ Input Commands that are Possibly Subject to Change
Note that the ``<label>`` is a mpv filter label, not a libavfilter filter
name.
-``af-command "<label>" "<cmd>" "<args>"``
+``af-command <label> <command> <argument>``
Same as ``vf-command``, but for audio filters.
-``apply-profile "<name>"``
+``apply-profile <name>``
Apply the contents of a named profile. This is like using ``profile=name``
in a config file, except you can map it to a key binding to change it at
runtime.
@@ -803,14 +898,14 @@ Input Commands that are Possibly Subject to Change
There is no such thing as "unapplying" a profile - applying a profile
merely sets all option values listed within the profile.
-``load-script "<path>"``
+``load-script <filename>``
Load a script, similar to the ``--script`` option. Whether this waits for
the script to finish initialization or not changed multiple times, and the
future behavior is left undefined.
-``change-list "<option>" "<operation>" "<value>"``
+``change-list <name> <operation> <value>``
This command changes list options as described in `List Options`_. The
- ``<option>`` parameter is the normal option name, while ``<operation>`` is
+ ``<name>`` parameter is the normal option name, while ``<operation>`` is
the suffix or action used on the option.
Some operations take no value, but the command still requires the value
diff --git a/input/cmd.c b/input/cmd.c
index c637ec22bd..7e50f0784b 100644
--- a/input/cmd.c
+++ b/input/cmd.c
@@ -239,6 +239,13 @@ static bool cmd_node_map(struct mp_log *log, struct mp_cmd *cmd, mpv_node *node)
if (!find_cmd(log, cmd, bstr0(name->u.string)))
return false;
+ if (cmd->def->vararg) {
+ mp_err(log, "Command %s: this command uses a variable number of "
+ "arguments, which does not work with named arguments.\n",
+ cmd->name);
+ return false;
+ }
+
for (int n = 0; n < args->num; n++) {
const char *key = args->keys[n];
mpv_node *val = &args->values[n];
diff --git a/libmpv/client.h b/libmpv/client.h
index 32c2d0a6e1..44c48402a8 100644
--- a/libmpv/client.h
+++ b/libmpv/client.h
@@ -955,8 +955,8 @@ int mpv_command(mpv_handle *ctx, const char **args);
* The special entry "_flags" is optional, and if present, must be an
* array of strings, each being a command prefix to apply. All other
* entries are interpreted as arguments. They must use the argument names
- * as documented in each command description. Currently, most commands do
- * not support named arguments at all.
+ * as documented in each command description. Some commands do not
+ * support named arguments at all, and must use MPV_FORMAT_NODE_ARRAY.
*
* @param[in] args mpv_node with format set to one of the values documented
* above (see there for details)
diff --git a/player/command.c b/player/command.c
index ffe9683adb..9c6bce6aa1 100644
--- a/player/command.c
+++ b/player/command.c
@@ -5623,7 +5623,7 @@ static void cmd_rescan_external_files(void *p)
}
autoload_external_files(mpctx);
- if (cmd->args[0].v.i && mpctx->playback_initialized) {
+ if (!cmd->args[0].v.i && mpctx->playback_initialized) {
// somewhat fuzzy and not ideal
struct track *a = select_default_track(mpctx, 0, STREAM_AUDIO);
if (a && a->is_external)
@@ -5752,7 +5752,7 @@ static void cmd_define_input_section(void *p)
struct mp_cmd_ctx *cmd = p;
struct MPContext *mpctx = cmd->mpctx;
mp_input_define_section(mpctx->input, cmd->args[0].v.s, "<api>",
- cmd->args[1].v.s, !!cmd->args[2].v.i,
+ cmd->args[1].v.s, !cmd->args[2].v.i,
cmd->cmd->sender);
}
@@ -6005,263 +6005,318 @@ static void cmd_load_script(void *p)
cmd->success = false;
}
-// This does not specify the real destination of the command parameter values,
-// it just provides a dummy for the OPT_ macros.
-#define OPT_BASE_STRUCT struct mp_cmd_arg
-#define ARG(t) "", v. t
-
/* This array defines all known commands.
- * The first field is an id used to recognize the command.
- * The second is the command name used in slave mode and input.conf.
- * Then comes the definition of each argument, first mandatory arguments
- * (ARG_INT, ARG_FLOAT, ARG_STRING) if any, then optional arguments
- * (OARG_INT(default), etc) if any. The command will be given the default
- * argument value if the user didn't give enough arguments to specify it.
- * A command can take a maximum of MP_CMD_DEF_MAX_ARGS arguments, or more
- * if the command uses varargs.
+ * The first field the command name used in libmpv and input.conf.
+ * The second field is the handler function (see mp_cmd_def.handler and
+ * run_command()).
+ * Then comes the definition of each argument. They are defined like options,
+ * except that the result is parsed into mp_cmd.args[] (thus the option variable
+ * is a field in the mp_cmd_arg union field). Arguments are optional if either
+ * defval is set (usually via OPTDEF_ macros), or the MP_CMD_OPT_ARG flag is
+ * set, or if it's the last argument and .vararg is set. If .vararg is set, the
+ * command has an arbitrary number of arguments, all using the type indicated by
+ * the last argument (they are appended to mp_cmd.args[] starting at the last
+ * argument's index).
+ * Arguments have named, which can be used by named argument functions, e.g. in
+ * Lua with mp.command_native().
*/
-#define ARG_INT OPT_INT(ARG(i), 0)
-#define ARG_FLOAT OPT_FLOAT(ARG(f), 0)
-#define ARG_DOUBLE OPT_DOUBLE(ARG(d), 0)
-#define ARG_STRING OPT_STRING(ARG(s), 0)
-#define ARG_CHOICE(c) OPT_CHOICE(ARG(i), 0, c)
-#define ARG_CHOICE_OR_INT(...) OPT_CHOICE_OR_INT(ARG(i), 0, __VA_ARGS__)
-#define ARG_TIME OPT_TIME(ARG(d), 0)
-#define OARG_DOUBLE(def) OPT_DOUBLE(ARG(d), 0, OPTDEF_DOUBLE(def))
-#define OARG_INT(def) OPT_INT(ARG(i), 0, OPTDEF_INT(def))
-#define OARG_CHOICE(def, c) OPT_CHOICE(ARG(i), 0, c, OPTDEF_INT(def))
-#define OARG_FLAGS(def, c) OPT_FLAGS(ARG(i), 0, c, OPTDEF_INT(def))
-#define OARG_STRING(def) OPT_STRING(ARG(s), 0, OPTDEF_STR(def))
-
-#define OARG_CYCLEDIR(def) OPT_CYCLEDIR(ARG(d), 0, OPTDEF_DOUBLE(def))
+// This does not specify the real destination of the command parameter values,
+// it just provides a dummy for the OPT_ macros. The real destination is an
+// array item in mp_cmd.args[], using the index of the option definition.
+#define OPT_BASE_STRUCT struct mp_cmd_arg
const struct mp_cmd_def mp_cmds[] = {
{ "ignore", cmd_ignore, .is_ignore = true },
- { "seek", cmd_seek, {
- ARG_TIME,
- OARG_FLAGS(4|0, ({"relative", 4|0}, {"-", 4|0},
- {"absolute-percent", 4|1},
- {"absolute", 4|2},
- {"relative-percent", 4|3},
- {"keyframes", 32|8},
- {"exact", 32|16})),
- // backwards compatibility only
- OARG_CHOICE(0, ({"unused", 0}, {"default-precise", 0},
+ { "seek", cmd_seek,
+ {
+ OPT_TIME("target", v.d, 0),
+ OPT_FLAGS("flags", v.i, 0,
+ ({"relative", 4|0}, {"-", 4|0},
+ {"absolute-percent", 4|1},
+ {"absolute", 4|2},
+ {"relative-percent", 4|3},
+ {"keyframes", 32|8},
+ {"exact", 32|16}),
+ OPTDEF_INT(4|0)),
+ // backwards compatibility only
+ OPT_CHOICE("legacy", v.i, MP_CMD_OPT_ARG,
+ ({"unused", 0}, {"default-precise", 0},
{"keyframes", 32|8},
{"exact", 32|16})),
},
.allow_auto_repeat = true,
.scalable = true,
},
- { "revert-seek", cmd_revert_seek, {
- OARG_FLAGS(0, ({"mark", 1})),
- }},
- { "quit", cmd_quit, { OARG_INT(0) },
+ { "revert-seek", cmd_revert_seek,
+ {OPT_FLAGS("flags", v.i, MP_CMD_OPT_ARG, ({"mark", 1}))},
+ },
+ { "quit", cmd_quit, { OPT_INT("code", v.i, MP_CMD_OPT_ARG) },
.priv = &(const bool){0}, .is_abort = true },
- { "quit-watch-later", cmd_quit, { OARG_INT(0) },
+ { "quit-watch-later", cmd_quit, { OPT_INT("code", v.i, MP_CMD_OPT_ARG) },
.priv = &(const bool){1}, .is_abort = true },
{ "stop", cmd_stop, .is_abort = true },
{ "frame-step", cmd_frame_step, .allow_auto_repeat = true,
.on_updown = true },
{ "frame-back-step", cmd_frame_back_step, .allow_auto_repeat = true },
- { "playlist-next", cmd_playlist_next_prev, {
- OARG_CHOICE(0, ({"weak", 0},
- {"force", 1})),
+ { "playlist-next", cmd_playlist_next_prev,
+ {
+ OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, ({"weak", 0},
+ {"force", 1})),
},
.is_soft_abort = true, .priv = &(const int){1},
},
- { "playlist-prev", cmd_playlist_next_prev, {
- OARG_CHOICE(0, ({"weak", 0},
- {"force", 1})),
+ { "playlist-prev", cmd_playlist_next_prev,
+ {
+ OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG, ({"weak", 0},
+ {"force", 1})),
},
.is_soft_abort = true, .priv = &(const int){-1},
},
{ "playlist-shuffle", cmd_playlist_shuffle, },
- { "sub-step", cmd_sub_step_seek, { ARG_INT }, .allow_auto_repeat = true,
- .priv = &(const bool){true} },
- { "sub-seek", cmd_sub_step_seek, { ARG_INT }, .allow_auto_repeat = true,
- .priv = &(const bool){false} },
- { "print-text", cmd_print_text, { ARG_STRING }, .allow_auto_repeat = true },
- { "show-text", cmd_show_text, { ARG_STRING, OARG_INT(-1), OARG_INT(0) },
+ { "sub-step", cmd_sub_step_seek, { OPT_INT("skip", v.i, 0) },
+ .allow_auto_repeat = true, .priv = &(const bool){true} },
+ { "sub-seek", cmd_sub_step_seek, { OPT_INT("skip", v.i, 0) },
+ .allow_auto_repeat = true, .priv = &(const bool){false} },
+ { "print-text", cmd_print_text, { OPT_STRING("text", v.s, 0) },
+ .allow_auto_repeat = true },
+ { "show-text", cmd_show_text, { OPT_STRING("text", v.s, 0),
+ OPT_INT("duration", v.i, 0, OPTDEF_INT(-1)),
+ OPT_INT("level", v.i, MP_CMD_OPT_ARG), },
.allow_auto_repeat = true},
- { "expand-text", cmd_expand_text, { ARG_STRING } },
+ { "expand-text", cmd_expand_text, { OPT_STRING("text", v.s, 0) } },
{ "show-progress", cmd_show_progress, .allow_auto_repeat = true},
- { "sub-add", cmd_track_add, {
- ARG_STRING,
- OARG_CHOICE(0, ({"select", 0}, {"auto", 1}, {"cached", 2})),
- OARG_STRING(""), OARG_STRING(""),
+
+ { "sub-add", cmd_track_add,
+ {
+ OPT_STRING("url", v.s, 0),
+ OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG,
+ ({"select", 0}, {"auto", 1}, {"cached", 2})),
+ OPT_STRING("title", v.s, MP_CMD_OPT_ARG),
+ OPT_STRING("lang", v.s, MP_CMD_OPT_ARG),
},
.priv = &(const int){STREAM_SUB},
.spawn_thread = true,
},
- { "sub-remove", cmd_track_remove, { OARG_INT(-1) },
+ { "audio-add", cmd_track_add,
+ {
+ OPT_STRING("url", v.s, 0),
+ OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG,
+ ({"select", 0}, {"auto", 1}, {"cached", 2})),
+ OPT_STRING("title", v.s, MP_CMD_OPT_ARG),
+ OPT_STRING("lang", v.s, MP_CMD_OPT_ARG),
+ },
+ .priv = &(const int){STREAM_AUDIO},
+ .spawn_thread = true,
+ },
+
+ { "sub-remove", cmd_track_remove, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) },
.priv = &(const int){STREAM_SUB}, },
- { "sub-reload", cmd_track_reload, { OARG_INT(-1) },
+ { "audio-remove", cmd_track_remove, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) },
+ .priv = &(const int){STREAM_AUDIO}, },
+
+ { "sub-reload", cmd_track_reload, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) },
.priv = &(const int){STREAM_SUB},
.spawn_thread = true,
},
+ { "audio-reload", cmd_track_reload, { OPT_INT("id", v.i, 0, OPTDEF_INT(-1)) },
+ .priv = &(const int){STREAM_AUDIO},
+ .spawn_thread = true,
+ },
+
+ { "rescan-external-files", cmd_rescan_external_files,
+ {
+ OPT_CHOICE("flags", v.i, MP_CMD_OPT_ARG,
+ ({"keep-selection", 1},
+ {"reselect", 0})),