player/command: add discnav command and bind default keys
User-facing entry point for in-disc menu navigation. The command forwards an action (up/down/left/right/select/menu/title-menu/popup/ prev/mouse-move/mouse-click) to the current disc stream handler. The new discnav input section allows binding controls that are only active while a disc menu is on screen. Setting the edition property on a disc jumps to the title through the stream directly, so selecting the currently-playing edition can still return to it from a menu.
This commit is contained in:
1 parent
a5682eb2ad
commit
216e26c871
5 files changed
+155
-4
No files matched your search
@@ -1,2 +1,3 @@
|
|||||||
add `--disc-menu` option
|
add `--disc-menu` option
|
||||||
add `disc-menu-active` property
|
add `disc-menu-active` property
|
||||||
|
add `discnav` command
|
||||||
@@ -1771,6 +1771,46 @@ Miscellaneous Commands
|
|||||||
``context-menu``
|
``context-menu``
|
||||||
Show context menu on the video window. See `Context Menu`_ section for details.
|
Show context menu on the video window. See `Context Menu`_ section for details.
|
||||||
|
|
||||||
|
``discnav <action> [<x> <y>]``
|
||||||
|
Send a navigation command to the optical-disc stream that is currently
|
||||||
|
playing. The command does nothing when no disc is being played.
|
||||||
|
|
||||||
|
``<action>`` is one of:
|
||||||
|
|
||||||
|
up, down, left, right
|
||||||
|
Move the on-disc button selection.
|
||||||
|
select
|
||||||
|
Activate the currently highlighted button.
|
||||||
|
menu
|
||||||
|
Jump to the root menu of the current title set (DVD: VTSM root menu,
|
||||||
|
BD: HDMV top menu).
|
||||||
|
title-menu
|
||||||
|
Jump to the disc's title menu (DVD: VMGM title menu, treated like
|
||||||
|
``menu`` on BD).
|
||||||
|
popup
|
||||||
|
Show / dismiss the Blu-ray popup menu. For DVDs, falls back to the
|
||||||
|
chapter menu where available.
|
||||||
|
prev
|
||||||
|
Return from a menu to playback, or to the previous menu domain.
|
||||||
|
mouse-move
|
||||||
|
Forward a mouse position to the disc, so it can update the focused
|
||||||
|
button under the cursor. With no ``<x> <y>`` arguments, the position
|
||||||
|
is read from the ``mouse-pos`` property and mapped from window into
|
||||||
|
source-video coordinates automatically.
|
||||||
|
mouse-click
|
||||||
|
Like ``mouse-move`` but also activates the button under the cursor.
|
||||||
|
|
||||||
|
``<x>`` and ``<y>`` are optional and only meaningful for the ``mouse-*``
|
||||||
|
actions. They are normalized coordinates in the range 0..1 (top-left at
|
||||||
|
``0,0``), and are used instead of the live ``mouse-pos``.
|
||||||
|
|
||||||
|
mpv ships default bindings for this command in the ``{discnav}`` input
|
||||||
|
section (``UP``/``DOWN``/``LEFT``/``RIGHT`` for navigation, ``ENTER`` to
|
||||||
|
select, ``ESC`` / ``BS`` to leave, ``MBTN_LEFT`` / ``MOUSE_MOVE`` for
|
||||||
|
mouse). The player enables and disables that section automatically as
|
||||||
|
the menu appears and disappears, so the bindings only shadow the normal
|
||||||
|
ones while a menu is actually on screen.
|
||||||
|
|
||||||
``update-clipboard <type> [timeout]``
|
``update-clipboard <type> [timeout]``
|
||||||
Update the clipboard content so that the ``clipboard`` property reflects
|
Update the clipboard content so that the ``clipboard`` property reflects
|
||||||
up-to-date value. This command is required to update the ``clipboard``
|
up-to-date value. This command is required to update the ``clipboard``
|
||||||
|
|||||||
+16
-4
@@ -174,6 +174,15 @@ z and Z
|
|||||||
l
|
l
|
||||||
Set/clear A-B loop points. See ``ab-loop`` command for details.
|
Set/clear A-B loop points. See ``ab-loop`` command for details.
|
||||||
|
|
||||||
|
Ctrl+m
|
||||||
|
Jump to the disc menu when playing a DVD or Blu-ray (see the ``discnav``
|
||||||
|
command). While a menu with a button highlight is on screen, the arrow
|
||||||
|
keys, ENTER, ESC/BACKSPACE and the mouse control the menu instead of
|
||||||
|
their usual functions.
|
||||||
|
|
||||||
|
Ctrl+M
|
||||||
|
Show or hide the Blu-ray popup menu.
|
||||||
|
|
||||||
L
|
L
|
||||||
Toggle infinite looping.
|
Toggle infinite looping.
|
||||||
|
|
||||||
@@ -1328,7 +1337,8 @@ PROTOCOLS
|
|||||||
by passing them to ``--bluray-device``.
|
by passing them to ``--bluray-device``.
|
||||||
|
|
||||||
``title`` can be: ``longest`` or ``first`` (selects the default
|
``title`` can be: ``longest`` or ``first`` (selects the default
|
||||||
playlist); ``mpls/<number>`` (selects <number>.mpls playlist);
|
playlist); ``menu`` (starts in the disc menu, see ``--disc-menu`` and the
|
||||||
|
``discnav`` command); ``mpls/<number>`` (selects <number>.mpls playlist);
|
||||||
``<number>`` (select playlist with the same index). mpv will list
|
``<number>`` (select playlist with the same index). mpv will list
|
||||||
the available playlists on loading.
|
the available playlists on loading.
|
||||||
|
|
||||||
@@ -1336,9 +1346,11 @@ PROTOCOLS
|
|||||||
|
|
||||||
``dvd://[title][/device]`` ``--dvd-device=PATH``
|
``dvd://[title][/device]`` ``--dvd-device=PATH``
|
||||||
|
|
||||||
Play a DVD. DVD menus are not supported. If no title is given, the longest
|
Play a DVD. If no title is given, the longest title is auto-selected.
|
||||||
title is auto-selected. Without ``--dvd-device``, it will probably try
|
``title`` can also be ``menu`` to start in the disc menu (see
|
||||||
to open an actual optical drive, if available and implemented for the OS.
|
``--disc-menu`` and the ``discnav`` command). Without ``--dvd-device``,
|
||||||
|
it will probably try to open an actual optical drive, if available and
|
||||||
|
implemented for the OS.
|
||||||
|
|
||||||
``dvdnav://`` is an old alias for ``dvd://`` and does exactly the same
|
``dvdnav://`` is an old alias for ``dvd://`` and does exactly the same
|
||||||
thing.
|
thing.
|
||||||
|
|||||||
@@ -234,6 +234,22 @@
|
|||||||
#Ctrl+KP_UP add video-align-y -0.01 # align video up
|
#Ctrl+KP_UP add video-align-y -0.01 # align video up
|
||||||
#Ctrl+KP_PGUP add video-align-x 0.01; add video-align-y -0.01 # align video right and up
|
#Ctrl+KP_PGUP add video-align-x 0.01; add video-align-y -0.01 # align video right and up
|
||||||
|
|
||||||
|
#
|
||||||
|
# The "{discnav}" section is enabled only while a disc menu with a button
|
||||||
|
# highlight is actually on screen.
|
||||||
|
#
|
||||||
|
#UP {discnav} discnav up
|
||||||
|
#DOWN {discnav} discnav down
|
||||||
|
#LEFT {discnav} discnav left
|
||||||
|
#RIGHT {discnav} discnav right
|
||||||
|
#ENTER {discnav} discnav select
|
||||||
|
#ESC {discnav} discnav prev
|
||||||
|
#BS {discnav} discnav prev
|
||||||
|
#MOUSE_MOVE {discnav} discnav mouse-move
|
||||||
|
#MBTN_LEFT {discnav} discnav mouse-click
|
||||||
|
#Ctrl+m discnav menu # jump to the disc's root menu
|
||||||
|
#Ctrl+M discnav popup # show/hide Blu-ray popup menu
|
||||||
|
|
||||||
#
|
#
|
||||||
# Legacy bindings (may or may not be removed in the future)
|
# Legacy bindings (may or may not be removed in the future)
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1182,6 +1182,26 @@ static int mp_property_edition(void *ctx, struct m_property *prop,
|
|||||||
}
|
}
|
||||||
return M_PROPERTY_OK;
|
return M_PROPERTY_OK;
|
||||||
}
|
}
|
||||||
|
case M_PROPERTY_SET: {
|
||||||
|
// For disc demuxers, jump the title directly, we sometimes need to
|
||||||
|
// react even if the actual edition "value" doesn't change.
|
||||||
|
if (disc_nav_get_stream(mpctx)) {
|
||||||
|
int new_ed = *(int *)arg;
|
||||||
|
if (new_ed < 0 || new_ed >= demuxer->num_editions)
|
||||||
|
return M_PROPERTY_ERROR;
|
||||||
|
unsigned new_title = new_ed;
|
||||||
|
if (stream_control(demuxer->stream, STREAM_CTRL_SET_CURRENT_TITLE,
|
||||||
|
&new_title) < 1)
|
||||||
|
return M_PROPERTY_ERROR;
|
||||||
|
mpctx->opts->edition_id = new_ed;
|
||||||
|
m_config_notify_change_opt_ptr(mpctx->mconfig,
|
||||||
|
&mpctx->opts->edition_id);
|
||||||
|
mp_notify_property(mpctx, "edition");
|
||||||
|
mp_wakeup_core(mpctx);
|
||||||
|
return M_PROPERTY_OK;
|
||||||
|
}
|
||||||
|
return mp_property_generic_option(mpctx, prop, action, arg);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return mp_property_generic_option(mpctx, prop, action, arg);
|
return mp_property_generic_option(mpctx, prop, action, arg);
|
||||||
}
|
}
|
||||||
@@ -7449,6 +7469,47 @@ static void cmd_context_menu(void *p)
|
|||||||
vo_control(vo, VOCTRL_SHOW_MENU, NULL);
|
vo_control(vo, VOCTRL_SHOW_MENU, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cmd_discnav(void *p)
|
||||||
|
{
|
||||||
|
struct mp_cmd_ctx *cmd = p;
|
||||||
|
struct MPContext *mpctx = cmd->mpctx;
|
||||||
|
int action = cmd->args[0].v.i;
|
||||||
|
|
||||||
|
struct stream *s = disc_nav_get_stream(mpctx);
|
||||||
|
if (!s) {
|
||||||
|
cmd->success = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stream_nav_cmd nc = { .action = action };
|
||||||
|
|
||||||
|
struct stream_nav_state pre = {0};
|
||||||
|
stream_control(s, STREAM_CTRL_GET_NAV_STATE, &pre);
|
||||||
|
|
||||||
|
if (action == STREAM_NAV_MOUSE_MOVE || action == STREAM_NAV_MOUSE_CLICK) {
|
||||||
|
double nx = cmd->args[1].v.d;
|
||||||
|
double ny = cmd->args[2].v.d;
|
||||||
|
if (nx >= 0 && ny >= 0) {
|
||||||
|
if (pre.src_w <= 0 || pre.src_h <= 0 || nx > 1 || ny > 1) {
|
||||||
|
cmd->success = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nc.x = (int)(nx * pre.src_w);
|
||||||
|
nc.y = (int)(ny * pre.src_h);
|
||||||
|
} else if (!disc_nav_mouse_pos_to_src(mpctx, pre.src_w, pre.src_h,
|
||||||
|
&nc.x, &nc.y))
|
||||||
|
{
|
||||||
|
cmd->success = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream_control(s, STREAM_CTRL_NAV_CMD, &nc) < 1)
|
||||||
|
cmd->success = false;
|
||||||
|
|
||||||
|
mp_wakeup_core(mpctx);
|
||||||
|
}
|
||||||
|
|
||||||
static void cmd_flush_status_line(void *p)
|
static void cmd_flush_status_line(void *p)
|
||||||
{
|
{
|
||||||
struct mp_cmd_ctx *cmd = p;
|
struct mp_cmd_ctx *cmd = p;
|
||||||
@@ -8013,6 +8074,23 @@ const struct mp_cmd_def mp_cmds[] = {
|
|||||||
|
|
||||||
{ "context-menu", cmd_context_menu },
|
{ "context-menu", cmd_context_menu },
|
||||||
|
|
||||||
|
{ "discnav", cmd_discnav,
|
||||||
|
{ {"action", OPT_CHOICE(v.i,
|
||||||
|
{"up", STREAM_NAV_UP},
|
||||||
|
{"down", STREAM_NAV_DOWN},
|
||||||
|
{"left", STREAM_NAV_LEFT},
|
||||||
|
{"right", STREAM_NAV_RIGHT},
|
||||||
|
{"select", STREAM_NAV_SELECT},
|
||||||
|
{"menu", STREAM_NAV_MENU_ROOT},
|
||||||
|
{"title-menu", STREAM_NAV_MENU_TITLE},
|
||||||
|
{"popup", STREAM_NAV_MENU_POPUP},
|
||||||
|
{"prev", STREAM_NAV_PREV_MENU},
|
||||||
|
{"mouse-move", STREAM_NAV_MOUSE_MOVE},
|
||||||
|
{"mouse-click", STREAM_NAV_MOUSE_CLICK})},
|
||||||
|
{"x", OPT_DOUBLE(v.d), OPTDEF_DOUBLE(-1)},
|
||||||
|
{"y", OPT_DOUBLE(v.d), OPTDEF_DOUBLE(-1)} },
|
||||||
|
},
|
||||||
|
|
||||||
{ "flush-status-line", cmd_flush_status_line, { {"clear", OPT_BOOL(v.b)} } },
|
{ "flush-status-line", cmd_flush_status_line, { {"clear", OPT_BOOL(v.b)} } },
|
||||||
|
|
||||||
{ "notify-property", cmd_notify_property, { {"property", OPT_STRING(v.s)} } },
|
{ "notify-property", cmd_notify_property, { {"property", OPT_STRING(v.s)} } },
|
||||||
@@ -8438,6 +8516,10 @@ void mp_option_run_callback(struct MPContext *mpctx, struct mp_option_callback *
|
|||||||
mp_notify_property(mpctx, "current-edition");
|
mp_notify_property(mpctx, "current-edition");
|
||||||
print_track_list(mpctx,
|
print_track_list(mpctx,
|
||||||
mp_tprintf(42, "Selected edition %d:", demuxer->edition));
|
mp_tprintf(42, "Selected edition %d:", demuxer->edition));
|
||||||
|
} else if (disc_nav_get_stream(mpctx)) {
|
||||||
|
unsigned new_title = opts->edition_id;
|
||||||
|
stream_control(demuxer->stream,
|
||||||
|
STREAM_CTRL_SET_CURRENT_TITLE, &new_title);
|
||||||
} else {
|
} else {
|
||||||
if (!mpctx->stop_play)
|
if (!mpctx->stop_play)
|
||||||
mpctx->stop_play = PT_CURRENT_ENTRY;
|
mpctx->stop_play = PT_CURRENT_ENTRY;
|
||||||
|
|||||||
Reference in new issue
Block a user