summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrcombs <rcombs@rcombs.me>2020-06-22 15:08:42 -0500
committerrcombs <rcombs@rcombs.me>2020-06-22 15:19:00 -0500
commite25b951d45c394df9432150d67693ee681638c68 (patch)
treeef3ee7705f7a1b1cf1f69753d041ab83841b8991
parent514166242763699633147e7aead31fc7ae16372e (diff)
downloadmpv-rcombs/subtitle-selection.tar.bz2
mpv-rcombs/subtitle-selection.tar.xz
player: add --subs-with-matching-audio optionrcombs/subtitle-selection
This allows users to control whether full dialogue subtitles are displayed with an audio track already in their preferred subtitle language. Additionally, this improves handling for the forced flag, automatically selecting between forced and unforced subtitle streams based on the user's settings and the selected audio.
-rw-r--r--DOCS/man/options.rst12
-rw-r--r--options/options.c6
-rw-r--r--options/options.h2
-rw-r--r--player/loadfile.c21
-rw-r--r--sub/sd_ass.c8
-rw-r--r--sub/sd_lavc.c2
6 files changed, 42 insertions, 9 deletions
diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst
index e5e43bfb7f..1ca57cb401 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
----------------
@@ -2475,9 +2480,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 4467c106ba..394c37c1cf 100644
--- a/options/options.c
+++ b/options/options.c
@@ -227,7 +227,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)},
@@ -266,6 +267,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,
@@ -483,6 +485,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},
@@ -985,6 +988,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 45d0747358..d22a7ff7d1 100644
--- a/options/options.h
+++ b/options/options.h
@@ -72,6 +72,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;
@@ -250,6 +251,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 46f16908b0..5d2513f417 100644
--- a/sub/sd_ass.c
+++ b/sub/sd_ass.c
@@ -307,8 +307,16 @@ static bool check_packet_seen(struct sd *sd, int64_t pos)
static void decode(struct sd *sd, struct demux_packet *packet)
{
+ struct mp_subtitle_opts *opts = sd->opts;
struct sd_ass_priv *ctx = sd->priv;
ASS_Track *track = ctx->ass_track;
+
+ // 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)
+ return;
+
if (ctx->converter) {
if (!sd->opts->sub_clear_on_seek && packet->pos >= 0 &&
check_packet_seen(sd, packet->pos))
diff --git a/sub/sd_lavc.c b/sub/sd_lavc.c
index 21dd85f408..3caf0fc2dc 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;