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.
This commit is contained in:
David Vaughan 2024-02-03 13:44:49 -08:00 committed by Dudemanguy
parent b71af009dc
commit 9e162d2604
4 changed files with 45 additions and 5 deletions

View File

@ -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-next>
Insert the file into the playlist, directly after the current entry.
<insert-next-play>
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,..``.

View File

@ -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--;

View File

@ -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);

View File

@ -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},
},