mirror of https://github.com/mpv-player/mpv
demux: add --autocreate-playlist
This commit is contained in:
parent
4b97c23dac
commit
bb9b862f0c
|
@ -67,6 +67,7 @@ static const demuxer_desc_t *const demuxer_list[] = {
|
|||
&demuxer_desc_disc,
|
||||
&demuxer_desc_edl,
|
||||
&demuxer_desc_cue,
|
||||
&demuxer_desc_playlist,
|
||||
&demuxer_desc_rawaudio,
|
||||
&demuxer_desc_rawvideo,
|
||||
&demuxer_desc_matroska,
|
||||
|
@ -75,7 +76,6 @@ static const demuxer_desc_t *const demuxer_list[] = {
|
|||
#endif
|
||||
&demuxer_desc_lavf,
|
||||
&demuxer_desc_mf,
|
||||
&demuxer_desc_playlist,
|
||||
&demuxer_desc_null,
|
||||
NULL
|
||||
};
|
||||
|
@ -117,6 +117,7 @@ const struct m_sub_options demux_conf = {
|
|||
{"demuxer-backward-playback-step", OPT_DOUBLE(back_seek_size),
|
||||
M_RANGE(0, DBL_MAX)},
|
||||
{"metadata-codepage", OPT_STRING(meta_cp)},
|
||||
{"autocreate-playlist", OPT_BOOL(autocreate_playlist)},
|
||||
{0}
|
||||
},
|
||||
.size = sizeof(struct demux_opts),
|
||||
|
|
|
@ -86,6 +86,7 @@ struct demux_opts {
|
|||
double back_seek_size;
|
||||
char *meta_cp;
|
||||
bool force_retry_eof;
|
||||
bool autocreate_playlist;
|
||||
};
|
||||
|
||||
#define SEEK_FACTOR (1 << 1) // argument is in range [0,1]
|
||||
|
@ -211,6 +212,7 @@ struct demuxer_params {
|
|||
bool stream_record; // if true, enable stream recording if option is set
|
||||
int stream_flags;
|
||||
struct stream *external_stream; // if set, use this, don't open or close streams
|
||||
bool has_playlist;
|
||||
// result
|
||||
bool demuxer_failed;
|
||||
};
|
||||
|
|
|
@ -85,6 +85,7 @@ struct pl_parser {
|
|||
bool force;
|
||||
bool add_base;
|
||||
bool line_allocated;
|
||||
bool create_dir_playlist;
|
||||
enum demux_check check_level;
|
||||
struct stream *real_stream;
|
||||
char *format;
|
||||
|
@ -463,14 +464,25 @@ static bool scan_dir(struct pl_parser *p, char *path,
|
|||
|
||||
static int parse_dir(struct pl_parser *p)
|
||||
{
|
||||
if (!p->real_stream->is_directory)
|
||||
return -1;
|
||||
if (p->probing)
|
||||
return 0;
|
||||
int ret = -1;
|
||||
struct stream *stream = p->real_stream;
|
||||
if (p->create_dir_playlist && p->real_stream->is_local_file && !p->real_stream->is_directory) {
|
||||
int flags = STREAM_ORIGIN_DIRECT | STREAM_READ | STREAM_LOCAL_FS_ONLY |
|
||||
STREAM_LESS_NOISE;
|
||||
bstr dir = mp_dirname(p->real_stream->url);
|
||||
if (dir.len)
|
||||
stream = stream_create(bstrdup0(p, dir), flags, NULL, p->global);
|
||||
}
|
||||
if (!stream->is_directory)
|
||||
goto done;
|
||||
if (p->probing) {
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
char *path = mp_file_get_path(p, bstr0(p->real_stream->url));
|
||||
char *path = mp_file_get_path(p, bstr0(stream->url));
|
||||
if (!path)
|
||||
return -1;
|
||||
goto done;
|
||||
|
||||
struct stat dir_stack[MAX_DIR_STACK];
|
||||
|
||||
|
@ -483,8 +495,12 @@ static int parse_dir(struct pl_parser *p)
|
|||
scan_dir(p, path, dir_stack, 0);
|
||||
|
||||
p->add_base = false;
|
||||
ret = p->pl->num_entries > 0 ? 0 : -1;
|
||||
|
||||
return p->pl->num_entries > 0 ? 0 : -1;
|
||||
done:
|
||||
if (stream != p->real_stream)
|
||||
free_stream(stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MIME_TYPES(...) \
|
||||
|
@ -497,7 +513,6 @@ struct pl_format {
|
|||
};
|
||||
|
||||
static const struct pl_format formats[] = {
|
||||
{"directory", parse_dir},
|
||||
{"m3u", parse_m3u,
|
||||
MIME_TYPES("audio/mpegurl", "audio/x-mpegurl", "application/x-mpegurl")},
|
||||
{"ini", parse_ref_init},
|
||||
|
@ -505,6 +520,7 @@ static const struct pl_format formats[] = {
|
|||
MIME_TYPES("audio/x-scpls")},
|
||||
{"url", parse_url},
|
||||
{"txt", parse_txt},
|
||||
{"directory", parse_dir},
|
||||
};
|
||||
|
||||
static const struct pl_format *probe_pl(struct pl_parser *p)
|
||||
|
@ -549,6 +565,8 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
|
|||
p->force = force;
|
||||
p->check_level = check;
|
||||
p->probing = true;
|
||||
p->create_dir_playlist = !demuxer->params->has_playlist && opts->autocreate_playlist;
|
||||
|
||||
const struct pl_format *fmt = probe_pl(p);
|
||||
free_stream(p->s);
|
||||
playlist_clear(p->pl);
|
||||
|
|
|
@ -1041,6 +1041,17 @@ void prepare_playlist(struct MPContext *mpctx, struct playlist *pl)
|
|||
if (opts->playlist_pos >= 0)
|
||||
pl->current = playlist_entry_from_index(pl, opts->playlist_pos);
|
||||
|
||||
for (int i = 0; i < pl->num_entries; ++i) {
|
||||
if (!pl->entries[i]->playlist_path)
|
||||
continue;
|
||||
// If playlist_path exists as an element in the playlist itself, it means
|
||||
// playlist was autogenerated.
|
||||
if (!strcmp(pl->entries[i]->filename, pl->entries[i]->playlist_path)) {
|
||||
pl->current = pl->entries[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts->shuffle)
|
||||
playlist_shuffle(pl);
|
||||
|
||||
|
@ -1144,6 +1155,7 @@ static MP_THREAD_VOID open_demux_thread(void *ctx)
|
|||
.stream_flags = mpctx->open_url_flags,
|
||||
.stream_record = true,
|
||||
.is_top_level = true,
|
||||
.has_playlist = mpctx->playlist->num_entries > 1,
|
||||
};
|
||||
struct demuxer *demux =
|
||||
demux_open_url(mpctx->open_url, &p, mpctx->open_cancel, mpctx->global);
|
||||
|
|
Loading…
Reference in New Issue