diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index f772bc9f19d..ae5bc0fb95d 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -8,6 +8,9 @@
use this with `FfmpegAudioRenderer`.
* Support extraction and decoding of Dolby Atmos
([#2465](https://github.com/google/ExoPlayer/issues/2465)).
+* DefaultTrackSelector: Support undefined language text track selection when the
+ preferred language is not available
+ ([#2980](https://github.com/google/ExoPlayer/issues/2980)).
### 2.6.0 ###
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/C.java b/library/core/src/main/java/com/google/android/exoplayer2/C.java
index 592589e2212..6a35c0c5e86 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/C.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/C.java
@@ -424,6 +424,11 @@ private C() {}
*/
public static final int SELECTION_FLAG_AUTOSELECT = 4;
+ /**
+ * Represents an undetermined language as an ISO 639 alpha-3 language code.
+ */
+ public static final String LANGUAGE_UNDETERMINED = "und";
+
/**
* Represents a streaming or other media type.
*/
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 c789caded4a..0029cdbd315 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
@@ -46,7 +46,7 @@
* Parameters currentParameters = trackSelector.getParameters();
* // Generate new parameters to prefer German audio and impose a maximum video size constraint.
* Parameters newParameters = currentParameters
- * .withPreferredAudioLanguage("de")
+ * .withPreferredAudioLanguage("deu")
* .withMaxVideoSize(1024, 768);
* // Set the new parameters on the selector.
* trackSelector.setParameters(newParameters);}
@@ -81,17 +81,22 @@ public static final class Parameters {
// Audio
/**
- * The preferred language for audio, as well as for forced text tracks as defined by RFC 5646.
+ * The preferred language for audio, as well as for forced text tracks, as an ISO 639-2/T tag.
* {@code null} selects the default track, or the first track if there's no default.
*/
public final String preferredAudioLanguage;
// Text
/**
- * The preferred language for text tracks as defined by RFC 5646. {@code null} selects the
+ * The preferred language for text tracks as an ISO 639-2/T tag. {@code null} selects the
* default track if there is one, or no track otherwise.
*/
public final String preferredTextLanguage;
+ /**
+ * Whether a text track with undetermined language should be selected if no track with
+ * {@link #preferredTextLanguage} is available, or if {@link #preferredTextLanguage} is unset.
+ */
+ public final boolean selectUndeterminedTextLanguage;
// Video
/**
@@ -150,6 +155,8 @@ public static final class Parameters {
*
* - No preferred audio language is set.
* - No preferred text language is set.
+ * - Text tracks with undetermined language are not selected if no track with
+ * {@link #preferredTextLanguage} is available.
* - Lowest bitrate track selections are not forced.
* - Adaptation between different mime types is not allowed.
* - Non seamless adaptation is allowed.
@@ -161,13 +168,14 @@ public static final class Parameters {
*
*/
public Parameters() {
- this(null, null, false, false, true, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
- true, true, Integer.MAX_VALUE, Integer.MAX_VALUE, true);
+ this(null, null, false, false, false, true, Integer.MAX_VALUE, Integer.MAX_VALUE,
+ Integer.MAX_VALUE, true, true, Integer.MAX_VALUE, Integer.MAX_VALUE, true);
}
/**
* @param preferredAudioLanguage See {@link #preferredAudioLanguage}
* @param preferredTextLanguage See {@link #preferredTextLanguage}
+ * @param selectUndeterminedTextLanguage See {@link #selectUndeterminedTextLanguage}.
* @param forceLowestBitrate See {@link #forceLowestBitrate}.
* @param allowMixedMimeAdaptiveness See {@link #allowMixedMimeAdaptiveness}
* @param allowNonSeamlessAdaptiveness See {@link #allowNonSeamlessAdaptiveness}
@@ -181,13 +189,14 @@ public Parameters() {
* @param viewportOrientationMayChange See {@link #viewportOrientationMayChange}
*/
public Parameters(String preferredAudioLanguage, String preferredTextLanguage,
- boolean forceLowestBitrate, boolean allowMixedMimeAdaptiveness,
- boolean allowNonSeamlessAdaptiveness, int maxVideoWidth, int maxVideoHeight,
- int maxVideoBitrate, boolean exceedVideoConstraintsIfNecessary,
+ boolean selectUndeterminedTextLanguage, boolean forceLowestBitrate,
+ boolean allowMixedMimeAdaptiveness, boolean allowNonSeamlessAdaptiveness, int maxVideoWidth,
+ int maxVideoHeight, int maxVideoBitrate, boolean exceedVideoConstraintsIfNecessary,
boolean exceedRendererCapabilitiesIfNecessary, int viewportWidth, int viewportHeight,
boolean viewportOrientationMayChange) {
this.preferredAudioLanguage = preferredAudioLanguage;
this.preferredTextLanguage = preferredTextLanguage;
+ this.selectUndeterminedTextLanguage = selectUndeterminedTextLanguage;
this.forceLowestBitrate = forceLowestBitrate;
this.allowMixedMimeAdaptiveness = allowMixedMimeAdaptiveness;
this.allowNonSeamlessAdaptiveness = allowNonSeamlessAdaptiveness;
@@ -209,10 +218,11 @@ public Parameters withPreferredAudioLanguage(String preferredAudioLanguage) {
if (TextUtils.equals(preferredAudioLanguage, this.preferredAudioLanguage)) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -223,10 +233,26 @@ public Parameters withPreferredTextLanguage(String preferredTextLanguage) {
if (TextUtils.equals(preferredTextLanguage, this.preferredTextLanguage)) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
+ }
+
+ /**
+ * Returns an instance with the provided {@link #selectUndeterminedTextLanguage}.
+ */
+ public Parameters withSelectUndeterminedTextLanguageAsFallback(
+ boolean selectUndeterminedTextLanguage) {
+ if (selectUndeterminedTextLanguage == this.selectUndeterminedTextLanguage) {
+ return this;
+ }
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -236,10 +262,11 @@ public Parameters withForceLowestBitrate(boolean forceLowestBitrate) {
if (forceLowestBitrate == this.forceLowestBitrate) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -249,10 +276,11 @@ public Parameters withAllowMixedMimeAdaptiveness(boolean allowMixedMimeAdaptiven
if (allowMixedMimeAdaptiveness == this.allowMixedMimeAdaptiveness) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -262,10 +290,11 @@ public Parameters withAllowNonSeamlessAdaptiveness(boolean allowNonSeamlessAdapt
if (allowNonSeamlessAdaptiveness == this.allowNonSeamlessAdaptiveness) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -275,10 +304,11 @@ public Parameters withMaxVideoSize(int maxVideoWidth, int maxVideoHeight) {
if (maxVideoWidth == this.maxVideoWidth && maxVideoHeight == this.maxVideoHeight) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -288,10 +318,11 @@ public Parameters withMaxVideoBitrate(int maxVideoBitrate) {
if (maxVideoBitrate == this.maxVideoBitrate) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -320,10 +351,11 @@ public Parameters withExceedVideoConstraintsIfNecessary(
if (exceedVideoConstraintsIfNecessary == this.exceedVideoConstraintsIfNecessary) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -334,10 +366,11 @@ public Parameters withExceedRendererCapabilitiesIfNecessary(
if (exceedRendererCapabilitiesIfNecessary == this.exceedRendererCapabilitiesIfNecessary) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -350,10 +383,11 @@ public Parameters withViewportSize(int viewportWidth, int viewportHeight,
&& viewportOrientationMayChange == this.viewportOrientationMayChange) {
return this;
}
- return new Parameters(preferredAudioLanguage, preferredTextLanguage, forceLowestBitrate,
- allowMixedMimeAdaptiveness, allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight,
- maxVideoBitrate, exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary,
- viewportWidth, viewportHeight, viewportOrientationMayChange);
+ return new Parameters(preferredAudioLanguage, preferredTextLanguage,
+ selectUndeterminedTextLanguage, forceLowestBitrate, allowMixedMimeAdaptiveness,
+ allowNonSeamlessAdaptiveness, maxVideoWidth, maxVideoHeight, maxVideoBitrate,
+ exceedVideoConstraintsIfNecessary, exceedRendererCapabilitiesIfNecessary, viewportWidth,
+ viewportHeight, viewportOrientationMayChange);
}
/**
@@ -880,17 +914,20 @@ protected TrackSelection selectTextTrack(TrackGroupArray groups, int[][] formatS
boolean isDefault = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
boolean isForced = (format.selectionFlags & C.SELECTION_FLAG_FORCED) != 0;
int trackScore;
- if (formatHasLanguage(format, params.preferredTextLanguage)) {
+ boolean preferredLanguageFound = formatHasLanguage(format, params.preferredTextLanguage);
+ if (preferredLanguageFound
+ || (params.selectUndeterminedTextLanguage && formatHasNoLanguage(format))) {
if (isDefault) {
- trackScore = 6;
+ trackScore = 8;
} else if (!isForced) {
// 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
// a subset.
- trackScore = 5;
+ trackScore = 6;
} else {
trackScore = 4;
}
+ trackScore += preferredLanguageFound ? 1 : 0;
} else if (isDefault) {
trackScore = 3;
} else if (isForced) {
@@ -980,6 +1017,16 @@ protected static boolean isSupported(int formatSupport, boolean allowExceedsCapa
&& maskedSupport == RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES);
}
+ /**
+ * 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) {
+ return TextUtils.isEmpty(format.language) || formatHasLanguage(format, C.LANGUAGE_UNDETERMINED);
+ }
+
/**
* Returns whether a {@link Format} specifies a particular language, or {@code false} if
* {@code language} is null.
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 5b2de1042e3..24c5f4036de 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
@@ -50,6 +50,7 @@
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
+import java.util.MissingResourceException;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -238,13 +239,18 @@ public static void closeQuietly(Closeable closeable) {
}
/**
- * Returns a normalized RFC 5646 language code.
+ * Returns a normalized RFC 639-2/T code for {@code language}.
*
- * @param language A possibly non-normalized RFC 5646 language code.
- * @return The normalized code, or null if the input was null.
+ * @param language A case-insensitive ISO 639 alpha-2 or alpha-3 language code.
+ * @return The all-lowercase normalized code, or null if the input was null, or
+ * {@code language.toLowerCase()} if the language could not be normalized.
*/
public static String normalizeLanguageCode(String language) {
- return language == null ? null : new Locale(language).getLanguage();
+ try {
+ return language == null ? null : new Locale(language).getISO3Language();
+ } catch (MissingResourceException e) {
+ return language.toLowerCase();
+ }
}
/**
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 a0e499139c9..b2b149b004d 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
@@ -36,6 +36,8 @@ public final class DefaultTrackSelectorTest {
private static final Parameters DEFAULT_PARAMETERS = new Parameters();
private static final RendererCapabilities ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES =
new FakeRendererCapabilities(C.TRACK_TYPE_AUDIO);
+ private static final RendererCapabilities ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES =
+ new FakeRendererCapabilities(C.TRACK_TYPE_TEXT);
private static final RendererCapabilities ALL_AUDIO_FORMAT_EXCEEDED_RENDERER_CAPABILITIES =
new FakeRendererCapabilities(C.TRACK_TYPE_AUDIO, FORMAT_EXCEEDS_CAPABILITIES);
@@ -534,6 +536,60 @@ public void testSelectTracksExceedingCapabilitiesPreferLowerSampleRateBeforeBitr
.isEqualTo(lowerSampleRateHigherBitrateFormat);
}
+ /**
+ * Tests that the default track selector will select a text track with undetermined language if no
+ * text track with the preferred language is available but
+ * {@link Parameters#selectUndeterminedTextLanguage} is true.
+ */
+ @Test
+ public void testSelectUndeterminedTextLanguageAsFallback() throws ExoPlaybackException{
+ Format spanish = Format.createTextContainerFormat("spanish", null,
+ MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "spa");
+ Format german = Format.createTextContainerFormat("german", null,
+ MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "de");
+ Format undeterminedUnd = Format.createTextContainerFormat("undeterminedUnd", null,
+ MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, "und");
+ Format undeterminedNull = Format.createTextContainerFormat("undeterminedNull", null,
+ MimeTypes.TEXT_VTT, null, Format.NO_VALUE, 0, null);
+
+ RendererCapabilities[] textRendererCapabilites =
+ new RendererCapabilities[] {ALL_TEXT_FORMAT_SUPPORTED_RENDERER_CAPABILITIES};
+
+ TrackSelectorResult result;
+
+ result = trackSelector.selectTracks(textRendererCapabilites,
+ wrapFormats(spanish, german, undeterminedUnd, undeterminedNull));
+ assertThat(result.selections.get(0)).isNull();
+
+ trackSelector.setParameters(
+ DEFAULT_PARAMETERS.withSelectUndeterminedTextLanguageAsFallback(true));
+ result = trackSelector.selectTracks(textRendererCapabilites,
+ wrapFormats(spanish, german, undeterminedUnd, undeterminedNull));
+ assertThat(result.selections.get(0).getFormat(0)).isSameAs(undeterminedUnd);
+
+ trackSelector.setParameters(DEFAULT_PARAMETERS.withPreferredTextLanguage("spa"));
+ result = trackSelector.selectTracks(textRendererCapabilites,
+ wrapFormats(spanish, german, undeterminedUnd, undeterminedNull));
+ assertThat(result.selections.get(0).getFormat(0)).isSameAs(spanish);
+
+ result = trackSelector.selectTracks(textRendererCapabilites,
+ wrapFormats(german, undeterminedUnd, undeterminedNull));
+ assertThat(result.selections.get(0)).isNull();
+
+ trackSelector.setParameters(
+ trackSelector.getParameters().withSelectUndeterminedTextLanguageAsFallback(true));
+ result = trackSelector.selectTracks(textRendererCapabilites,
+ wrapFormats(german, undeterminedUnd, undeterminedNull));
+ assertThat(result.selections.get(0).getFormat(0)).isSameAs(undeterminedUnd);
+
+ result = trackSelector.selectTracks(textRendererCapabilites,
+ wrapFormats(german, undeterminedNull));
+ assertThat(result.selections.get(0).getFormat(0)).isSameAs(undeterminedNull);
+
+ result = trackSelector.selectTracks(textRendererCapabilites, wrapFormats(german));
+ assertThat(result.selections.get(0)).isNull();
+ }
+
/**
* Tests that track selector will select audio tracks with lower bitrate when {@link Parameters}
* indicate lowest bitrate preference, even when tracks are within capabilities.
@@ -562,6 +618,14 @@ private static TrackGroupArray singleTrackGroup(Format... formats) {
return new TrackGroupArray(new TrackGroup(formats));
}
+ private static TrackGroupArray wrapFormats(Format... formats) {
+ TrackGroup[] trackGroups = new TrackGroup[formats.length];
+ for (int i = 0; i < trackGroups.length; i++) {
+ trackGroups[i] = new TrackGroup(formats[i]);
+ }
+ return new TrackGroupArray(trackGroups);
+ }
+
/**
* A {@link RendererCapabilities} that advertises support for all formats of a given type using
* a provided support value. For any format that does not have the given track type,