diff options
-rw-r--r-- | DOCS/man/options.rst | 12 | ||||
-rw-r--r-- | options/options.c | 6 | ||||
-rw-r--r-- | options/options.h | 2 | ||||
-rw-r--r-- | player/loadfile.c | 21 | ||||
-rw-r--r-- | sub/sd_ass.c | 6 | ||||
-rw-r--r-- | sub/sd_lavc.c | 2 |
6 files changed, 40 insertions, 9 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 5245e18cae..30ea5d7ce1 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -135,6 +135,11 @@ Track Selection Note that if ``--lavfi-complex`` is set before playback is started, the referenced tracks are always selected. +``--subs-with-matching-audio=<yes|no>`` + When autoselecting a subtitle track, select a non-forced one even if the selected + audio stream matches your preferred subtitle language (default: yes). Disable this + if you'd like to only show subtitles for foreign audio or onscreen text. + Playback Control ---------------- @@ -2487,9 +2492,12 @@ Subtitles subtitles (if the difference is smaller than 210 ms, the gap or overlap is removed). -``--sub-forced-only`` +``--sub-forced-only=<auto|yes|no>`` Display only forced subtitles for the DVD subtitle stream selected by e.g. - ``--slang``. + ``--slang`` (default: ``auto``). When set to ``auto``, enabled when the + ``--subs-with-matching-audio`` option is on and a non-forced stream is selected. + Enabling this will hide all subtitles in streams that don't make a distinction + between forced and unforced events within a stream. ``--sub-fps=<rate>`` Specify the framerate of the subtitle file (default: video fps). Affects diff --git a/options/options.c b/options/options.c index 6e22de0a07..35b23abce3 100644 --- a/options/options.c +++ b/options/options.c @@ -228,7 +228,8 @@ const struct m_sub_options mp_subtitle_sub_opts = { {"sub-fps", OPT_FLOAT(sub_fps)}, {"sub-speed", OPT_FLOAT(sub_speed)}, {"sub-visibility", OPT_FLAG(sub_visibility)}, - {"sub-forced-only", OPT_FLAG(forced_subs_only)}, + {"sub-forced-only", OPT_CHOICE(forced_subs_only, + {"auto", -1}, {"no", 0}, {"yes", 1})}, {"stretch-dvd-subs", OPT_FLAG(stretch_dvd_subs)}, {"stretch-image-subs-to-screen", OPT_FLAG(stretch_image_subs)}, {"image-subs-video-resolution", OPT_FLAG(image_subs_video_res)}, @@ -269,6 +270,7 @@ const struct m_sub_options mp_subtitle_sub_opts = { .size = sizeof(OPT_BASE_STRUCT), .defaults = &(OPT_BASE_STRUCT){ .sub_visibility = 1, + .forced_subs_only = -1, .sub_pos = 100, .sub_speed = 1.0, .ass_enabled = 1, @@ -489,6 +491,7 @@ static const m_option_t mp_opts[] = { {"slang", OPT_STRINGLIST(stream_lang[STREAM_SUB])}, {"vlang", OPT_STRINGLIST(stream_lang[STREAM_VIDEO])}, {"track-auto-selection", OPT_FLAG(stream_auto_sel)}, + {"subs-with-matching-audio", OPT_FLAG(subs_with_matching_audio)}, {"lavfi-complex", OPT_STRING(lavfi_complex), .flags = UPDATE_LAVFI_COMPLEX}, @@ -992,6 +995,7 @@ static const struct MPOpts mp_default_opts = { [STREAM_VIDEO] = -2, [STREAM_SUB] = -2, }, }, .stream_auto_sel = 1, + .subs_with_matching_audio = 1, .audio_display = 1, .audio_output_format = 0, // AF_FORMAT_UNKNOWN .playback_speed = 1., diff --git a/options/options.h b/options/options.h index 00b58dfbff..62eef010d7 100644 --- a/options/options.h +++ b/options/options.h @@ -73,6 +73,7 @@ struct mp_subtitle_opts { float sub_fps; float sub_speed; int forced_subs_only; + int forced_subs_only_current; int stretch_dvd_subs; int stretch_image_subs; int image_subs_video_res; @@ -252,6 +253,7 @@ typedef struct MPOpts { int stream_id[2][STREAM_TYPE_COUNT]; char **stream_lang[STREAM_TYPE_COUNT]; int stream_auto_sel; + int subs_with_matching_audio; int audio_display; char **display_tags; diff --git a/player/loadfile.c b/player/loadfile.c index 97ae9328f1..f8d5327acf 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -453,17 +453,19 @@ static int match_lang(char **langs, char *lang) * 1) track is external (no_default cancels this) * 1b) track was passed explicitly (is not an auto-loaded subtitle) * 2) earlier match in lang list - * 3a) track is marked forced - * 3b) track is marked default + * 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 * 4) attached picture, HLS bitrate * 5) lower track number * If select_fallback is not set, 5) is only used to determine whether a * matching track is preferred over another track. Otherwise, always pick a * track (if nothing else matches, return the track with lowest ID). + * Forced tracks are preferred when the user prefers not to display subtitles */ // Return whether t1 is preferred over t2 static bool compare_track(struct track *t1, struct track *t2, char **langs, - struct MPOpts *opts) + int prefer_forced, struct MPOpts *opts) { if (!opts->autoload_files && t1->is_external != t2->is_external) return !t1->is_external; @@ -477,7 +479,7 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs, if (l1 != l2) return l1 > l2; if (t1->forced_track != t2->forced_track) - return t1->forced_track; + return prefer_forced ? t1->forced_track : !t1->forced_track; if (t1->default_track != t2->default_track) return t1->default_track; if (t1->attached_picture != t2->attached_picture) @@ -512,6 +514,10 @@ struct track *select_default_track(struct MPContext *mpctx, int order, struct MPOpts *opts = mpctx->opts; int tid = opts->stream_id[order][type]; char **langs = opts->stream_lang[type]; + int prefer_forced = type != STREAM_SUB || + (!opts->subs_with_matching_audio && + mpctx->current_track[0][STREAM_AUDIO] && + match_lang(langs, mpctx->current_track[0][STREAM_AUDIO]->lang)); if (tid == -2) return NULL; bool select_fallback = type == STREAM_VIDEO || type == STREAM_AUDIO; @@ -528,7 +534,7 @@ 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)) + if (!pick || compare_track(track, pick, langs, prefer_forced, mpctx->opts)) pick = track; } if (pick && !select_fallback && !(pick->is_external && !pick->no_default) @@ -539,6 +545,9 @@ struct track *select_default_track(struct MPContext *mpctx, int order, pick = NULL; if (pick && !opts->autoload_files && pick->is_external) pick = NULL; + if (pick && type == STREAM_SUB && prefer_forced && !pick->forced_track && + opts->subs_rend->forced_subs_only == -1) + opts->subs_rend->forced_subs_only_current = 1; return pick; } @@ -1522,6 +1531,8 @@ static void play_current_file(struct MPContext *mpctx) if (reinit_complex_filters(mpctx, false) < 0) goto terminate_playback; + opts->subs_rend->forced_subs_only_current = (opts->subs_rend->forced_subs_only == 1) ? 1 : 0; + for (int t = 0; t < STREAM_TYPE_COUNT; t++) { for (int i = 0; i < num_ptracks[t]; i++) { struct track *sel = NULL; diff --git a/sub/sd_ass.c b/sub/sd_ass.c index 7c40a01faf..eae1536df8 100644 --- a/sub/sd_ass.c +++ b/sub/sd_ass.c @@ -533,6 +533,12 @@ static struct sub_bitmaps *get_bitmaps(struct sd *sd, struct mp_osd_res dim, if (pts == MP_NOPTS_VALUE || !renderer) goto done; + // Currently no supported text sub formats support a distinction between forced + // and unforced lines, so we just assume everything's unforced and discard everything. + // If we ever see a format that makes this distinction, we can add support here. + if (opts->forced_subs_only_current) + goto done; + double scale = dim.display_par; if (!converted && (!opts->ass_style_override || opts->ass_vsfilter_aspect_compat)) diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c index 81906ceb23..77877fdbd1 100644 --- a/sub/sd_lavc.c +++ b/sub/sd_lavc.c @@ -191,7 +191,7 @@ static void read_sub_bitmaps(struct sd *sd, struct sub *sub) MP_ERR(sd, "unsupported subtitle type from libavcodec\n"); continue; } - if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) && opts->forced_subs_only) + if (!(r->flags & AV_SUBTITLE_FLAG_FORCED) && opts->forced_subs_only_current) continue; if (r->w <= 0 || r->h <= 0) continue; |