summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst2
-rw-r--r--DOCS/man/options.rst7
-rw-r--r--options/options.c1
-rw-r--r--options/options.h1
-rw-r--r--osdep/io.h3
-rw-r--r--player/configfiles.c44
6 files changed, 58 insertions, 0 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 26337e9713..3a399fb265 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -25,6 +25,8 @@ Interface changes
::
--- mpv 0.31.0 ---
+ - add `--resume-playback-check-mtime` to check consistent mtime when
+ restoring playback state.
- add `--d3d11-output-csp` to enable explicit selection of a D3D11
swap chain color space.
- the --sws- options and similar now affect vo_image and screenshot
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 3c52acec00..b2ba69ff26 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -714,6 +714,13 @@ Program Behavior
subdirectory (usually ``~/.config/mpv/watch_later/``).
See ``quit-watch-later`` input command.
+``--resume-playback-check-mtime``
+ Only restore the playback position from the ``watch_later`` configuration
+ subdirectory (usually ``~/.config/mpv/watch_later/``) if the file's
+ modification time is the same as at the time of saving. This may prevent
+ skipping forward in files with the same name which have different content.
+ (Default: ``no``)
+
``--profile=<profile1,profile2,...>``
Use the given profile(s), ``--profile=help`` displays a list of the
defined profiles.
diff --git a/options/options.c b/options/options.c
index 480186a908..1f0c9b1ef3 100644
--- a/options/options.c
+++ b/options/options.c
@@ -631,6 +631,7 @@ const m_option_t mp_opts[] = {
OPT_ALIAS("loop", "loop-file"),
OPT_FLAG("resume-playback", position_resume, 0),
+ OPT_FLAG("resume-playback-check-mtime", position_check_mtime, 0),
OPT_FLAG("save-position-on-quit", position_save_on_quit, 0),
OPT_FLAG("write-filename-in-watch-later-config", write_filename_in_watch_later_config, 0),
OPT_FLAG("ignore-path-in-watch-later-config", ignore_path_in_watch_later_config, 0),
diff --git a/options/options.h b/options/options.h
index 2f7e368446..126e4cb59a 100644
--- a/options/options.h
+++ b/options/options.h
@@ -232,6 +232,7 @@ typedef struct MPOpts {
double ab_loop[2];
double step_sec;
int position_resume;
+ int position_check_mtime;
int position_save_on_quit;
int write_filename_in_watch_later_config;
int ignore_path_in_watch_later_config;
diff --git a/osdep/io.h b/osdep/io.h
index 8699fb3e4a..12907e5cc9 100644
--- a/osdep/io.h
+++ b/osdep/io.h
@@ -172,6 +172,9 @@ void mp_globfree(mp_glob_t *pglob);
#undef fstat
#define fstat(...) mp_fstat(__VA_ARGS__)
+#define utime(...) _utime(__VA_ARGS__)
+#define utimbuf _utimbuf
+
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
int msync(void *addr, size_t length, int flags);
diff --git a/player/configfiles.c b/player/configfiles.c
index 668b34c542..d9a1e7d9f1 100644
--- a/player/configfiles.c
+++ b/player/configfiles.c
@@ -15,12 +15,14 @@
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <errno.h>
#include <stddef.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
+#include <utime.h>
#include <libavutil/md5.h>
@@ -155,6 +157,32 @@ void mp_load_auto_profiles(struct MPContext *mpctx)
#define MP_WATCH_LATER_CONF "watch_later"
+static bool check_mtime(const char *f1, const char *f2)
+{
+ struct stat st1, st2;
+ if (stat(f1, &st1) != 0 || stat(f2, &st2) != 0)
+ return false;
+ return st1.st_mtime == st2.st_mtime;
+}
+
+static bool copy_mtime(const char *f1, const char *f2)
+{
+ struct stat st1, st2;
+
+ if (stat(f1, &st1) != 0 || stat(f2, &st2) != 0)
+ return false;
+
+ struct utimbuf ut = {
+ .actime = st2.st_atime, // we want to pass this through intact
+ .modtime = st1.st_mtime,
+ };
+
+ if (!utime(f2, &ut))
+ return false;
+
+ return true;
+}
+
static char *mp_get_playback_resume_config_filename(struct MPContext *mpctx,
const char *fname)
{
@@ -290,6 +318,10 @@ static void write_redirect(struct MPContext *mpctx, char *path)
write_filename(mpctx, file, path);
fclose(file);
}
+
+ if (mpctx->opts->position_check_mtime && !copy_mtime(path, conffile))
+ MP_WARN(mpctx, "Can't copy mtime from %s to %s\n", path, conffile);
+
talloc_free(conffile);
}
}
@@ -346,6 +378,13 @@ void mp_write_watch_later_conf(struct MPContext *mpctx)
}
fclose(file);
+ if (mpctx->opts->position_check_mtime &&
+ !copy_mtime(cur->filename, conffile))
+ {
+ MP_WARN(mpctx, "Can't copy mtime from %s to %s\n", cur->filename,
+ conffile);
+ }
+
// This allows us to recursively resume directories etc., whose entries are
// expanded the first time it's "played". For example, if "/a/b/c.mkv" is
// the current entry, then we want to resume this file if the user does
@@ -387,6 +426,11 @@ void mp_load_playback_resume(struct MPContext *mpctx, const char *file)
return;
char *fname = mp_get_playback_resume_config_filename(mpctx, file);
if (fname && mp_path_exists(fname)) {
+ if (mpctx->opts->position_check_mtime && !check_mtime(file, fname)) {
+ talloc_free(fname);
+ return;
+ }
+
// Never apply the saved start position to following files
m_config_backup_opt(mpctx->mconfig, "start");
MP_INFO(mpctx, "Resuming playback. This behavior can "