mirror of
https://github.com/mpv-player/mpv.git
synced 2026-10-24 20:20:18 +08:00
command: add a revert_seek command
As discussed on IRC.
This commit is contained in:
@@ -86,6 +86,12 @@ List of Input Commands
|
||||
keyframes
|
||||
Always restart playback at keyframe boundaries (fast).
|
||||
|
||||
``revert_seek``
|
||||
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
|
||||
``revert_seek`` command itself.
|
||||
|
||||
``frame_step``
|
||||
Play one frame, then pause.
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ static const struct mp_cmd_def mp_cmds[] = {
|
||||
},
|
||||
.allow_auto_repeat = true,
|
||||
},
|
||||
{ MP_CMD_REVERT_SEEK, "revert_seek", },
|
||||
{ MP_CMD_QUIT, "quit", { OARG_INT(0) } },
|
||||
{ MP_CMD_QUIT_WATCH_LATER, "quit_watch_later", },
|
||||
{ MP_CMD_STOP, "stop", },
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
enum mp_command_type {
|
||||
MP_CMD_IGNORE,
|
||||
MP_CMD_SEEK,
|
||||
MP_CMD_REVERT_SEEK,
|
||||
MP_CMD_QUIT,
|
||||
MP_CMD_QUIT_WATCH_LATER,
|
||||
MP_CMD_PLAYLIST_NEXT,
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "config.h"
|
||||
#include "talloc.h"
|
||||
#include "command.h"
|
||||
#include "osdep/timer.h"
|
||||
#include "mpvcore/mp_common.h"
|
||||
#include "mpvcore/input/input.h"
|
||||
#include "stream/stream.h"
|
||||
@@ -75,6 +76,9 @@
|
||||
struct command_ctx {
|
||||
int events;
|
||||
|
||||
double last_seek_time;
|
||||
double last_seek_pts;
|
||||
|
||||
struct cycle_counter *cycle_counters;
|
||||
int num_cycle_counters;
|
||||
|
||||
@@ -87,6 +91,16 @@ static int edit_filters(struct MPContext *mpctx, enum stream_type mediatype,
|
||||
static int set_filters(struct MPContext *mpctx, enum stream_type mediatype,
|
||||
struct m_obj_settings *new_chain);
|
||||
|
||||
// Call before a seek, in order to allow revert_seek to undo the seek.
|
||||
static void mark_seek(struct MPContext *mpctx)
|
||||
{
|
||||
struct command_ctx *cmd = mpctx->command_ctx;
|
||||
double now = mp_time_sec();
|
||||
if (now > cmd->last_seek_time + 2.0 || cmd->last_seek_pts == MP_NOPTS_VALUE)
|
||||
cmd->last_seek_pts = get_current_time(mpctx);
|
||||
cmd->last_seek_time = now;
|
||||
}
|
||||
|
||||
static char *format_bitrate(int rate)
|
||||
{
|
||||
return talloc_asprintf(NULL, "%d kbps", rate * 8 / 1000);
|
||||
@@ -397,6 +411,7 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
|
||||
}
|
||||
case M_PROPERTY_SWITCH:
|
||||
case M_PROPERTY_SET: ;
|
||||
mark_seek(mpctx);
|
||||
int step_all;
|
||||
if (action == M_PROPERTY_SWITCH) {
|
||||
struct m_property_switch_arg *sarg = arg;
|
||||
@@ -2475,6 +2490,7 @@ static bool check_property_autorepeat(char *property, struct MPContext *mpctx)
|
||||
|
||||
void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
{
|
||||
struct command_ctx *cmdctx = mpctx->command_ctx;
|
||||
struct MPOpts *opts = mpctx->opts;
|
||||
int osd_duration = opts->osd_duration;
|
||||
bool auto_osd = cmd->on_osd == MP_ON_OSD_AUTO;
|
||||
@@ -2500,6 +2516,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
double v = cmd->args[0].v.d * cmd->scale;
|
||||
int abs = cmd->args[1].v.i;
|
||||
int exact = cmd->args[2].v.i;
|
||||
mark_seek(mpctx);
|
||||
if (abs == 2) { // Absolute seek to a timestamp in seconds
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, v, exact);
|
||||
set_osd_function(mpctx,
|
||||
@@ -2518,6 +2535,20 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
case MP_CMD_REVERT_SEEK: {
|
||||
double oldpts = cmdctx->last_seek_pts;
|
||||
if (oldpts != MP_NOPTS_VALUE) {
|
||||
cmdctx->last_seek_pts = get_current_time(mpctx);
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, oldpts, 1);
|
||||
set_osd_function(mpctx, OSD_REW);
|
||||
if (bar_osd)
|
||||
mpctx->add_osd_seek_info |= OSD_SEEK_INFO_BAR;
|
||||
if (msg_or_nobar_osd)
|
||||
mpctx->add_osd_seek_info |= OSD_SEEK_INFO_TEXT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MP_CMD_SET: {
|
||||
int r = mp_property_do(cmd->args[0].v.s, M_PROPERTY_SET_STRING,
|
||||
cmd->args[1].v.s, mpctx);
|
||||
@@ -2687,6 +2718,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
// frame PTS and sub PTS rarely match exactly). Add some
|
||||
// rounding for the mess of it.
|
||||
a[0] += 0.01 * (a[1] > 0 ? 1 : -1);
|
||||
mark_seek(mpctx);
|
||||
queue_seek(mpctx, MPSEEK_RELATIVE, a[0], 1);
|
||||
set_osd_function(mpctx, (a[0] > 0) ? OSD_FFW : OSD_REW);
|
||||
if (bar_osd)
|
||||
@@ -3137,7 +3169,10 @@ void command_uninit(struct MPContext *mpctx)
|
||||
|
||||
void command_init(struct MPContext *mpctx)
|
||||
{
|
||||
mpctx->command_ctx = talloc_zero(NULL, struct command_ctx);
|
||||
mpctx->command_ctx = talloc(NULL, struct command_ctx);
|
||||
*mpctx->command_ctx = (struct command_ctx){
|
||||
.last_seek_pts = MP_NOPTS_VALUE,
|
||||
};
|
||||
}
|
||||
|
||||
// Notify that a property might have changed.
|
||||
@@ -3183,6 +3218,8 @@ void mp_flush_events(struct MPContext *mpctx)
|
||||
}
|
||||
if (name)
|
||||
handle_script_event(mpctx, name, "");
|
||||
if (event == MP_EVENT_START_FILE)
|
||||
ctx->last_seek_pts = MP_NOPTS_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user