mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Avoid selecting a forced text track that doesn't match the audio selection
Assuming there is no text language preference. PiperOrigin-RevId: 244176667
This commit is contained in:
parent
fe65f002a5
commit
4ea2463856
3 changed files with 40 additions and 44 deletions
|
|
@ -44,7 +44,7 @@
|
||||||
* MP3: Fix ID3 frame unsychronization
|
* MP3: Fix ID3 frame unsychronization
|
||||||
([#5673](https://github.com/google/ExoPlayer/issues/5673)).
|
([#5673](https://github.com/google/ExoPlayer/issues/5673)).
|
||||||
* MP3: Fix playback of badly clipped files
|
* MP3: Fix playback of badly clipped files
|
||||||
([#5772](https://github.com/google/ExoPlayer/issues/5772)).
|
([#5772](https://github.com/google/ExoPlayer/issues/5772)).
|
||||||
* MPEG-TS: Enable HDMV DTS stream detection only if a flag is set. By default
|
* MPEG-TS: Enable HDMV DTS stream detection only if a flag is set. By default
|
||||||
(i.e. if the flag is not set), the 0x82 elementary stream type is now
|
(i.e. if the flag is not set), the 0x82 elementary stream type is now
|
||||||
treated as an SCTE subtitle track
|
treated as an SCTE subtitle track
|
||||||
|
|
@ -55,6 +55,8 @@
|
||||||
* Update `TrackSelection.Factory` interface to support creating all track
|
* Update `TrackSelection.Factory` interface to support creating all track
|
||||||
selections together.
|
selections together.
|
||||||
* Allow to specify a selection reason for a `SelectionOverride`.
|
* Allow to specify a selection reason for a `SelectionOverride`.
|
||||||
|
* When no text language preference matches, only select forced text tracks
|
||||||
|
whose language matches the selected audio language.
|
||||||
* UI:
|
* UI:
|
||||||
* Update `DefaultTimeBar` based on duration of media and add parameter to set
|
* Update `DefaultTimeBar` based on duration of media and add parameter to set
|
||||||
the minimum update interval to control the smoothness of the updates
|
the minimum update interval to control the smoothness of the updates
|
||||||
|
|
|
||||||
|
|
@ -2070,29 +2070,25 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||||
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
|
boolean isForced = (maskedSelectionFlags & C.SELECTION_FLAG_FORCED) != 0;
|
||||||
int trackScore;
|
int trackScore;
|
||||||
int languageScore = getFormatLanguageScore(format, params.preferredTextLanguage);
|
int languageScore = getFormatLanguageScore(format, params.preferredTextLanguage);
|
||||||
if (languageScore > 0
|
boolean trackHasNoLanguage = formatHasNoLanguage(format);
|
||||||
|| (params.selectUndeterminedTextLanguage && formatHasNoLanguage(format))) {
|
if (languageScore > 0 || (params.selectUndeterminedTextLanguage && trackHasNoLanguage)) {
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
trackScore = 17;
|
trackScore = 11;
|
||||||
} else if (!isForced) {
|
} else if (!isForced) {
|
||||||
// Prefer non-forced to forced if a preferred text language has been specified. Where
|
// Prefer non-forced to forced if a preferred text language has been specified. Where
|
||||||
// both are provided the non-forced track will usually contain the forced subtitles as
|
// both are provided the non-forced track will usually contain the forced subtitles as
|
||||||
// a subset.
|
// a subset.
|
||||||
trackScore = 13;
|
trackScore = 7;
|
||||||
} else {
|
} else {
|
||||||
trackScore = 9;
|
trackScore = 3;
|
||||||
}
|
}
|
||||||
trackScore += languageScore;
|
trackScore += languageScore;
|
||||||
} else if (isDefault) {
|
} else if (isDefault) {
|
||||||
trackScore = 8;
|
trackScore = 2;
|
||||||
} else if (isForced) {
|
} else if (isForced
|
||||||
int preferredAudioLanguageScore =
|
&& (getFormatLanguageScore(format, selectedAudioLanguage) > 0
|
||||||
getFormatLanguageScore(format, params.preferredAudioLanguage);
|
|| (trackHasNoLanguage && stringDefinesNoLanguage(selectedAudioLanguage)))) {
|
||||||
if (preferredAudioLanguageScore > 0) {
|
trackScore = 1;
|
||||||
trackScore = 4 + preferredAudioLanguageScore;
|
|
||||||
} else {
|
|
||||||
trackScore = 1 + getFormatLanguageScore(format, selectedAudioLanguage);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Track should not be selected.
|
// Track should not be selected.
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -2281,15 +2277,19 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||||
&& maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
|
&& maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Equivalent to {@link #stringDefinesNoLanguage stringDefinesNoLanguage(format.language)}. */
|
||||||
* Returns whether a {@link Format} does not define a language.
|
|
||||||
*
|
|
||||||
* @param format The {@link Format}.
|
|
||||||
* @return Whether the {@link Format} does not define a language.
|
|
||||||
*/
|
|
||||||
protected static boolean formatHasNoLanguage(Format format) {
|
protected static boolean formatHasNoLanguage(Format format) {
|
||||||
return TextUtils.isEmpty(format.language)
|
return stringDefinesNoLanguage(format.language);
|
||||||
|| TextUtils.equals(format.language, C.LANGUAGE_UNDETERMINED);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given string does not define a language.
|
||||||
|
*
|
||||||
|
* @param language The string.
|
||||||
|
* @return Whether the given string does not define a language.
|
||||||
|
*/
|
||||||
|
protected static boolean stringDefinesNoLanguage(@Nullable String language) {
|
||||||
|
return TextUtils.isEmpty(language) || TextUtils.equals(language, C.LANGUAGE_UNDETERMINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -910,13 +910,8 @@ public final class DefaultTrackSelectorTest {
|
||||||
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
|
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
|
||||||
assertFixedSelection(result.selections.get(0), trackGroups, defaultOnly);
|
assertFixedSelection(result.selections.get(0), trackGroups, defaultOnly);
|
||||||
|
|
||||||
// With no language preference and no text track flagged as default, the first forced should be
|
// Default flags are disabled and no language preference is provided, so no text track is
|
||||||
// selected.
|
// selected.
|
||||||
trackGroups = wrapFormats(forcedOnly, noFlag);
|
|
||||||
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
|
|
||||||
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnly);
|
|
||||||
|
|
||||||
// Default flags are disabled, so the first track flagged as forced should be selected.
|
|
||||||
trackGroups = wrapFormats(defaultOnly, noFlag, forcedOnly, forcedDefault);
|
trackGroups = wrapFormats(defaultOnly, noFlag, forcedOnly, forcedDefault);
|
||||||
trackSelector.setParameters(
|
trackSelector.setParameters(
|
||||||
Parameters.DEFAULT
|
Parameters.DEFAULT
|
||||||
|
|
@ -924,15 +919,7 @@ public final class DefaultTrackSelectorTest {
|
||||||
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
.setDisabledTextTrackSelectionFlags(C.SELECTION_FLAG_DEFAULT)
|
||||||
.build());
|
.build());
|
||||||
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
|
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
|
||||||
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnly);
|
assertNoSelection(result.selections.get(0));
|
||||||
|
|
||||||
// Default flags are disabled, but there is a text track flagged as forced whose language
|
|
||||||
// matches the preferred audio language.
|
|
||||||
trackGroups = wrapFormats(forcedDefault, forcedOnly, defaultOnly, noFlag, forcedOnlySpanish);
|
|
||||||
trackSelector.setParameters(
|
|
||||||
trackSelector.getParameters().buildUpon().setPreferredTextLanguage("spa").build());
|
|
||||||
result = trackSelector.selectTracks(textRendererCapabilities, trackGroups, periodId, TIMELINE);
|
|
||||||
assertFixedSelection(result.selections.get(0), trackGroups, forcedOnlySpanish);
|
|
||||||
|
|
||||||
// All selection flags are disabled and there is no language preference, so nothing should be
|
// All selection flags are disabled and there is no language preference, so nothing should be
|
||||||
// selected.
|
// selected.
|
||||||
|
|
@ -977,6 +964,11 @@ public final class DefaultTrackSelectorTest {
|
||||||
buildTextFormat(/* id= */ "forcedEnglish", /* language= */ "eng", C.SELECTION_FLAG_FORCED);
|
buildTextFormat(/* id= */ "forcedEnglish", /* language= */ "eng", C.SELECTION_FLAG_FORCED);
|
||||||
Format forcedGerman =
|
Format forcedGerman =
|
||||||
buildTextFormat(/* id= */ "forcedGerman", /* language= */ "deu", C.SELECTION_FLAG_FORCED);
|
buildTextFormat(/* id= */ "forcedGerman", /* language= */ "deu", C.SELECTION_FLAG_FORCED);
|
||||||
|
Format forcedNoLanguage =
|
||||||
|
buildTextFormat(
|
||||||
|
/* id= */ "forcedNoLanguage",
|
||||||
|
/* language= */ C.LANGUAGE_UNDETERMINED,
|
||||||
|
C.SELECTION_FLAG_FORCED);
|
||||||
Format audio = buildAudioFormat(/* id= */ "audio");
|
Format audio = buildAudioFormat(/* id= */ "audio");
|
||||||
Format germanAudio =
|
Format germanAudio =
|
||||||
buildAudioFormat(
|
buildAudioFormat(
|
||||||
|
|
@ -994,16 +986,18 @@ public final class DefaultTrackSelectorTest {
|
||||||
ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES
|
ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES
|
||||||
};
|
};
|
||||||
|
|
||||||
// The audio declares no language. The first forced text track should be selected.
|
// Neither the audio nor the forced text track define a language. We select them both under the
|
||||||
TrackGroupArray trackGroups = wrapFormats(audio, forcedEnglish, forcedGerman);
|
// assumption that they have matching language.
|
||||||
|
TrackGroupArray trackGroups = wrapFormats(audio, forcedNoLanguage);
|
||||||
TrackSelectorResult result =
|
TrackSelectorResult result =
|
||||||
trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
|
trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
|
||||||
assertFixedSelection(result.selections.get(1), trackGroups, forcedEnglish);
|
assertFixedSelection(result.selections.get(1), trackGroups, forcedNoLanguage);
|
||||||
|
|
||||||
// Ditto.
|
// No forced text track should be selected because none of the forced text tracks' languages
|
||||||
trackGroups = wrapFormats(audio, forcedGerman, forcedEnglish);
|
// matches the selected audio language.
|
||||||
|
trackGroups = wrapFormats(audio, forcedEnglish, forcedGerman);
|
||||||
result = trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
|
result = trackSelector.selectTracks(rendererCapabilities, trackGroups, periodId, TIMELINE);
|
||||||
assertFixedSelection(result.selections.get(1), trackGroups, forcedGerman);
|
assertNoSelection(result.selections.get(1));
|
||||||
|
|
||||||
// The audio declares german. The german forced track should be selected.
|
// The audio declares german. The german forced track should be selected.
|
||||||
trackGroups = wrapFormats(germanAudio, forcedGerman, forcedEnglish);
|
trackGroups = wrapFormats(germanAudio, forcedGerman, forcedEnglish);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue