diff options
author | wm4 <wm4@nowhere> | 2013-09-04 16:08:36 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-09-04 16:15:09 +0200 |
commit | 3bb217d5e9fda241693c7f3c6a4046c845d8d5a8 (patch) | |
tree | c9bc6582aefd62d4a1c31c300c527395c2da6a14 /mpvcore | |
parent | b0f8e03f17c3dca88fa28265e88f7ec4c0d01d4d (diff) | |
download | mpv-3bb217d5e9fda241693c7f3c6a4046c845d8d5a8.tar.bz2 mpv-3bb217d5e9fda241693c7f3c6a4046c845d8d5a8.tar.xz |
mplayer: allow resuming from playlist
This includes the case of passing multiple files to command line
(internally this is the same as loading a playlist).
Resuming works by finding the first playlist entry that can be resumed.
Alternative implementations would be possible, such as hashing the
playlist contents. But this implementation is simpler, and doesn't have
the disadvantage that changes to the playlist (like appending entries)
will throw away the resume point.
This makes loading large playlists a bit slower, because it has to look
into ~/.mpv/watch_later/ for every entry. Loading a 15000 entries
playlist now increases from 150ms to 400ms. Considering you rarely load
playlists this big with mpv (because it's impractical considering the
terminal and non-GUI nature of the player), this is probably ok.
Diffstat (limited to 'mpvcore')
-rw-r--r-- | mpvcore/command.c | 6 | ||||
-rw-r--r-- | mpvcore/mp_core.h | 1 | ||||
-rw-r--r-- | mpvcore/mplayer.c | 22 |
3 files changed, 26 insertions, 3 deletions
diff --git a/mpvcore/command.c b/mpvcore/command.c index 1a50504b8b..3834f4ed30 100644 --- a/mpvcore/command.c +++ b/mpvcore/command.c @@ -2332,8 +2332,10 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd) playlist_transfer_entries(mpctx->playlist, pl); talloc_free(pl); - if (!append && mpctx->playlist->first) - mp_set_playlist_entry(mpctx, mpctx->playlist->first); + if (!append && mpctx->playlist->first) { + struct playlist_entry *e = mp_resume_playlist(mpctx->playlist); + mp_set_playlist_entry(mpctx, e ? e : mpctx->playlist->first); + } } else { mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "\nUnable to load playlist %s.\n", filename); diff --git a/mpvcore/mp_core.h b/mpvcore/mp_core.h index ac79d6ca0c..3bf2c8d6aa 100644 --- a/mpvcore/mp_core.h +++ b/mpvcore/mp_core.h @@ -334,6 +334,7 @@ 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); void mp_set_playlist_entry(struct MPContext *mpctx, struct playlist_entry *e); +struct playlist_entry *mp_resume_playlist(struct playlist *pl); void mp_force_video_refresh(struct MPContext *mpctx); void mp_print_version(int always); diff --git a/mpvcore/mplayer.c b/mpvcore/mplayer.c index be820dd10e..8918be3615 100644 --- a/mpvcore/mplayer.c +++ b/mpvcore/mplayer.c @@ -898,6 +898,23 @@ static void load_playback_resume(m_config_t *conf, const char *file) talloc_free(fname); } +// Returns the first file that has a resume config. +// Compared to hashing the playlist file or contents and managing separate +// resume file for them, this is simpler, and also has the nice property +// that appending to a playlist doesn't interfere with resuming (especially +// if the playlist comes from the command line). +struct playlist_entry *mp_resume_playlist(struct playlist *playlist) +{ + for (struct playlist_entry *e = playlist->first; e; e = e->next) { + char *conf = get_playback_resume_config_filename(e->filename); + bool exists = conf && mp_path_exists(conf); + talloc_free(conf); + if (exists) + return e; + } + return NULL; +} + static void load_per_file_options(m_config_t *conf, struct playlist_param *params, int params_count) @@ -4757,7 +4774,10 @@ static int mpv_main(int argc, char *argv[]) if (opts->shuffle) playlist_shuffle(mpctx->playlist); - mpctx->playlist->current = mpctx->playlist->first; + + mpctx->playlist->current = mp_resume_playlist(mpctx->playlist); + if (!mpctx->playlist->current) + mpctx->playlist->current = mpctx->playlist->first; play_files(mpctx); |