mirror of
https://github.com/mpv-player/mpv
synced 2024-12-25 00:02:13 +00:00
demux_playlist: add option to control recursive directory loading
Directories were always loaded recursively, which can be slow
(e.g. one of the subdirectories is a mounting point to a slow device)
and can unexpectedly expand into a massive playlist.
Due to the problems described in 503dada42f
,
this defaults to recursive loading.
ref. https://github.com/mpv-player/mpv/issues/9652
This commit is contained in:
parent
9ad14e0886
commit
f266eadf1e
@ -84,6 +84,7 @@ Interface changes
|
||||
passthrough the mpv window
|
||||
- icc and gpu-shader cache are now saved by default (use --no-icc-shader-cache and
|
||||
--no-gpu-shader-cache to disable)
|
||||
- add `--directory-mode=recursive|lazy|ignore`
|
||||
--- mpv 0.35.0 ---
|
||||
- add the `--vo=gpu-next` video output driver, as well as the options
|
||||
`--allow-delayed-peak-detect`, `--builtin-scalers`,
|
||||
|
@ -3945,6 +3945,13 @@ Demuxer
|
||||
libarchive opens all volumes anyway when playing the main file, even though
|
||||
mpv iterated no archive entries yet.
|
||||
|
||||
``--directory-mode=<recursive|lazy|ignore>``
|
||||
When opening a directory, open subdirectories recursively, lazily or not at
|
||||
all (default: recursive).
|
||||
|
||||
Values other then ``recursive`` can lead to problems with resuming playlists
|
||||
(`RESUMING PLAYBACK`_) and possibly other things.
|
||||
|
||||
Input
|
||||
-----
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "common/common.h"
|
||||
#include "options/options.h"
|
||||
#include "options/m_config.h"
|
||||
#include "common/msg.h"
|
||||
#include "common/playlist.h"
|
||||
#include "misc/thread_tools.h"
|
||||
@ -35,6 +36,31 @@
|
||||
|
||||
#define PROBE_SIZE (8 * 1024)
|
||||
|
||||
enum dir_mode {
|
||||
DIR_RECURSIVE,
|
||||
DIR_LAZY,
|
||||
DIR_IGNORE,
|
||||
};
|
||||
|
||||
#define OPT_BASE_STRUCT struct demux_playlist_opts
|
||||
struct demux_playlist_opts {
|
||||
int dir_mode;
|
||||
};
|
||||
|
||||
struct m_sub_options demux_playlist_conf = {
|
||||
.opts = (const struct m_option[]) {
|
||||
{"directory-mode", OPT_CHOICE(dir_mode,
|
||||
{"recursive", DIR_RECURSIVE},
|
||||
{"lazy", DIR_LAZY},
|
||||
{"ignore", DIR_IGNORE})},
|
||||
{0}
|
||||
},
|
||||
.size = sizeof(struct demux_playlist_opts),
|
||||
.defaults = &(const struct demux_playlist_opts){
|
||||
.dir_mode = DIR_RECURSIVE,
|
||||
},
|
||||
};
|
||||
|
||||
static bool check_mimetype(struct stream *s, const char *const *list)
|
||||
{
|
||||
if (s->mime_type) {
|
||||
@ -59,6 +85,7 @@ struct pl_parser {
|
||||
enum demux_check check_level;
|
||||
struct stream *real_stream;
|
||||
char *format;
|
||||
struct demux_playlist_opts *opts;
|
||||
};
|
||||
|
||||
|
||||
@ -323,6 +350,7 @@ static bool scan_dir(struct pl_parser *p, char *path,
|
||||
return false;
|
||||
}
|
||||
|
||||
int dir_mode = p->opts->dir_mode;
|
||||
struct dirent *ep;
|
||||
while ((ep = readdir(dp))) {
|
||||
if (ep->d_name[0] == '.')
|
||||
@ -334,16 +362,18 @@ static bool scan_dir(struct pl_parser *p, char *path,
|
||||
char *file = mp_path_join(p, path, ep->d_name);
|
||||
|
||||
struct stat st;
|
||||
if (stat(file, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
for (int n = 0; n < num_dir_stack; n++) {
|
||||
if (same_st(&dir_stack[n], &st)) {
|
||||
MP_VERBOSE(p, "Skip recursive entry: %s\n", file);
|
||||
goto skip;
|
||||
if (dir_mode != DIR_LAZY && stat(file, &st) == 0 && S_ISDIR(st.st_mode)) {
|
||||
if (dir_mode != DIR_IGNORE) {
|
||||
for (int n = 0; n < num_dir_stack; n++) {
|
||||
if (same_st(&dir_stack[n], &st)) {
|
||||
MP_VERBOSE(p, "Skip recursive entry: %s\n", file);
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dir_stack[num_dir_stack] = st;
|
||||
scan_dir(p, file, dir_stack, num_dir_stack + 1, files, num_files);
|
||||
dir_stack[num_dir_stack] = st;
|
||||
scan_dir(p, file, dir_stack, num_dir_stack + 1, files, num_files);
|
||||
}
|
||||
} else {
|
||||
MP_TARRAY_APPEND(p, *files, *num_files, file);
|
||||
}
|
||||
@ -458,6 +488,7 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
p->error = false;
|
||||
p->s = demuxer->stream;
|
||||
p->utf16 = stream_skip_bom(p->s);
|
||||
p->opts = mp_get_config_group(demuxer, demuxer->global, &demux_playlist_conf);
|
||||
bool ok = fmt->parse(p) >= 0 && !p->error;
|
||||
if (p->add_base)
|
||||
playlist_add_base_path(p->pl, mp_dirname(demuxer->filename));
|
||||
@ -471,7 +502,7 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
|
||||
return ok ? 0 : -1;
|
||||
}
|
||||
|
||||
const struct demuxer_desc demuxer_desc_playlist = {
|
||||
const demuxer_desc_t demuxer_desc_playlist = {
|
||||
.name = "playlist",
|
||||
.desc = "Playlist file",
|
||||
.open = open_file,
|
||||
|
@ -63,6 +63,7 @@ extern const struct m_sub_options zimg_conf;
|
||||
extern const struct m_sub_options drm_conf;
|
||||
extern const struct m_sub_options demux_rawaudio_conf;
|
||||
extern const struct m_sub_options demux_rawvideo_conf;
|
||||
extern const struct m_sub_options demux_playlist_conf;
|
||||
extern const struct m_sub_options demux_lavf_conf;
|
||||
extern const struct m_sub_options demux_mkv_conf;
|
||||
extern const struct m_sub_options demux_cue_conf;
|
||||
@ -591,6 +592,7 @@ static const m_option_t mp_opts[] = {
|
||||
{"", OPT_SUBSTRUCT(demux_lavf, demux_lavf_conf)},
|
||||
{"demuxer-rawaudio", OPT_SUBSTRUCT(demux_rawaudio, demux_rawaudio_conf)},
|
||||
{"demuxer-rawvideo", OPT_SUBSTRUCT(demux_rawvideo, demux_rawvideo_conf)},
|
||||
{"", OPT_SUBSTRUCT(demux_playlist, demux_playlist_conf)},
|
||||
{"demuxer-mkv", OPT_SUBSTRUCT(demux_mkv, demux_mkv_conf)},
|
||||
{"demuxer-cue", OPT_SUBSTRUCT(demux_cue, demux_cue_conf)},
|
||||
|
||||
|
@ -326,6 +326,7 @@ typedef struct MPOpts {
|
||||
|
||||
struct demux_rawaudio_opts *demux_rawaudio;
|
||||
struct demux_rawvideo_opts *demux_rawvideo;
|
||||
struct demux_playlist_opts *demux_playlist;
|
||||
struct demux_lavf_opts *demux_lavf;
|
||||
struct demux_mkv_opts *demux_mkv;
|
||||
struct demux_cue_opts *demux_cue;
|
||||
|
Loading…
Reference in New Issue
Block a user