diff options
-rw-r--r-- | DOCS/man/options.rst | 34 | ||||
-rw-r--r-- | options/options.c | 12 | ||||
-rw-r--r-- | options/options.h | 2 | ||||
-rw-r--r-- | player/external_files.c | 37 | ||||
-rw-r--r-- | player/external_files.h | 2 | ||||
-rw-r--r-- | player/loadfile.c | 16 |
6 files changed, 95 insertions, 8 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index e9d5016074..fd19d3d25c 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -6603,7 +6603,39 @@ Miscellaneous ``--external-file=<file>`` CLI/config file only alias for ``--external-files-append``. Each use of this - option will add a new external files. + option will add a new external file. + +``--cover-art-files=<file-list>`` + Use an external file as cover art while playing audio. This makes it appear + on the track list and subject to automatic track selection. Options like + ``--audio-display`` control whether such tracks are supposed to be selected. + + (The difference to loading a file with ``--external-files`` is that video + tracks will be marked as being pictures, which affects the auto-selection + method. If the passed file is a video, only the first frame will be decoded + and displayed. Enabling the cover art track during playback may show a + random frame if the source file is a video. Normally you're not supposed to + pass videos to this option, so this paragraph describes the behavior + coincidentally resulting from implementation details.) + + This is a path list option. See `List Options`_ for details. + +``--cover-art-file=<file>`` + CLI/config file only alias for ``--cover-art-files-append``. Each use of this + option will add a new external file. + +``--cover-art-auto=<no|fuzzy>`` + Whether to load _external_ cover art automatically (default: fuzzy). Similar + to ``--sub-auto`` and ``--audio-file-auto``. However, it's currently limited + to picking up a whitelist of "album art" filenames (such as ``cover.jpg``), + so currently only the ``fuzzy`` choice is available. In addition, if a video + already has tracks (which are not marked as cover art), external cover art + will not be loaded. + + See ``--cover-art-files`` for details about what constitutes cover art. + + See ``--audio-display`` how to control display of cover art (this can be + used to disable cover art that is part of the file). ``--autoload-files=<yes|no>`` Automatically load/select external files (default: yes). diff --git a/options/options.c b/options/options.c index 6da8e7fbef..51df987c6e 100644 --- a/options/options.c +++ b/options/options.c @@ -512,8 +512,6 @@ static const m_option_t mp_opts[] = { #endif // demuxer.c - select audio/sub file/demuxer - {"audio-files", OPT_PATHLIST(audio_files), .flags = M_OPT_FILE}, - {"audio-file", OPT_CLI_ALIAS("audio-files-append")}, {"demuxer", OPT_STRING(demuxer_name)}, {"audio-demuxer", OPT_STRING(audio_demuxer_name)}, {"sub-demuxer", OPT_STRING(sub_demuxer_name)}, @@ -573,15 +571,24 @@ static const m_option_t mp_opts[] = { {"sub-files", OPT_PATHLIST(sub_name), .flags = M_OPT_FILE}, {"sub-file", OPT_CLI_ALIAS("sub-files-append")}, + {"audio-files", OPT_PATHLIST(audio_files), .flags = M_OPT_FILE}, + {"audio-file", OPT_CLI_ALIAS("audio-files-append")}, + {"cover-art-files", OPT_PATHLIST(coverart_files), .flags = M_OPT_FILE}, + {"cover-art-file", OPT_CLI_ALIAS("covert-art-files-append")}, + {"sub-file-paths", OPT_PATHLIST(sub_paths), .flags = M_OPT_FILE}, {"audio-file-paths", OPT_PATHLIST(audiofile_paths), .flags = M_OPT_FILE}, + {"external-files", OPT_PATHLIST(external_files), .flags = M_OPT_FILE}, {"external-file", OPT_CLI_ALIAS("external-files-append")}, {"autoload-files", OPT_FLAG(autoload_files)}, + {"sub-auto", OPT_CHOICE(sub_auto, {"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})}, {"audio-file-auto", OPT_CHOICE(audiofile_auto, {"no", -1}, {"exact", 0}, {"fuzzy", 1}, {"all", 2})}, + {"cover-art-auto", OPT_CHOICE(coverart_auto, + {"no", -1}, {"fuzzy", 1})}, {"", OPT_SUBSTRUCT(subs_rend, mp_subtitle_sub_opts)}, {"", OPT_SUBSTRUCT(subs_filt, mp_sub_filter_opts)}, @@ -1002,6 +1009,7 @@ static const struct MPOpts mp_default_opts = { .pitch_correction = 1, .sub_auto = 0, .audiofile_auto = -1, + .coverart_auto = 1, .osd_bar_visible = 1, .screenshot_template = "mpv-shot%n", .play_dir = 1, diff --git a/options/options.h b/options/options.h index 68f8bed052..606bc6c8a2 100644 --- a/options/options.h +++ b/options/options.h @@ -291,10 +291,12 @@ typedef struct MPOpts { char **sub_name; char **sub_paths; char **audiofile_paths; + char **coverart_files; char **external_files; int autoload_files; int sub_auto; int audiofile_auto; + int coverart_auto; int osd_bar_visible; int w32_priority; diff --git a/player/external_files.c b/player/external_files.c index 69610642d2..40fad916ef 100644 --- a/player/external_files.c +++ b/player/external_files.c @@ -42,6 +42,25 @@ static const char *const audio_exts[] = {"mp3", "aac", "mka", "dts", "flac", "wv", NULL}; +// Stolen from: vlc/-/blob/master/modules/meta_engine/folder.c#L40 +static const char *const cover_files[] = { + "Folder.jpg", + "Folder.png", + "AlbumArtSmall.jpg", + "AlbumArt.jpg", + "Album.jpg", + ".folder.png", + "cover.jpg", + "cover.png", + "cover.gif", + "front.jpg", + "front.png", + "front.gif", + "front.bmp", + "thumb.jpg", + NULL +}; + static bool test_ext_list(bstr ext, const char *const *list) { for (int n = 0; list[n]; n++) { @@ -60,6 +79,15 @@ static int test_ext(bstr ext) return -1; } +static int test_filename(bstr fname) +{ + for (int n = 0; cover_files[n]; n++) { + if (bstrcasecmp(bstr0(cover_files[n]), fname) == 0) + return STREAM_VIDEO; + } + return -1; +} + bool mp_might_be_subtitle_file(const char *filename) { return test_ext(bstr_get_ext(bstr0(filename))) == STREAM_SUB; @@ -159,6 +187,8 @@ static void append_dir_subtitles(struct mpv_global *global, struct MPOpts *opts, // check what it is (most likely) int type = test_ext(tmp_fname_ext); + if (type < 0) + type = test_filename(dename); char **langs = NULL; int fuzz = -1; switch (type) { @@ -170,6 +200,9 @@ static void append_dir_subtitles(struct mpv_global *global, struct MPOpts *opts, langs = opts->stream_lang[type]; fuzz = opts->audiofile_auto; break; + case STREAM_VIDEO: + fuzz = opts->coverart_auto; + break; } if (fuzz < 0 || (limit_type >= 0 && limit_type != type)) @@ -210,6 +243,10 @@ static void append_dir_subtitles(struct mpv_global *global, struct MPOpts *opts, if (!limit_fuzziness && fuzz >= 2) prio |= 1; + // cover art: just accept it + if (type == STREAM_VIDEO && fuzz >= 1) + prio |= 1; + mp_dbg(log, "Potential external file: \"%s\" Priority: %d\n", de->d_name, prio); diff --git a/player/external_files.h b/player/external_files.h index d2de60ee5e..e64f249c6d 100644 --- a/player/external_files.h +++ b/player/external_files.h @@ -21,7 +21,7 @@ #include <stdbool.h> struct subfn { - int type; // STREAM_SUB/STREAM_AUDIO + int type; // STREAM_SUB/STREAM_AUDIO/STREAM_VIDEO(coverart) int priority; char *fname; char *lang; diff --git a/player/loadfile.c b/player/loadfile.c index b5ae9c0212..cb6c1060d7 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -827,6 +827,8 @@ int mp_add_external_file(struct MPContext *mpctx, char *filename, t->external_filename = talloc_strdup(t, filename); t->no_default = sh->type != filter; t->no_auto_select = t->no_default; + // filter==STREAM_VIDEO always means cover art. + t->attached_picture = t->type == STREAM_VIDEO && filter == STREAM_VIDEO; if (first_num < 0 && (filter == STREAM_TYPE_COUNT || sh->type == filter)) first_num = mpctx->num_tracks - 1; } @@ -859,14 +861,15 @@ static void open_external_files(struct MPContext *mpctx, char **files, // See mp_add_external_file() for meaning of cancel parameter. void autoload_external_files(struct MPContext *mpctx, struct mp_cancel *cancel) { - if (mpctx->opts->sub_auto < 0 && mpctx->opts->audiofile_auto < 0) + struct MPOpts *opts = mpctx->opts; + + if (opts->sub_auto < 0 && opts->audiofile_auto < 0 && opts->coverart_auto < 0) return; - if (!mpctx->opts->autoload_files || strcmp(mpctx->filename, "-") == 0) + if (!opts->autoload_files || strcmp(mpctx->filename, "-") == 0) return; void *tmp = talloc_new(NULL); - struct subfn *list = find_external_files(mpctx->global, mpctx->filename, - mpctx->opts); + struct subfn *list = find_external_files(mpctx->global, mpctx->filename, opts); talloc_steal(tmp, list); int sc[STREAM_TYPE_COUNT] = {0}; @@ -887,6 +890,8 @@ void autoload_external_files(struct MPContext *mpctx, struct mp_cancel *cancel) goto skip; if (list[i].type == STREAM_AUDIO && !sc[STREAM_VIDEO]) goto skip; + if (list[i].type == STREAM_VIDEO && (sc[STREAM_VIDEO] || !sc[STREAM_AUDIO])) + goto skip; int first = mp_add_external_file(mpctx, filename, list[i].type, cancel); if (first < 0) goto skip; @@ -894,6 +899,8 @@ void autoload_external_files(struct MPContext *mpctx, struct mp_cancel *cancel) for (int n = first; n < mpctx->num_tracks; n++) { struct track *t = mpctx->tracks[n]; t->auto_loaded = true; + t->attached_picture = + t->type == STREAM_VIDEO && list[i].type == STREAM_VIDEO; if (!t->lang) t->lang = talloc_strdup(t, lang); } @@ -1364,6 +1371,7 @@ static void load_external_opts_thread(void *p) load_chapters(mpctx); open_external_files(mpctx, mpctx->opts->audio_files, STREAM_AUDIO); open_external_files(mpctx, mpctx->opts->sub_name, STREAM_SUB); + open_external_files(mpctx, mpctx->opts->coverart_files, STREAM_VIDEO); open_external_files(mpctx, mpctx->opts->external_files, STREAM_TYPE_COUNT); autoload_external_files(mpctx, mpctx->playback_abort); |