summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/interface-changes.rst1
-rw-r--r--DOCS/man/options.rst6
-rw-r--r--options/options.c2
-rw-r--r--options/options.h1
-rw-r--r--player/loadfile.c32
5 files changed, 31 insertions, 11 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst
index 8d34fcf99e..0384796699 100644
--- a/DOCS/interface-changes.rst
+++ b/DOCS/interface-changes.rst
@@ -45,6 +45,7 @@ Interface changes
- add `--audio-file-exts`, `--cover-art-auto-exts`, and `--sub-auto-exts`
- change `slang` default back to NULL
- remove special handling of the `auto` value from `--alang/slang/vlang` options
+ - add `--subs-match-os-language` as a replacement for `--slang=auto`
--- mpv 0.36.0 ---
- add `--target-contrast`
- Target luminance value is now also applied when ICC profile is used.
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index 94d7bce6e8..b4e9a2b8d3 100644
--- a/DOCS/man/options.rst
+++ b/DOCS/man/options.rst
@@ -139,6 +139,12 @@ Track Selection
When autoselecting a subtitle track, select a full/non-forced one even if the selected
audio stream matches your preferred subtitle language (default: yes).
+``--subs-match-os-language=<yes|no>``
+ When autoselecting a subtitle track, select the track that matches the language of your OS
+ if the audio stream is in a different language if suitable (default track or a forced track
+ under the right conditions). Note that if ``-slang`` is set, this will be completely ignored
+ (default: yes).
+
``--subs-fallback=<yes|default|no>``
When autoselecting a subtitle track, if no tracks match your preferred languages,
select a full track even if it doesn't match your preferred subtitle language (default: default).
diff --git a/options/options.c b/options/options.c
index 13fefd5f0d..14fb4039c0 100644
--- a/options/options.c
+++ b/options/options.c
@@ -522,6 +522,7 @@ static const m_option_t mp_opts[] = {
{"vlang", OPT_STRINGLIST(stream_lang[STREAM_VIDEO])},
{"track-auto-selection", OPT_BOOL(stream_auto_sel)},
{"subs-with-matching-audio", OPT_BOOL(subs_with_matching_audio)},
+ {"subs-match-os-language", OPT_BOOL(subs_match_os_language)},
{"subs-fallback", OPT_CHOICE(subs_fallback, {"no", 0}, {"default", 1}, {"yes", 2})},
{"subs-fallback-forced", OPT_BOOL(subs_fallback_forced)},
@@ -1044,6 +1045,7 @@ static const struct MPOpts mp_default_opts = {
[STREAM_SUB] = -2, }, },
.stream_auto_sel = true,
.subs_with_matching_audio = true,
+ .subs_match_os_language = true,
.subs_fallback = 1,
.subs_fallback_forced = true,
.audio_display = 1,
diff --git a/options/options.h b/options/options.h
index 6f8c8a5998..52547183a2 100644
--- a/options/options.h
+++ b/options/options.h
@@ -268,6 +268,7 @@ typedef struct MPOpts {
char **stream_lang[STREAM_TYPE_COUNT];
bool stream_auto_sel;
bool subs_with_matching_audio;
+ bool subs_match_os_language;
int subs_fallback;
bool subs_fallback_forced;
int audio_display;
diff --git a/player/loadfile.c b/player/loadfile.c
index 3b0dcb1a39..2a83f57241 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -472,10 +472,11 @@ static int match_lang(char **langs, const char *lang)
* 1) track is external (no_default cancels this)
* 1b) track was passed explicitly (is not an auto-loaded subtitle)
* 1c) track matches the program ID of the video
- * 2) earlier match in lang list
+ * 2) earlier match in lang list but not if we're using os_langs
* 3a) track is marked forced and we're preferring forced tracks
* 3b) track is marked non-forced and we're preferring non-forced tracks
* 3c) track is marked default
+ * 3d) match in lang list with os_langs
* 4) attached picture, HLS bitrate
* 5) lower track number
* If select_fallback is not set, 5) is only used to determine whether a
@@ -485,7 +486,7 @@ static int match_lang(char **langs, const char *lang)
*/
// Return whether t1 is preferred over t2
static bool compare_track(struct track *t1, struct track *t2, char **langs,
- struct MPOpts *opts, int preferred_program)
+ bool os_langs, struct MPOpts *opts, int preferred_program)
{
if (!opts->autoload_files && t1->is_external != t2->is_external)
return !t1->is_external;
@@ -505,10 +506,12 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs,
return t1->program_id == preferred_program;
}
int l1 = match_lang(langs, t1->lang), l2 = match_lang(langs, t2->lang);
- if (l1 != l2)
+ if (!os_langs && l1 != l2)
return l1 > l2;
if (t1->default_track != t2->default_track)
return t1->default_track;
+ if (os_langs && l1 != l2)
+ return l1 > l2;
if (t1->attached_picture != t2->attached_picture)
return !t1->attached_picture;
if (t1->stream && t2->stream && opts->hls_bitrate >= 0 &&
@@ -546,19 +549,19 @@ static bool append_lang(size_t *nb, char ***out, char *in)
return true;
}
-static bool add_auto_langs(size_t *nb, char ***out)
+static char **add_os_langs(void)
{
- bool ret = false;
+ size_t nb = 0;
+ char **out = NULL;
char **autos = mp_get_user_langs();
for (int i = 0; autos && autos[i]; i++) {
- if (!append_lang(nb, out, autos[i]))
+ if (!append_lang(&nb, &out, autos[i]))
goto cleanup;
}
- ret = true;
cleanup:
talloc_free(autos);
- return ret;
+ return out;
}
static char **process_langs(char **in)
@@ -611,6 +614,13 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
if (tid == -2)
return NULL;
char **langs = process_langs(opts->stream_lang[type]);
+ bool os_langs = false;
+ // Try to add OS languages if enabled by the user and we don't already have a lang from slang.
+ if (type == STREAM_SUB && (!langs || !strcmp(langs[0], "")) && opts->subs_match_os_language) {
+ talloc_free(langs);
+ langs = add_os_langs();
+ os_langs = true;
+ }
const char *audio_lang = get_audio_lang(mpctx);
bool sub = type == STREAM_SUB;
bool fallback_forced = sub && opts->subs_fallback_forced;
@@ -633,12 +643,12 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
continue;
if (duplicate_track(mpctx, order, type, track))
continue;
- if (!pick || compare_track(track, pick, langs, mpctx->opts, preferred_program))
+ if (!pick || compare_track(track, pick, langs, os_langs, mpctx->opts, preferred_program))
pick = track;
// We only try to autoselect forced tracks if they match the audio language and are subs
if (fallback_forced && track->forced_track && mp_match_lang_single(audio_lang, track->lang) &&
- (!forced_pick || compare_track(track, forced_pick, langs, mpctx->opts, preferred_program)))
+ (!forced_pick || compare_track(track, forced_pick, langs, os_langs, mpctx->opts, preferred_program)))
forced_pick = track;
}
@@ -652,7 +662,7 @@ struct track *select_default_track(struct MPContext *mpctx, int order,
sub_fallback = (pick->is_external && !pick->no_default) || opts->subs_fallback == 2 ||
(opts->subs_fallback == 1 && pick->default_track);
}
- if (pick && !forced_pick && sub && !match_lang(langs, pick->lang) &&
+ if (pick && !forced_pick && sub && (!match_lang(langs, pick->lang) || os_langs) &&
((!opts->subs_with_matching_audio && audio_matches) || !sub_fallback))
pick = NULL;