diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/cfg-mplayer.h | 3 | ||||
-rw-r--r-- | core/command.c | 6 | ||||
-rw-r--r-- | core/defaultopts.c | 1 | ||||
-rw-r--r-- | core/input/input.c | 1 | ||||
-rw-r--r-- | core/input/input.h | 1 | ||||
-rw-r--r-- | core/mp_core.h | 1 | ||||
-rw-r--r-- | core/mplayer.c | 125 | ||||
-rw-r--r-- | core/options.h | 2 | ||||
-rw-r--r-- | core/path.c | 14 | ||||
-rw-r--r-- | core/path.h | 2 |
10 files changed, 155 insertions, 1 deletions
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h index 570c403f9c..f2e90d07d2 100644 --- a/core/cfg-mplayer.h +++ b/core/cfg-mplayer.h @@ -650,6 +650,9 @@ const m_option_t mplayer_opts[]={ {"{", NULL, CONF_TYPE_STORE, CONF_NOCFG, 0, 0, NULL}, {"}", NULL, CONF_TYPE_STORE, CONF_NOCFG, 0, 0, NULL}, + OPT_FLAG("resume-playback", position_resume, 0), + OPT_FLAG("save-position-on-quit", position_save_on_quit, 0), + OPT_FLAG("ordered-chapters", ordered_chapters, 0), OPT_INTRANGE("chapter-merge-threshold", chapter_merge_threshold, 0, 0, 10000), diff --git a/core/command.c b/core/command.c index 4831c939c0..72d6f34469 100644 --- a/core/command.c +++ b/core/command.c @@ -1856,6 +1856,12 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd) mpctx->quit_player_rc = cmd->args[0].v.i; break; + case MP_CMD_QUIT_WATCH_LATER: + mp_write_watch_later_conf(mpctx); + mpctx->stop_play = PT_QUIT; + mpctx->quit_player_rc = 0; + break; + case MP_CMD_PLAYLIST_NEXT: case MP_CMD_PLAYLIST_PREV: { diff --git a/core/defaultopts.c b/core/defaultopts.c index 03d697d732..b80bea5c1e 100644 --- a/core/defaultopts.c +++ b/core/defaultopts.c @@ -52,6 +52,7 @@ void set_default_mplayer_options(struct MPOpts *opts) .ordered_chapters = 1, .chapter_merge_threshold = 100, .load_config = 1, + .position_resume = 1, .stream_cache_min_percent = 20.0, .stream_cache_seek_min_percent = 50.0, .stream_cache_pause = 10.0, diff --git a/core/input/input.c b/core/input/input.c index 31b807d92f..7ba6b64cdc 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -126,6 +126,7 @@ static const mp_cmd_t mp_cmds[] = { }}, { MP_CMD_SPEED_MULT, "speed_mult", { ARG_FLOAT } }, { MP_CMD_QUIT, "quit", { OARG_INT(0) } }, + { MP_CMD_QUIT_WATCH_LATER, "quit_watch_later", }, { MP_CMD_STOP, "stop", }, { MP_CMD_FRAME_STEP, "frame_step", }, { MP_CMD_FRAME_BACK_STEP, "frame_back_step", }, diff --git a/core/input/input.h b/core/input/input.h index ff79222c9b..367abedfca 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -28,6 +28,7 @@ enum mp_command_type { MP_CMD_IGNORE, MP_CMD_SEEK, MP_CMD_QUIT, + MP_CMD_QUIT_WATCH_LATER, MP_CMD_PLAYLIST_NEXT, MP_CMD_PLAYLIST_PREV, MP_CMD_OSD, diff --git a/core/mp_core.h b/core/mp_core.h index 9588a77b24..2590eefb96 100644 --- a/core/mp_core.h +++ b/core/mp_core.h @@ -321,6 +321,7 @@ struct track *mp_track_by_tid(struct MPContext *mpctx, enum stream_type type, bool mp_remove_track(struct MPContext *mpctx, struct track *track); struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction); int mp_get_cache_percent(struct MPContext *mpctx); +void mp_write_watch_later_conf(struct MPContext *mpctx); // timeline/tl_matroska.c void build_ordered_chapter_timeline(struct MPContext *mpctx); diff --git a/core/mplayer.c b/core/mplayer.c index 9028cbafce..a6cc189df6 100644 --- a/core/mplayer.c +++ b/core/mplayer.c @@ -21,6 +21,7 @@ #include <stdbool.h> #include <math.h> #include <assert.h> +#include <ctype.h> #ifdef PTW32_STATIC_LIB #include <pthread.h> @@ -28,6 +29,7 @@ #include <libavutil/intreadwrite.h> #include <libavutil/attributes.h> +#include <libavutil/md5.h> #include <libavcodec/version.h> @@ -763,6 +765,121 @@ static void load_per_file_config(m_config_t *conf, const char * const file, } } +static bool might_be_an_url(bstr f) +{ + return bstr_find0(f, "://") >= 0; +} + +#define MP_WATCH_LATER_CONF "watch_later" + +static char *get_playback_resume_config_filename(const char *fname) +{ + char *res = NULL; + void *tmp = talloc_new(NULL); + const char *realpath = fname; + if (!might_be_an_url(bstr0(fname))) { + char *cwd = mp_getcwd(tmp); + if (!cwd) + goto exit; + realpath = mp_path_join(tmp, bstr0(cwd), bstr0(fname)); + } + uint8_t md5[16]; + av_md5_sum(md5, realpath, strlen(realpath)); + char *conf = talloc_strdup(tmp, ""); + for (int i = 0; i < 16; i++) + conf = talloc_asprintf_append(conf, "%02X", md5[i]); + + conf = talloc_asprintf(tmp, "%s/%s", MP_WATCH_LATER_CONF, conf); + + res = mp_find_user_config_file(conf); + +exit: + talloc_free(tmp); + return res; +} + +static const char *backup_properties[] = { + "osd-level", + //"loop", + "speed", + "edition", + "pause", + //"volume", + //"mute", + "audio-delay", + //"balance", + "fullscreen", + "colormatrix", + "colormatrix-input-range", + "colormatrix-output-range", + "ontop", + "border", + "gamma", + "brightness", + "contrast", + "saturation", + "hue", + "panscan", + "aid", + "vid", + "sid", + "sub-delay", + "sub-pos", + //"sub-visibility", + "sub-scale", + "ass-use-margins", + "ass-vsfilter-aspect-compat", + "ass-style-override", + 0 +}; + +void mp_write_watch_later_conf(struct MPContext *mpctx) +{ + void *tmp = talloc_new(NULL); + char *filename = mpctx->filename; + if (!filename) + goto exit; + + double pos = get_current_time(mpctx); + int percent = get_percent_pos(mpctx); + if (percent < 1 || percent > 99 || pos == MP_NOPTS_VALUE) + goto exit; + + mk_config_dir(MP_WATCH_LATER_CONF); + + char *conffile = get_playback_resume_config_filename(mpctx->filename); + talloc_steal(tmp, conffile); + if (!conffile) + goto exit; + + FILE *file = fopen(conffile, "wb"); + if (!file) + goto exit; + fprintf(file, "start=%f\n", pos); + for (int i = 0; backup_properties[i]; i++) { + const char *pname = backup_properties[i]; + char *tmp = NULL; + int r = mp_property_do(pname, M_PROPERTY_GET_STRING, &tmp, mpctx); + if (r == M_PROPERTY_OK) + fprintf(file, "%s=%s\n", pname, tmp); + talloc_free(tmp); + } + fclose(file); + +exit: + talloc_free(tmp); +} + +static void load_playback_resume(m_config_t *conf, const char *file) +{ + char *fname = get_playback_resume_config_filename(file); + if (fname) { + try_load_config(conf, fname); + unlink(fname); + } + talloc_free(fname); +} + static void load_per_file_options(m_config_t *conf, struct playlist_param *params, int params_count) @@ -3988,7 +4105,9 @@ static void play_current_file(struct MPContext *mpctx) load_per_output_config(mpctx->mconfig, PROFILE_CFG_AO, opts->audio_driver_list[0]); - assert(mpctx->playlist->current); + if (opts->position_resume) + load_playback_resume(mpctx->mconfig, mpctx->filename); + load_per_file_options(mpctx->mconfig, mpctx->playlist->current->params, mpctx->playlist->current->num_params); @@ -4283,6 +4402,9 @@ goto_enable_cache: ; terminate_playback: // don't jump here after ao/vo/getch initialization! + if (opts->position_save_on_quit && mpctx->stop_play != PT_RESTART) + mp_write_watch_later_conf(mpctx); + if (mpctx->step_frames) opts->pause = 1; @@ -4566,6 +4688,7 @@ int main(int argc, char *argv[]) init_input(mpctx); mpctx->playlist->current = mpctx->playlist->first; + play_files(mpctx); exit_player(mpctx, mpctx->stop_play == PT_QUIT ? EXIT_QUIT : EXIT_EOF, diff --git a/core/options.h b/core/options.h index 4729d7ca6a..276745492d 100644 --- a/core/options.h +++ b/core/options.h @@ -125,6 +125,8 @@ typedef struct MPOpts { int play_frames; double step_sec; int64_t seek_to_byte; + int position_resume; + int position_save_on_quit; int pause; int keep_open; int audio_id; diff --git a/core/path.c b/core/path.c index ed53d5d465..e373df21ab 100644 --- a/core/path.c +++ b/core/path.c @@ -31,6 +31,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> +#include <errno.h> #include "config.h" #include "core/mp_msg.h" #include "core/path.h" @@ -178,6 +179,19 @@ char *mp_path_join(void *talloc_ctx, struct bstr p1, struct bstr p2) have_separator ? "" : "/", BSTR_P(p2)); } +char *mp_getcwd(void *talloc_ctx) +{ + char *wd = talloc_array(talloc_ctx, char, 20); + while (getcwd(wd, talloc_get_size(wd)) == NULL) { + if (errno != ERANGE) { + talloc_free(wd); + return NULL; + } + wd = talloc_realloc(talloc_ctx, wd, char, talloc_get_size(wd) * 2); + } + return wd; +} + bool mp_path_exists(const char *path) { struct stat st; diff --git a/core/path.h b/core/path.h index 3711be44b9..a3033199df 100644 --- a/core/path.h +++ b/core/path.h @@ -51,6 +51,8 @@ struct bstr mp_dirname(const char *path); */ char *mp_path_join(void *talloc_ctx, struct bstr p1, struct bstr p2); +char *mp_getcwd(void *talloc_ctx); + bool mp_path_exists(const char *path); bool mp_path_isdir(const char *path); |