summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/options.rst34
-rw-r--r--options/options.c12
-rw-r--r--options/options.h2
-rw-r--r--player/external_files.c37
-rw-r--r--player/external_files.h2
-rw-r--r--player/loadfile.c16
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);