diff options
author | wm4 <wm4@nowhere> | 2020-05-09 23:31:33 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2020-05-09 23:31:33 +0200 |
commit | caf228b21807423c28e2f5bde0dcd7dc981e3773 (patch) | |
tree | 27fcee079adbf5bf0f6674615e6094170bc2fafb | |
parent | 327302bdb97665f7a3f3eb813b1abe64a892e807 (diff) | |
download | mpv-caf228b21807423c28e2f5bde0dcd7dc981e3773.tar.bz2 mpv-caf228b21807423c28e2f5bde0dcd7dc981e3773.tar.xz |
player: make external subtitle auto-loading stricter
By default --sub-auto uses "exact". This was far from an "exact" match,
because it added anything that started with the video filename (without
extension), and seemed to end in something that looked like a language
code.
Make this stricter. "exact" still tolerate a language code, but the
video's filename must come before it without any unknown extra
characters. This may not load subtitles in some situations where it
previously did, and where the user might think that the naming
convention is such that it should be considered an exact match.
The subtitle priority sorting seems a bit worthless. I suppose it may
have some value in higher "fuzz" modes (like --sub-auto=fuzzy).
Also remove the mysterious "prio += prio;" line. I probably shouldn't
have checked, but it goes back to commit f16fa9d31 (2003), where someone
wanted to "refine" the priority without changing the rest of the code or
something.
Mostly untested, so have fun.
Fixes: #7702
-rw-r--r-- | DOCS/man/options.rst | 3 | ||||
-rw-r--r-- | player/external_files.c | 63 |
2 files changed, 41 insertions, 25 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 0a96d18baf..431837e26a 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -2423,7 +2423,8 @@ Subtitles default. :no: Don't automatically load external subtitle files. - :exact: Load the media filename with subtitle file extension (default). + :exact: Load the media filename with subtitle file extension and possibly + language suffixes (default). :fuzzy: Load all subs containing media filename. :all: Load all subs in the current and ``--sub-file-paths`` directories. diff --git a/player/external_files.c b/player/external_files.c index 0af9e5a448..90a1487be1 100644 --- a/player/external_files.c +++ b/player/external_files.c @@ -83,7 +83,7 @@ static int compare_sub_priority(const void *a, const void *b) return strcoll(s1->fname, s2->fname); } -static struct bstr guess_lang_from_filename(struct bstr name) +static struct bstr guess_lang_from_filename(struct bstr name, int *fn_start) { if (name.len < 2) return (struct bstr){NULL, 0}; @@ -91,16 +91,27 @@ static struct bstr guess_lang_from_filename(struct bstr name) int n = 0; int i = name.len - 1; - if (name.start[i] == ')' || name.start[i] == ']') + char thing = '.'; + if (name.start[i] == ')') { + thing = '('; i--; + } + if (name.start[i] == ']') { + thing = '['; + i--; + } + while (i >= 0 && mp_isalpha(name.start[i])) { n++; if (n > 3) return (struct bstr){NULL, 0}; i--; } - if (n < 2) + + if (n < 2 || i == 0 || name.start[i] != thing) return (struct bstr){NULL, 0}; + + *fn_start = i; return (struct bstr){name.start + i + 1, n}; } @@ -165,40 +176,44 @@ static void append_dir_subtitles(struct mpv_global *global, struct MPOpts *opts, goto next_sub; // we have a (likely) subtitle file - // 0 = nothing - // 1 = any subtitle file - // 2 = any sub file containing movie name - // 3 = sub file containing movie name and the lang extension + // higher prio -> auto-selection may prefer it (0 = not loaded) int prio = 0; + if (bstrcmp(tmp_fname_trim, f_fname_trim) == 0) + prio |= 32; // exact movie name match + bstr lang = {0}; - if (bstr_startswith(tmp_fname_trim, f_fname_trim)) - lang = guess_lang_from_filename(tmp_fname_trim); + if (bstr_startswith(tmp_fname_trim, f_fname_trim)) { + int start = 0; + lang = guess_lang_from_filename(tmp_fname_trim, &start); + + if (lang.len && start == f_fname_trim.len) + prio |= 16; // exact movie name + followed by lang + } + for (int n = 0; langs && langs[n]; n++) { if (lang.len && bstr_case_startswith(lang, bstr0(langs[n]))) { - prio = 4; // matches the movie name + lang extension + if (fuzz >= 1) + prio |= 8; // known language -> boost priority break; } } - if (!prio && bstrcmp(tmp_fname_trim, f_fname_trim) == 0) - prio = 3; // matches the movie name - if (!prio && lang.len) - prio = 3; // matches the movie name + a language was matched - if (!prio && bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && fuzz >= 1) - prio = 2; // contains the movie name - if (!prio) { - // doesn't contain the movie name - // don't try in the mplayer subtitle directory - if (!limit_fuzziness && fuzz >= 2) { - prio = 1; - } - } + + if (lang.len && fuzz >= 1) + prio |= 4; // matches the movie name + a language was matched + + if (bstr_find(tmp_fname_trim, f_fname_trim) >= 0 && fuzz >= 1) + prio |= 2; // contains the movie name + + // doesn't contain the movie name + // don't try in the mplayer subtitle directory + if (!limit_fuzziness && fuzz >= 2) + prio |= 1; mp_dbg(log, "Potential external file: \"%s\" Priority: %d\n", de->d_name, prio); if (prio) { - prio += prio; char *subpath = mp_path_join_bstr(*slist, path, dename); if (mp_path_exists(subpath)) { MP_TARRAY_GROW(NULL, *slist, *nsub); |