History

demux_playlist: add --directory-filter-types

Kacper Michajłow committed 2 years ago

Commit 4f1e9e31 parent c54ad697 files · +83 −49Browse files

Unified · Split

7 files
  1. DOCS/interface-changes/autocreate-playlist.txt +3 −3
  2. DOCS/interface-changes/directory-filter-types.txt +1 −0
  3. DOCS/man/options.rst +21 −15
  4. common/playlist.h +1 −1
  5. demux/demux.c +1 −1
  6. demux/demux_playlist.c +46 −25
  7. player/loadfile.c +10 −4
DOCS/interface-changes/autocreate-playlist.txt+3−3
@@ -1,4 +1,4 @@
11 add `--autocreate-playlist`
2−add `--autocreate-playlist-video-exts`
3−add `--autocreate-playlist-audio-exts`
4−add `--autocreate-playlist-image-exts`
2+add `--directory-video-exts`
3+add `--directory-audio-exts`
4+add `--directory-image-exts`
DOCS/interface-changes/directory-filter-types.txt+1−0
@@ -0,0 +1 @@
1+add `--directory-filter-types`
DOCS/man/options.rst+21−15
@@ -4139,30 +4139,36 @@ Demuxer · 4138 unmodified lines
41394139 all. The default is ``auto``, which behaves like ``recursive`` with
41404140 ``--shuffle``, and like ``lazy`` otherwise.
41414141
4142−``--autocreate-playlist=<no|any|exts|same>``
4142+``--directory-filter-types=<video,audio,image>``
4143+ Media file types to filter when opening directory. If the list is empty,
4144+ all files are added to the playlist.
4145+
4146+ This is a string list option. See `List Options`_ for details.
4147+
4148+``--autocreate-playlist=<no|any|filter|same>``
41434149 When opening a local file, act as if the parent directory is opened and
41444150 create a playlist automatically.
41454151
4146− :no: Load a single file (default).
4147− :any: Create a playlist from the parent directory with any file type.
4148− :exts: Create a playlist from the parent directory with files matching
4149− extensions from any list ``autocreate-playlist-*-exts``.
4150− :same: Create a playlist from the parent directory with files matching the
4151− same category as the currently loaded file. One of the
4152− ``autocreate-playlist-*-exts`` is selected based on the input file
4153− and only files with matching extensions are added to the playlist.
4154− If the input file itself is not matched to any extension list,
4155− the playlist is not autogenerated.
4156−
4157−``--autocreate-playlist-video-exts=<ext-list>``
4152+ :no: Load a single file (default).
4153+ :any: Create a playlist from the parent directory with any file type.
4154+ :filter: Create a playlist from the parent directory with files matching
4155+ extensions from any list ``directory-*-exts``.
4156+ :same: Create a playlist from the parent directory with files matching the
4157+ same category as the currently loaded file. One of the
4158+ ``directory-*-exts`` is selected based on the input file
4159+ and only files with matching extensions are added to the playlist.
4160+ If the input file itself is not matched to any extension list,
4161+ the playlist is not autogenerated.
4162+
4163+``--directory-video-exts=<ext1,ext2,...>``
41584164 Video file extension list that is used to match files when using
41594165 ``--autocreate-playlist=<exts|same>``.
41604166
4161−``--autocreate-playlist-audio-exts=<ext-list>``
4167+``--directory-audio-exts=<ext1,ext2,...>``
41624168 Audio file extension list that is used to match files when using
41634169 ``--autocreate-playlist=<exts|same>``.
41644170
4165−``--autocreate-playlist-image-exts=<ext-list>``
4171+``--directory-image-exts=<ext1,ext2,...>``
41664172 Image file extension list that is used to match files when using
41674173 ``--autocreate-playlist=<exts|same>``.
41684174
common/playlist.h+1−1
@@ -72,7 +72,7 @@ struct playlist { · 71 unmodified lines
7272 bool current_was_replaced;
7373 bool playlist_completed;
7474 bool playlist_started;
75− bool autocreated;
75+ char *playlist_dir;
7676
7777 uint64_t id_alloc;
7878 };
demux/demux.c+1−1
@@ -120,7 +120,7 @@ const struct m_sub_options demux_conf = { · 119 unmodified lines
120120 M_RANGE(0, DBL_MAX)},
121121 {"metadata-codepage", OPT_STRING(meta_cp)},
122122 {"autocreate-playlist", OPT_CHOICE(autocreate_playlist,
123− {"no", 0}, {"any", 1}, {"exts", 2}, {"same", 3})},
123+ {"no", 0}, {"any", 1}, {"filter", 2}, {"same", 3})},
124124 {0}
125125 },
126126 .size = sizeof(struct demux_opts),
demux/demux_playlist.c+46−25
@@ -53,9 +53,10 @@ enum autocreate_mode { · 52 unmodified lines
5353 #define OPT_BASE_STRUCT struct demux_playlist_opts
5454 struct demux_playlist_opts {
5555 int dir_mode;
56− char **autocreate_playlist_vid_exts;
57− char **autocreate_playlist_aud_exts;
58− char **autocreate_playlist_img_exts;
56+ char **directory_filter;
57+ char **directory_vid_exts;
58+ char **directory_aud_exts;
59+ char **directory_img_exts;
5960 };
6061
6162 struct m_sub_options demux_playlist_conf = {
@@ -65,26 +66,31 @@ struct m_sub_options demux_playlist_conf = { · 3 unmodified lines
6566 {"lazy", DIR_LAZY},
6667 {"recursive", DIR_RECURSIVE},
6768 {"ignore", DIR_IGNORE})},
68− {"autocreate-playlist-video-exts",
69− OPT_STRINGLIST(autocreate_playlist_vid_exts)},
70− {"autocreate-playlist-audio-exts",
71− OPT_STRINGLIST(autocreate_playlist_aud_exts)},
72− {"autocreate-playlist-image-exts",
73− OPT_STRINGLIST(autocreate_playlist_img_exts)},
69+ {"directory-filter-types",
70+ OPT_STRINGLIST(directory_filter)},
71+ {"directory-video-exts",
72+ OPT_STRINGLIST(directory_vid_exts)},
73+ {"directory-audio-exts",
74+ OPT_STRINGLIST(directory_aud_exts)},
75+ {"directory-image-exts",
76+ OPT_STRINGLIST(directory_img_exts)},
7477 {0}
7578 },
7679 .size = sizeof(struct demux_playlist_opts),
7780 .defaults = &(const struct demux_playlist_opts){
7881 .dir_mode = DIR_AUTO,
79− .autocreate_playlist_vid_exts = (char *[]){
82+ .directory_filter = (char *[]){
83+ NULL
84+ },
85+ .directory_vid_exts = (char *[]){
8086 "3g2", "3gp", "avi", "flv", "m2ts", "m4v", "mj2", "mkv", "mov",
8187 "mp4", "mpeg", "mpg", "ogv", "rmvb", "webm", "wmv", "y4m", NULL
8288 },
83− .autocreate_playlist_aud_exts = (char *[]){
89+ .directory_aud_exts = (char *[]){
8490 "aiff", "ape", "au", "flac", "m4a", "mka", "mp3", "oga", "ogg",
8591 "ogm", "opus", "wav", "wma", NULL
8692 },
87− .autocreate_playlist_img_exts = (char *[]){
93+ .directory_img_exts = (char *[]){
8894 "avif", "bmp", "gif", "j2k", "jp2", "jpeg", "jpg", "jxl", "png",
8995 "svg", "tga", "tif", "tiff", "webp", NULL
9096 },
@@ -424,7 +430,7 @@ static int cmp_dir_entry(const void *a, const void *b) · 333 unmodified lines
424430 }
425431 }
426432
427−static bool has_ext(bstr ext, char **list)
433+static bool has_str(bstr ext, char **list)
428434 {
429435 if (!list)
430436 return false;
@@ -435,17 +441,17 @@ static bool has_ext(bstr ext, char **list) · 4 unmodified lines
435441 return false;
436442 }
437443
438−static bool test_autocreate_path(struct pl_parser *p, char *path, int autocreate)
444+static bool test_path(struct pl_parser *p, char *path, int autocreate)
439445 {
440446 if (autocreate & AUTO_ANY)
441447 return true;
442448
443449 bstr ext = bstr_get_ext(bstr0(path));
444− if (autocreate & AUTO_VIDEO && has_ext(ext, p->opts->autocreate_playlist_vid_exts))
450+ if (autocreate & AUTO_VIDEO && has_str(ext, p->opts->directory_vid_exts))
445451 return true;
446− if (autocreate & AUTO_AUDIO && has_ext(ext, p->opts->autocreate_playlist_aud_exts))
452+ if (autocreate & AUTO_AUDIO && has_str(ext, p->opts->directory_aud_exts))
447453 return true;
448− if (autocreate & AUTO_IMAGE && has_ext(ext, p->opts->autocreate_playlist_img_exts))
454+ if (autocreate & AUTO_IMAGE && has_str(ext, p->opts->directory_img_exts))
449455 return true;
450456
451457 return false;
@@ -505,13 +511,13 @@ static bool scan_dir(struct pl_parser *p, char *path, · 53 unmodified lines
505511 qsort(dir_entries, num_dir_entries, sizeof(dir_entries[0]), cmp_dir_entry);
506512
507513 for (int n = 0; n < num_dir_entries; n++) {
514+ char *file = dir_entries[n].path;
508515 if (dir_mode == DIR_RECURSIVE && dir_entries[n].is_dir) {
509516 dir_stack[num_dir_stack] = dir_entries[n].st;
510− char *file = dir_entries[n].path;
511517 scan_dir(p, file, dir_stack, num_dir_stack + 1, autocreate);
512518 }
513519 else {
514− if (autocreate == AUTO_NONE || test_autocreate_path(p, dir_entries[n].path, autocreate))
520+ if (dir_entries[n].is_dir || test_path(p, file, autocreate))
515521 playlist_append_file(p->pl, dir_entries[n].path);
516522 }
517523 }
@@ -524,21 +530,22 @@ static int parse_dir(struct pl_parser *p) · 6 unmodified lines
524530 int ret = -1;
525531 struct stream *stream = p->real_stream;
526532 int autocreate = AUTO_NONE;
533+ p->pl->playlist_dir = NULL;
527534 if (p->autocreate_playlist && p->real_stream->is_local_file && !p->real_stream->is_directory) {
528535 bstr ext = bstr_get_ext(bstr0(p->real_stream->url));
529536 switch (p->autocreate_playlist) {
530537 case 1: // any
531538 autocreate = AUTO_ANY;
532539 break;
533− case 2: // exts
540+ case 2: // filter
534541 autocreate = AUTO_VIDEO | AUTO_AUDIO | AUTO_IMAGE;
535542 break;
536543 case 3: // same
537− if (has_ext(ext, p->opts->autocreate_playlist_vid_exts)) {
544+ if (has_str(ext, p->opts->directory_vid_exts)) {
538545 autocreate = AUTO_VIDEO;
539− } else if (has_ext(ext, p->opts->autocreate_playlist_aud_exts)) {
546+ } else if (has_str(ext, p->opts->directory_aud_exts)) {
540547 autocreate = AUTO_AUDIO;
541− } else if (has_ext(ext, p->opts->autocreate_playlist_img_exts)) {
548+ } else if (has_str(ext, p->opts->directory_img_exts)) {
542549 autocreate = AUTO_IMAGE;
543550 }
544551 break;
@@ -548,8 +555,20 @@ static int parse_dir(struct pl_parser *p) · 3 unmodified lines
548555 bstr dir = mp_dirname(p->real_stream->url);
549556 if (!dir.len)
550557 autocreate = AUTO_NONE;
551− if (autocreate != AUTO_NONE)
558+ if (autocreate != AUTO_NONE) {
552559 stream = stream_create(bstrdup0(p, dir), flags, NULL, p->global);
560+ p->pl->playlist_dir = bstrdup0(p->pl, dir);
561+ }
562+ } else {
563+ autocreate = AUTO_NONE;
564+ if (!p->opts->directory_filter[0])
565+ autocreate = AUTO_ANY;
566+ if (has_str(bstr0("video"), p->opts->directory_filter))
567+ autocreate |= AUTO_VIDEO;
568+ if (has_str(bstr0("audio"), p->opts->directory_filter))
569+ autocreate |= AUTO_AUDIO;
570+ if (has_str(bstr0("image"), p->opts->directory_filter))
571+ autocreate |= AUTO_IMAGE;
553572 }
554573 if (!stream->is_directory)
555574 goto done;
@@ -562,6 +581,9 @@ static int parse_dir(struct pl_parser *p) · 6 unmodified lines
562581 if (!path)
563582 goto done;
564583
584+ if (autocreate == AUTO_NONE)
585+ goto done;
586+
565587 struct stat dir_stack[MAX_DIR_STACK];
566588
567589 if (p->opts->dir_mode == DIR_AUTO) {
@@ -573,7 +595,6 @@ static int parse_dir(struct pl_parser *p) · 5 unmodified lines
573595 scan_dir(p, path, dir_stack, 0, autocreate);
574596
575597 p->add_base = false;
576− p->pl->autocreated = autocreate != AUTO_NONE;
577598 ret = p->pl->num_entries > 0 ? 0 : -1;
578599
579600 done:
player/loadfile.c+10−4
@@ -1042,10 +1042,16 @@ void prepare_playlist(struct MPContext *mpctx, struct playlist *pl) · 1041 unmodified lines
10421042 if (opts->playlist_pos >= 0)
10431043 pl->current = playlist_entry_from_index(pl, opts->playlist_pos);
10441044
1045− for (int i = 0; i < pl->num_entries && pl->autocreated; ++i) {
1045+ for (int i = 0; i < pl->num_entries && pl->playlist_dir; ++i) {
10461046 if (!pl->entries[i]->playlist_path)
10471047 continue;
1048− if (!strcmp(pl->entries[i]->filename, pl->entries[i]->playlist_path)) {
1048+ char *path = pl->entries[i]->playlist_path;
1049+ if (path[0] != '.')
1050+ path = mp_path_join(NULL, pl->playlist_dir, pl->entries[i]->playlist_path);
1051+ bool same = !strcmp(pl->entries[i]->filename, path);
1052+ if (path != pl->entries[i]->playlist_path)
1053+ talloc_free(path);
1054+ if (same) {
10491055 pl->current = pl->entries[i];
10501056 break;
10511057 }
@@ -1079,7 +1085,7 @@ static void transfer_playlist(struct MPContext *mpctx, struct playlist *pl, · 27 unmodified lines
10791085 playlist_remove(mpctx->playlist, mpctx->playlist->current);
10801086 if (new)
10811087 mpctx->playlist->current = new;
1082− mpctx->playlist->autocreated = pl->autocreated;
1088+ mpctx->playlist->playlist_dir = talloc_steal(mpctx->playlist, pl->playlist_dir);
10831089 } else {
10841090 MP_WARN(mpctx, "Empty playlist!\n");
10851091 }
@@ -1156,7 +1162,7 @@ static MP_THREAD_VOID open_demux_thread(void *ctx) · 70 unmodified lines
11561162 .stream_record = true,
11571163 .is_top_level = true,
11581164 .allow_playlist_create = mpctx->playlist->num_entries <= 1 &&
1159− !mpctx->playlist->autocreated,
1165+ !mpctx->playlist->playlist_dir,
11601166 };
11611167 struct demuxer *demux =
11621168 demux_open_url(mpctx->open_url, &p, mpctx->open_cancel, mpctx->global);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t