diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java index 4e8da959ba..135de3d67f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelector.java @@ -480,6 +480,12 @@ public class DefaultTrackSelector extends MappingTrackSelector { return this; } + @Override + public ParametersBuilder setPreferredTextRoleFlags(@C.RoleFlags int preferredTextRoleFlags) { + super.setPreferredTextRoleFlags(preferredTextRoleFlags); + return this; + } + @Override public ParametersBuilder setSelectUndeterminedTextLanguage( boolean selectUndeterminedTextLanguage) { @@ -713,6 +719,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { allowAudioMixedChannelCountAdaptiveness, // Text preferredTextLanguage, + preferredTextRoleFlags, selectUndeterminedTextLanguage, disabledTextTrackSelectionFlags, // General @@ -917,6 +924,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { /* allowAudioMixedChannelCountAdaptiveness= */ false, // Text TrackSelectionParameters.DEFAULT.preferredTextLanguage, + TrackSelectionParameters.DEFAULT.preferredTextRoleFlags, TrackSelectionParameters.DEFAULT.selectUndeterminedTextLanguage, TrackSelectionParameters.DEFAULT.disabledTextTrackSelectionFlags, // General @@ -950,6 +958,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { boolean allowAudioMixedChannelCountAdaptiveness, // Text @Nullable String preferredTextLanguage, + @C.RoleFlags int preferredTextRoleFlags, boolean selectUndeterminedTextLanguage, @C.SelectionFlags int disabledTextTrackSelectionFlags, // General @@ -963,6 +972,7 @@ public class DefaultTrackSelector extends MappingTrackSelector { super( preferredAudioLanguage, preferredTextLanguage, + preferredTextRoleFlags, selectUndeterminedTextLanguage, disabledTextTrackSelectionFlags); // Video @@ -1407,7 +1417,8 @@ public class DefaultTrackSelector extends MappingTrackSelector { /** * @deprecated Use {@link #DefaultTrackSelector(Context)} instead. The bandwidth meter should be - * passed directly to the player in {@link SimpleExoPlayer.Builder}. + * passed directly to the player in {@link + * com.google.android.exoplayer2.SimpleExoPlayer.Builder}. */ @Deprecated @SuppressWarnings("deprecation") @@ -2691,7 +2702,9 @@ public class DefaultTrackSelector extends MappingTrackSelector { private final boolean isDefault; private final boolean hasPreferredIsForcedFlag; private final int preferredLanguageScore; + private final int preferredRoleFlagsScore; private final int selectedAudioLanguageScore; + private final boolean hasCaptionRoleFlags; public TextTrackScore( Format format, @@ -2707,6 +2720,10 @@ public class DefaultTrackSelector extends MappingTrackSelector { preferredLanguageScore = getFormatLanguageScore( format, parameters.preferredTextLanguage, parameters.selectUndeterminedTextLanguage); + preferredRoleFlagsScore = + Integer.bitCount(format.roleFlags & parameters.preferredTextRoleFlags); + hasCaptionRoleFlags = + (format.roleFlags & (C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND)) != 0; // Prefer non-forced to forced if a preferred text language has been matched. Where both are // provided the non-forced track will usually contain the forced subtitles as a subset. // Otherwise, prefer a forced track. @@ -2717,7 +2734,10 @@ public class DefaultTrackSelector extends MappingTrackSelector { selectedAudioLanguageScore = getFormatLanguageScore(format, selectedAudioLanguage, selectedAudioLanguageUndetermined); isWithinConstraints = - preferredLanguageScore > 0 || isDefault || (isForced && selectedAudioLanguageScore > 0); + preferredLanguageScore > 0 + || (parameters.preferredTextLanguage == null && preferredRoleFlagsScore > 0) + || isDefault + || (isForced && selectedAudioLanguageScore > 0); } /** @@ -2735,13 +2755,22 @@ public class DefaultTrackSelector extends MappingTrackSelector { if (this.preferredLanguageScore != other.preferredLanguageScore) { return compareInts(this.preferredLanguageScore, other.preferredLanguageScore); } + if (this.preferredRoleFlagsScore != other.preferredRoleFlagsScore) { + return compareInts(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore); + } if (this.isDefault != other.isDefault) { return this.isDefault ? 1 : -1; } if (this.hasPreferredIsForcedFlag != other.hasPreferredIsForcedFlag) { return this.hasPreferredIsForcedFlag ? 1 : -1; } - return compareInts(this.selectedAudioLanguageScore, other.selectedAudioLanguageScore); + if (this.selectedAudioLanguageScore != other.selectedAudioLanguageScore) { + return compareInts(this.selectedAudioLanguageScore, other.selectedAudioLanguageScore); + } + if (preferredRoleFlagsScore == 0 && this.hasCaptionRoleFlags != other.hasCaptionRoleFlags) { + return this.hasCaptionRoleFlags ? -1 : 1; + } + return 0; } } } diff --git a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java index 1582fabc88..e31c4f51b8 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/trackselection/TrackSelectionParameters.java @@ -33,6 +33,7 @@ public class TrackSelectionParameters implements Parcelable { @Nullable /* package */ String preferredAudioLanguage; @Nullable /* package */ String preferredTextLanguage; + @C.RoleFlags /* package */ int preferredTextRoleFlags; /* package */ boolean selectUndeterminedTextLanguage; @C.SelectionFlags /* package */ int disabledTextTrackSelectionFlags; @@ -48,6 +49,7 @@ public class TrackSelectionParameters implements Parcelable { /* package */ Builder(TrackSelectionParameters initialValues) { preferredAudioLanguage = initialValues.preferredAudioLanguage; preferredTextLanguage = initialValues.preferredTextLanguage; + preferredTextRoleFlags = initialValues.preferredTextRoleFlags; selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage; disabledTextTrackSelectionFlags = initialValues.disabledTextTrackSelectionFlags; } @@ -76,6 +78,17 @@ public class TrackSelectionParameters implements Parcelable { return this; } + /** + * Sets the preferred {@link C.RoleFlags} for text tracks. + * + * @param preferredTextRoleFlags Preferred text role flags. + * @return This builder. + */ + public Builder setPreferredTextRoleFlags(@C.RoleFlags int preferredTextRoleFlags) { + this.preferredTextRoleFlags = preferredTextRoleFlags; + return this; + } + /** * Sets whether a text track with undetermined language should be selected if no track with * {@link #setPreferredTextLanguage(String)} is available, or if the preferred language is @@ -110,6 +123,7 @@ public class TrackSelectionParameters implements Parcelable { preferredAudioLanguage, // Text preferredTextLanguage, + preferredTextRoleFlags, selectUndeterminedTextLanguage, disabledTextTrackSelectionFlags); } @@ -129,6 +143,11 @@ public class TrackSelectionParameters implements Parcelable { * the default track if there is one, or no track otherwise. The default value is {@code null}. */ @Nullable public final String preferredTextLanguage; + /** + * The preferred {@link C.RoleFlags} for text tracks. {@code 0} selects the default track if there + * is one, or no track otherwise. The default value is {@code 0}. + */ + @C.RoleFlags public final int preferredTextRoleFlags; /** * Whether a text track with undetermined language should be selected if no track with {@link * #preferredTextLanguage} is available, or if {@link #preferredTextLanguage} is unset. The @@ -146,6 +165,7 @@ public class TrackSelectionParameters implements Parcelable { /* preferredAudioLanguage= */ null, // Text /* preferredTextLanguage= */ null, + /* preferredTextRoleFlags= */ 0, /* selectUndeterminedTextLanguage= */ false, /* disabledTextTrackSelectionFlags= */ 0); } @@ -153,12 +173,14 @@ public class TrackSelectionParameters implements Parcelable { /* package */ TrackSelectionParameters( @Nullable String preferredAudioLanguage, @Nullable String preferredTextLanguage, + @C.RoleFlags int preferredTextRoleFlags, boolean selectUndeterminedTextLanguage, @C.SelectionFlags int disabledTextTrackSelectionFlags) { // Audio this.preferredAudioLanguage = Util.normalizeLanguageCode(preferredAudioLanguage); // Text this.preferredTextLanguage = Util.normalizeLanguageCode(preferredTextLanguage); + this.preferredTextRoleFlags = preferredTextRoleFlags; this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage; this.disabledTextTrackSelectionFlags = disabledTextTrackSelectionFlags; } @@ -166,6 +188,7 @@ public class TrackSelectionParameters implements Parcelable { /* package */ TrackSelectionParameters(Parcel in) { this.preferredAudioLanguage = in.readString(); this.preferredTextLanguage = in.readString(); + this.preferredTextRoleFlags = in.readInt(); this.selectUndeterminedTextLanguage = Util.readBoolean(in); this.disabledTextTrackSelectionFlags = in.readInt(); } @@ -187,6 +210,7 @@ public class TrackSelectionParameters implements Parcelable { TrackSelectionParameters other = (TrackSelectionParameters) obj; return TextUtils.equals(preferredAudioLanguage, other.preferredAudioLanguage) && TextUtils.equals(preferredTextLanguage, other.preferredTextLanguage) + && preferredTextRoleFlags == other.preferredTextRoleFlags && selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage && disabledTextTrackSelectionFlags == other.disabledTextTrackSelectionFlags; } @@ -196,6 +220,7 @@ public class TrackSelectionParameters implements Parcelable { int result = 1; result = 31 * result + (preferredAudioLanguage == null ? 0 : preferredAudioLanguage.hashCode()); result = 31 * result + (preferredTextLanguage == null ? 0 : preferredTextLanguage.hashCode()); + result = 31 * result + preferredTextRoleFlags; result = 31 * result + (selectUndeterminedTextLanguage ? 1 : 0); result = 31 * result + disabledTextTrackSelectionFlags; return result; @@ -212,6 +237,7 @@ public class TrackSelectionParameters implements Parcelable { public void writeToParcel(Parcel dest, int flags) { dest.writeString(preferredAudioLanguage); dest.writeString(preferredTextLanguage); + dest.writeInt(preferredTextRoleFlags); Util.writeBoolean(dest, selectUndeterminedTextLanguage); dest.writeInt(disabledTextTrackSelectionFlags); } diff --git a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java index 7c57c44924..292742b527 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/trackselection/DefaultTrackSelectorTest.java @@ -151,6 +151,7 @@ public final class DefaultTrackSelectorTest { /* allowAudioMixedChannelCountAdaptiveness= */ true, // Text /* preferredTextLanguage= */ "de", + /* preferredTextRoleFlags= */ C.ROLE_FLAG_CAPTION, /* selectUndeterminedTextLanguage= */ true, /* disabledTextTrackSelectionFlags= */ 8, // General