diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 514c179c93..1d23830c86 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -36,6 +36,11 @@
* Set `compileSdkVersion` to 29 to use Android Q APIs.
* Add `enable` and `disable` methods to `MediaSource` to improve resource
management in playlists.
+* Text selection logic:
+ * Allow to set preferred role flags using
+ `DefaultTrackSelector.ParametersBuilder.setPreferredTextRoleFlags`.
+ * Default text language and role flags to accessibility captioning settings
+ ([#5749](https://github.com/google/ExoPlayer/issues/5749)).
* Remove `AnalyticsCollector.Factory`. Instances can be created directly and
the `Player` set later using `AnalyticsCollector.setPlayer`.
* Replace `ExoPlayerFactory` by `SimpleExoPlayer.Builder` and
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 dbbf5deca0..ad606d78dd 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
@@ -474,6 +474,13 @@ public class DefaultTrackSelector extends MappingTrackSelector {
// Text
+ @Override
+ public ParametersBuilder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(
+ Context context) {
+ super.setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(context);
+ return this;
+ }
+
@Override
public ParametersBuilder setPreferredTextLanguage(@Nullable String preferredTextLanguage) {
super.setPreferredTextLanguage(preferredTextLanguage);
@@ -499,6 +506,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
super.setDisabledTextTrackSelectionFlags(disabledTextTrackSelectionFlags);
return this;
}
+
// General
/**
@@ -757,6 +765,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
*
* - {@link ParametersBuilder#setViewportSizeToPhysicalDisplaySize(Context, boolean)
* Viewport constraints} configured for the primary display.
+ *
- {@link
+ * ParametersBuilder#setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(Context)
+ * Preferred text language and role flags} configured to the accessibility settings of
+ * {@link android.view.accessibility.CaptioningManager}.
*
*/
public static final Parameters DEFAULT_WITHOUT_CONTEXT = new Parameters();
@@ -778,6 +790,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
return DEFAULT_WITHOUT_CONTEXT
.buildUpon()
.setViewportSizeToPhysicalDisplaySize(context, /* viewportOrientationMayChange= */ true)
+ .setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(context)
.build();
}
@@ -932,7 +945,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/* viewportHeight= */ Integer.MAX_VALUE,
/* viewportOrientationMayChange= */ true,
// Audio
- TrackSelectionParameters.DEFAULT.preferredAudioLanguage,
+ TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT.preferredAudioLanguage,
/* maxAudioChannelCount= */ Integer.MAX_VALUE,
/* maxAudioBitrate= */ Integer.MAX_VALUE,
/* exceedAudioConstraintsIfNecessary= */ true,
@@ -940,10 +953,10 @@ public class DefaultTrackSelector extends MappingTrackSelector {
/* allowAudioMixedSampleRateAdaptiveness= */ false,
/* allowAudioMixedChannelCountAdaptiveness= */ false,
// Text
- TrackSelectionParameters.DEFAULT.preferredTextLanguage,
- TrackSelectionParameters.DEFAULT.preferredTextRoleFlags,
- TrackSelectionParameters.DEFAULT.selectUndeterminedTextLanguage,
- TrackSelectionParameters.DEFAULT.disabledTextTrackSelectionFlags,
+ TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT.preferredTextLanguage,
+ TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT.preferredTextRoleFlags,
+ TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT.selectUndeterminedTextLanguage,
+ TrackSelectionParameters.DEFAULT_WITHOUT_CONTEXT.disabledTextTrackSelectionFlags,
// General
/* forceLowestBitrate= */ false,
/* forceHighestSupportedBitrate= */ false,
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 e31c4f51b8..dca9aef209 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
@@ -15,12 +15,16 @@
*/
package com.google.android.exoplayer2.trackselection;
+import android.annotation.TargetApi;
+import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import android.view.accessibility.CaptioningManager;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.util.Util;
+import java.util.Locale;
/** Constraint parameters for track selection. */
public class TrackSelectionParameters implements Parcelable {
@@ -37,9 +41,22 @@ public class TrackSelectionParameters implements Parcelable {
/* package */ boolean selectUndeterminedTextLanguage;
@C.SelectionFlags /* package */ int disabledTextTrackSelectionFlags;
- /** Creates a builder with default initial values. */
+ /**
+ * Creates a builder with default initial values.
+ *
+ * @param context Any context.
+ */
+ public Builder(Context context) {
+ this(TrackSelectionParameters.getDefaults(context));
+ }
+
+ /**
+ * @deprecated {@link Context} constraints will not be set when using this constructor. Use
+ * {@link #Builder(Context)} instead.
+ */
+ @Deprecated
public Builder() {
- this(DEFAULT);
+ this(DEFAULT_WITHOUT_CONTEXT);
}
/**
@@ -66,6 +83,23 @@ public class TrackSelectionParameters implements Parcelable {
return this;
}
+ /**
+ * Sets the preferred language and role flags for text tracks based on the accessibility
+ * settings of {@link CaptioningManager}.
+ *
+ * Does nothing for API levels < 19 or when the {@link CaptioningManager} is disabled.
+ *
+ * @param context A {@link Context}.
+ * @return This builder.
+ */
+ public Builder setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(
+ Context context) {
+ if (Util.SDK_INT >= 19) {
+ setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(context);
+ }
+ return this;
+ }
+
/**
* Sets the preferred language for text tracks.
*
@@ -127,10 +161,52 @@ public class TrackSelectionParameters implements Parcelable {
selectUndeterminedTextLanguage,
disabledTextTrackSelectionFlags);
}
+
+ @TargetApi(19)
+ private void setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettingsV19(
+ Context context) {
+ CaptioningManager captioningManager =
+ (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+ if (captioningManager == null || !captioningManager.isEnabled()) {
+ return;
+ }
+ preferredTextRoleFlags = C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND;
+ Locale preferredLocale = captioningManager.getLocale();
+ if (preferredLocale != null) {
+ preferredTextLanguage = Util.getLocaleLanguageTag(preferredLocale);
+ }
+ }
}
- /** An instance with default values. */
- public static final TrackSelectionParameters DEFAULT = new TrackSelectionParameters();
+ /**
+ * An instance with default values, except those obtained from the {@link Context}.
+ *
+ *
If possible, use {@link #getDefaults(Context)} instead.
+ *
+ *
This instance will not have the following settings:
+ *
+ *
+ * - {@link Builder#setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(Context)
+ * Preferred text language and role flags} configured to the accessibility settings of
+ * {@link CaptioningManager}.
+ *
+ */
+ public static final TrackSelectionParameters DEFAULT_WITHOUT_CONTEXT =
+ new TrackSelectionParameters();
+
+ /**
+ * @deprecated This instance is not configured using {@link Context} constraints. Use {@link
+ * #getDefaults(Context)} instead.
+ */
+ @Deprecated public static final TrackSelectionParameters DEFAULT = new TrackSelectionParameters();
+
+ /** Returns an instance configured with default values. */
+ public static TrackSelectionParameters getDefaults(Context context) {
+ return DEFAULT_WITHOUT_CONTEXT
+ .buildUpon()
+ .setPreferredTextLanguageAndRoleFlagsToCaptioningManagerSettings(context)
+ .build();
+ }
/**
* The preferred language for audio and forced text tracks as an IETF BCP 47 conformant tag.
@@ -140,12 +216,15 @@ public class TrackSelectionParameters implements Parcelable {
@Nullable public final String preferredAudioLanguage;
/**
* The preferred language for text tracks as an IETF BCP 47 conformant tag. {@code null} selects
- * the default track if there is one, or no track otherwise. The default value is {@code null}.
+ * the default track if there is one, or no track otherwise. The default value is {@code null}, or
+ * the language of the accessibility {@link CaptioningManager} if enabled.
*/
@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}.
+ * is one, or no track otherwise. The default value is {@code 0}, or {@link C#ROLE_FLAG_SUBTITLE}
+ * | {@link C#ROLE_FLAG_DESCRIBES_MUSIC_AND_SOUND} if the accessibility {@link CaptioningManager}
+ * is enabled.
*/
@C.RoleFlags public final int preferredTextRoleFlags;
/**
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java
index e7a1f2e92e..cbd246cf22 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/util/Util.java
@@ -459,6 +459,20 @@ public final class Util {
parcel.writeInt(value ? 1 : 0);
}
+ /**
+ * Returns the language tag for a {@link Locale}.
+ *
+ * For API levels ≥ 21, this tag is IETF BCP 47 compliant. Use {@link
+ * #normalizeLanguageCode(String)} to retrieve a normalized IETF BCP 47 language tag for all API
+ * levels if needed.
+ *
+ * @param locale A {@link Locale}.
+ * @return The language tag.
+ */
+ public static String getLocaleLanguageTag(Locale locale) {
+ return SDK_INT >= 21 ? getLocaleLanguageTagV21(locale) : locale.toString();
+ }
+
/**
* Returns a normalized IETF BCP 47 language tag for {@code language}.
*
@@ -1963,7 +1977,7 @@ public final class Util {
Configuration config = Resources.getSystem().getConfiguration();
return SDK_INT >= 24
? getSystemLocalesV24(config)
- : SDK_INT >= 21 ? getSystemLocaleV21(config) : new String[] {config.locale.toString()};
+ : new String[] {getLocaleLanguageTag(config.locale)};
}
@TargetApi(24)
@@ -1972,8 +1986,8 @@ public final class Util {
}
@TargetApi(21)
- private static String[] getSystemLocaleV21(Configuration config) {
- return new String[] {config.locale.toLanguageTag()};
+ private static String getLocaleLanguageTagV21(Locale locale) {
+ return locale.toLanguageTag();
}
@TargetApi(21)