diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index a738685095..87a18722ea 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -57,6 +57,7 @@ Interface changes - add `video-params/crop-[w,h,x,y]` - remove `--tone-mapping-mode` - add `auto` to `--sub-fix-timing` and make it the default + - change `--subs-fallback-forced` so that it works alongside `--slang` --- 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 a545947fe9..e8790a4672 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -153,10 +153,11 @@ Track Selection Setting this to `default` means that only streams flagged as `default` will be selected. ``--subs-fallback-forced=`` - When autoselecting a subtitle track, if no tracks match your preferred languages, - select a forced track that matches the language of the selected audio track (default: yes). - `always` will always select a forced track if possible, regardles if the language matches the - selected audio track or not. + When autoselecting a subtitle track, the default value of `yes` will prefer using a forced + subtitle track if the subtitle language matches the audio language and matches your list of + preferred languages. The special value `always` will only select forced subtitle tracks and + never fallback on a non-forced track. Conversely, `no` will never select a forced subtitle + track. Playback Control diff --git a/player/loadfile.c b/player/loadfile.c index 630ddfbf84..6c39f8e03a 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -505,13 +505,16 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs, (t2->program_id == preferred_program)) return t1->program_id == preferred_program; } + int forced = t1->type == STREAM_SUB ? opts->subs_fallback_forced : 1; + bool force_match = forced == 1 || (t1->forced_track && forced == 2) || + (!t1->forced_track && !forced); int l1 = match_lang(langs, t1->lang), l2 = match_lang(langs, t2->lang); if (!os_langs && l1 != l2) - return l1 > l2; + return l1 > l2 && force_match; if (t1->default_track != t2->default_track) - return t1->default_track; + return t1->default_track && force_match; if (os_langs && l1 != l2) - return l1 > l2; + return l1 > l2 && force_match; if (t1->attached_picture != t2->attached_picture) return !t1->attached_picture; if (t1->stream && t2->stream && opts->hls_bitrate >= 0 && @@ -648,10 +651,11 @@ struct track *select_default_track(struct MPContext *mpctx, int order, // Autoselecting forced sub tracks requires the following: // 1. Matches the audio language or --subs-fallback-forced=always. // 2. Matches the users list of preferred languages or none were specified (i.e. slang was not set). - // 3. A track *wasn't* already selected by slang previously. - if (fallback_forced && track->forced_track && - (os_langs || (match_lang(langs, track->lang) && !match_lang(langs, pick->lang))) && - (mp_match_lang_single(audio_lang, track->lang) || opts->subs_fallback_forced == 2) && + // 3. A track *wasn't* already selected by slang previously or the track->lang matches pick->lang and isn't forced. + bool valid_forced_slang = (os_langs || (mp_match_lang_single(pick->lang, track->lang) && !pick->forced_track) || + (match_lang(langs, track->lang) && !match_lang(langs, pick->lang))); + bool audio_lang_match = mp_match_lang_single(audio_lang, track->lang); + if (fallback_forced && track->forced_track && valid_forced_slang && audio_lang_match && (!forced_pick || compare_track(track, forced_pick, langs, os_langs, mpctx->opts, preferred_program))) { forced_pick = track; @@ -671,8 +675,14 @@ struct track *select_default_track(struct MPContext *mpctx, int order, if (pick && !forced_pick && sub && (!match_lang(langs, pick->lang) || os_langs) && !sub_fallback) pick = NULL; // Handle this after matching langs and selecting a fallback. - if (pick && !forced_pick && sub && (!opts->subs_with_matching_audio && audio_matches)) + if (pick && sub && (!opts->subs_with_matching_audio && audio_matches)) pick = NULL; + // Handle edge cases if we picked a track that doesn't match the --subs-fallback-force value + if (pick && sub && ((!pick->forced_track && opts->subs_fallback_forced == 2) || + (pick->forced_track && !opts->subs_fallback_forced))) + { + pick = NULL; + } if (pick && pick->attached_picture && !mpctx->opts->audio_display) pick = NULL;