summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorChris Down <chris@chrisdown.name>2019-11-09 18:24:16 +0000
committerwm4 <1387750+wm4@users.noreply.github.com>2019-11-20 15:11:33 +0100
commite143966a76a259e4e83fce1b816c8adf86898ab0 (patch)
treed8261a5c7c0c5be7f91d7be9bd3a3d962dfc3ac4 /player
parent1649ba15ab60a99db4ee6bd914d614848d8ed044 (diff)
downloadmpv-e143966a76a259e4e83fce1b816c8adf86898ab0.tar.bz2
mpv-e143966a76a259e4e83fce1b816c8adf86898ab0.tar.xz
player: Optionally validate st_mtime when restoring playback state
I often watch sporting events. On many occasions I get files with the same filename for each session. For example, for F1 I might have the following directory structure: F1/ FP1.mkv FP2.mkv FP3.mkv Qualification.mkv Race.mkv Since usually one simply watches one race after the other, I usually just rsync the new event's files over the old ones, so, for example, Race.mkv will be replaced from the file for the last event with the file from the new event. One problem with this is that I like to use --resume-playback for other kinds of media, so I have it on by default. That works great for, say, a movie, but doesn't work so well with this scheme, because you can trivially forget to pass --no-resume-playback on the command line and end up 2 hours in, watching spoilers as the race results scroll down the screen :-) This patch adds a new option, --resume-playback-check-mtime, which validates that the file's mtime hasn't changed since the watch_later configuration was saved. It does this by setting the watch_later configuration to have the same mtime as the file after it is saved. Switching back and forth between checking mtime and not checking mtime works fine, as we only choose whether to compare based on it, but we update the watch_later configuration mtime regardless of its value.
Diffstat (limited to 'player')
-rw-r--r--player/configfiles.c44
1 files changed, 44 insertions, 0 deletions
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 "