From 9e162d26046005ca0f58f22a057e1d8393900d50 Mon Sep 17 00:00:00 2001 From: David Vaughan Date: Sat, 3 Feb 2024 13:44:49 -0800 Subject: [PATCH] player: add loadfile insert-next commands This commit adds two new commands (`insert-next` and `insert-next-play`) which mirror the existing commands, `append` and `append-play` in functionality, with the difference that they insert directly after the current playlist entry, rather than at the end of the playlist. This change gives MPV a piece of functionality already found in (for example) Spotify's media player: "play next". Additionally, using the new `insert-next` command, users can trivially write a script to play a new piece of media immediately without otherwise clearing or altering the remainder of the playlist. --- DOCS/man/input.rst | 6 ++++++ common/playlist.c | 19 +++++++++++++++++++ common/playlist.h | 4 ++++ player/command.c | 21 ++++++++++++++++----- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 6ac9fb2bd5..e79979f243 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -469,6 +469,12 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_). Append the file, and if nothing is currently playing, start playback. (Always starts with the added file, even if the playlist was not empty before running this command.) + + Insert the file into the playlist, directly after the current entry. + + Insert the file next, and if nothing is currently playing, start playback. + (Always starts with the added file, even if the playlist was not empty + before running this command.) The third argument is a list of options and values which should be set while the file is playing. It is of the form ``opt1=value1,opt2=value2,..``. diff --git a/common/playlist.c b/common/playlist.c index 5de8e62745..eda583224c 100644 --- a/common/playlist.c +++ b/common/playlist.c @@ -70,6 +70,25 @@ void playlist_add(struct playlist *pl, struct playlist_entry *add) talloc_steal(pl, add); } +// Inserts the entry so that it comes directly after "at" (or move to end, if at==NULL). +void playlist_insert_next(struct playlist *pl, struct playlist_entry *add, + struct playlist_entry *at) +{ + assert(add->filename); + assert(!at || at->pl == pl); + + int index = at ? at->pl_index + 1 : pl->num_entries; + MP_TARRAY_INSERT_AT(pl, pl->entries, pl->num_entries, index, add); + + add->pl = pl; + add->pl_index = index; + add->id = ++pl->id_alloc; + + playlist_update_indexes(pl, index, pl->num_entries); + + talloc_steal(pl, add); +} + void playlist_entry_unref(struct playlist_entry *e) { e->reserved--; diff --git a/common/playlist.h b/common/playlist.h index aecd53988b..f1ee07d77c 100644 --- a/common/playlist.h +++ b/common/playlist.h @@ -82,6 +82,10 @@ void playlist_entry_add_params(struct playlist_entry *e, struct playlist_entry *playlist_entry_new(const char *filename); void playlist_add(struct playlist *pl, struct playlist_entry *add); + +void playlist_insert_next(struct playlist *pl, struct playlist_entry *entry, + struct playlist_entry *at); + void playlist_remove(struct playlist *pl, struct playlist_entry *entry); void playlist_clear(struct playlist *pl); void playlist_clear_except_current(struct playlist *pl); diff --git a/player/command.c b/player/command.c index 3eecdd3915..3e040bc256 100644 --- a/player/command.c +++ b/player/command.c @@ -5527,9 +5527,13 @@ static void cmd_loadfile(void *p) struct mp_cmd_ctx *cmd = p; struct MPContext *mpctx = cmd->mpctx; char *filename = cmd->args[0].v.s; - int append = cmd->args[1].v.i; + int action = cmd->args[1].v.i; - if (!append) + bool replace = (action == 0); + bool insert_next = (action == 3 || action == 4); + bool play = (action == 2 || action == 4); + + if (replace) playlist_clear(mpctx->playlist); struct playlist_entry *entry = playlist_entry_new(filename); @@ -5538,13 +5542,18 @@ static void cmd_loadfile(void *p) for (int i = 0; pairs[i] && pairs[i + 1]; i += 2) playlist_entry_add_param(entry, bstr0(pairs[i]), bstr0(pairs[i + 1])); } - playlist_add(mpctx->playlist, entry); + + if (insert_next) { + playlist_insert_next(mpctx->playlist, entry, mpctx->playlist->current); + } else { + playlist_add(mpctx->playlist, entry); + } struct mpv_node *res = &cmd->result; node_init(res, MPV_FORMAT_NODE_MAP, NULL); node_map_add_int64(res, "playlist_entry_id", entry->id); - if (!append || (append == 2 && !mpctx->playlist->current)) { + if (replace || (play && !mpctx->playlist->current)) { if (mpctx->opts->position_save_on_quit) // requested in issue #1148 mp_write_watch_later_conf(mpctx); mp_set_playlist_entry(mpctx, entry); @@ -6681,7 +6690,9 @@ const struct mp_cmd_def mp_cmds[] = { {"flags", OPT_CHOICE(v.i, {"replace", 0}, {"append", 1}, - {"append-play", 2}), + {"append-play", 2}, + {"insert-next", 3}, + {"insert-next-play", 4}), .flags = MP_CMD_OPT_ARG}, {"options", OPT_KEYVALUELIST(v.str_list), .flags = MP_CMD_OPT_ARG}, },