mirror of
https://github.com/androidx/media.git
synced 2025-05-14 11:09:53 +08:00
Add option to set preferred audio role flags in DefaultTrackSelector
We already have the eequivalent option for text tracks. PiperOrigin-RevId: 351999287
This commit is contained in:
parent
d2950c2e97
commit
68fd23a967
@ -141,6 +141,7 @@
|
||||
* Add option to specify multiple preferred audio or text languages.
|
||||
* Add option to specify preferred MIME type(s) for video and audio
|
||||
([#8320](https://github.com/google/ExoPlayer/issues/8320)).
|
||||
* Add option to specify preferred audio role flags.
|
||||
* Forward `Timeline` and `MediaPeriodId` to `TrackSelection.Factory`.
|
||||
* DASH:
|
||||
* Support low-latency DASH playback (`availabilityTimeOffset` and
|
||||
|
@ -489,6 +489,12 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParametersBuilder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAudioRoleFlags) {
|
||||
super.setPreferredAudioRoleFlags(preferredAudioRoleFlags);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum allowed audio channel count.
|
||||
*
|
||||
@ -843,6 +849,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
preferredVideoMimeTypes,
|
||||
// Audio
|
||||
preferredAudioLanguages,
|
||||
preferredAudioRoleFlags,
|
||||
maxAudioChannelCount,
|
||||
maxAudioBitrate,
|
||||
exceedAudioConstraintsIfNecessary,
|
||||
@ -1112,6 +1119,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
ImmutableList<String> preferredVideoMimeTypes,
|
||||
// Audio
|
||||
ImmutableList<String> preferredAudioLanguages,
|
||||
@C.RoleFlags int preferredAudioRoleFlags,
|
||||
int maxAudioChannelCount,
|
||||
int maxAudioBitrate,
|
||||
boolean exceedAudioConstraintsIfNecessary,
|
||||
@ -1135,6 +1143,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
SparseBooleanArray rendererDisabledFlags) {
|
||||
super(
|
||||
preferredAudioLanguages,
|
||||
preferredAudioRoleFlags,
|
||||
preferredTextLanguages,
|
||||
preferredTextRoleFlags,
|
||||
selectUndeterminedTextLanguage,
|
||||
@ -2724,6 +2733,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
private final boolean isWithinRendererCapabilities;
|
||||
private final int preferredLanguageScore;
|
||||
private final int preferredLanguageIndex;
|
||||
private final int preferredRoleFlagsScore;
|
||||
private final int localeLanguageMatchIndex;
|
||||
private final int localeLanguageScore;
|
||||
private final boolean isDefaultSelectionFlag;
|
||||
@ -2753,6 +2763,8 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
}
|
||||
preferredLanguageIndex = bestLanguageIndex;
|
||||
preferredLanguageScore = bestLanguageScore;
|
||||
preferredRoleFlagsScore =
|
||||
Integer.bitCount(format.roleFlags & parameters.preferredAudioRoleFlags);
|
||||
isDefaultSelectionFlag = (format.selectionFlags & C.SELECTION_FLAG_DEFAULT) != 0;
|
||||
channelCount = format.channelCount;
|
||||
sampleRate = format.sampleRate;
|
||||
@ -2809,6 +2821,7 @@ public class DefaultTrackSelector extends MappingTrackSelector {
|
||||
other.preferredLanguageIndex,
|
||||
Ordering.natural().reverse())
|
||||
.compare(this.preferredLanguageScore, other.preferredLanguageScore)
|
||||
.compare(this.preferredRoleFlagsScore, other.preferredRoleFlagsScore)
|
||||
.compareFalseFirst(this.isWithinConstraints, other.isWithinConstraints)
|
||||
.compare(
|
||||
this.preferredMimeTypeMatchIndex,
|
||||
|
@ -40,6 +40,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
public static class Builder {
|
||||
|
||||
/* package */ ImmutableList<String> preferredAudioLanguages;
|
||||
@C.RoleFlags /* package */ int preferredAudioRoleFlags;
|
||||
/* package */ ImmutableList<String> preferredTextLanguages;
|
||||
@C.RoleFlags /* package */ int preferredTextRoleFlags;
|
||||
/* package */ boolean selectUndeterminedTextLanguage;
|
||||
@ -63,6 +64,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
@Deprecated
|
||||
public Builder() {
|
||||
preferredAudioLanguages = ImmutableList.of();
|
||||
preferredAudioRoleFlags = 0;
|
||||
preferredTextLanguages = ImmutableList.of();
|
||||
preferredTextRoleFlags = 0;
|
||||
selectUndeterminedTextLanguage = false;
|
||||
@ -75,6 +77,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
*/
|
||||
/* package */ Builder(TrackSelectionParameters initialValues) {
|
||||
preferredAudioLanguages = initialValues.preferredAudioLanguages;
|
||||
preferredAudioRoleFlags = initialValues.preferredAudioRoleFlags;
|
||||
preferredTextLanguages = initialValues.preferredTextLanguages;
|
||||
preferredTextRoleFlags = initialValues.preferredTextRoleFlags;
|
||||
selectUndeterminedTextLanguage = initialValues.selectUndeterminedTextLanguage;
|
||||
@ -111,6 +114,17 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred {@link C.RoleFlags} for audio tracks.
|
||||
*
|
||||
* @param preferredAudioRoleFlags Preferred audio role flags.
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder setPreferredAudioRoleFlags(@C.RoleFlags int preferredAudioRoleFlags) {
|
||||
this.preferredAudioRoleFlags = preferredAudioRoleFlags;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preferred language and role flags for text tracks based on the accessibility
|
||||
* settings of {@link CaptioningManager}.
|
||||
@ -201,6 +215,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
return new TrackSelectionParameters(
|
||||
// Audio
|
||||
preferredAudioLanguages,
|
||||
preferredAudioRoleFlags,
|
||||
// Text
|
||||
preferredTextLanguages,
|
||||
preferredTextRoleFlags,
|
||||
@ -262,6 +277,11 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
* default. The default value is an empty list.
|
||||
*/
|
||||
public final ImmutableList<String> preferredAudioLanguages;
|
||||
/**
|
||||
* The preferred {@link C.RoleFlags} for audio tracks. {@code 0} selects the default track if
|
||||
* there is one, or the first track if there's no default. The default value is {@code 0}.
|
||||
*/
|
||||
@C.RoleFlags public final int preferredAudioRoleFlags;
|
||||
/**
|
||||
* The preferred languages for text tracks as IETF BCP 47 conformant tags in order of preference.
|
||||
* An empty list selects the default track if there is one, or no track otherwise. The default
|
||||
@ -290,12 +310,14 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
|
||||
/* package */ TrackSelectionParameters(
|
||||
ImmutableList<String> preferredAudioLanguages,
|
||||
@C.RoleFlags int preferredAudioRoleFlags,
|
||||
ImmutableList<String> preferredTextLanguages,
|
||||
@C.RoleFlags int preferredTextRoleFlags,
|
||||
boolean selectUndeterminedTextLanguage,
|
||||
@C.SelectionFlags int disabledTextTrackSelectionFlags) {
|
||||
// Audio
|
||||
this.preferredAudioLanguages = preferredAudioLanguages;
|
||||
this.preferredAudioRoleFlags = preferredAudioRoleFlags;
|
||||
// Text
|
||||
this.preferredTextLanguages = preferredTextLanguages;
|
||||
this.preferredTextRoleFlags = preferredTextRoleFlags;
|
||||
@ -307,6 +329,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
ArrayList<String> preferredAudioLanguages = new ArrayList<>();
|
||||
in.readList(preferredAudioLanguages, /* loader= */ null);
|
||||
this.preferredAudioLanguages = ImmutableList.copyOf(preferredAudioLanguages);
|
||||
this.preferredAudioRoleFlags = in.readInt();
|
||||
ArrayList<String> preferredTextLanguages = new ArrayList<>();
|
||||
in.readList(preferredTextLanguages, /* loader= */ null);
|
||||
this.preferredTextLanguages = ImmutableList.copyOf(preferredTextLanguages);
|
||||
@ -331,6 +354,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
}
|
||||
TrackSelectionParameters other = (TrackSelectionParameters) obj;
|
||||
return preferredAudioLanguages.equals(other.preferredAudioLanguages)
|
||||
&& preferredAudioRoleFlags == other.preferredAudioRoleFlags
|
||||
&& preferredTextLanguages.equals(other.preferredTextLanguages)
|
||||
&& preferredTextRoleFlags == other.preferredTextRoleFlags
|
||||
&& selectUndeterminedTextLanguage == other.selectUndeterminedTextLanguage
|
||||
@ -341,6 +365,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = 31 * result + preferredAudioLanguages.hashCode();
|
||||
result = 31 * result + preferredAudioRoleFlags;
|
||||
result = 31 * result + preferredTextLanguages.hashCode();
|
||||
result = 31 * result + preferredTextRoleFlags;
|
||||
result = 31 * result + (selectUndeterminedTextLanguage ? 1 : 0);
|
||||
@ -358,6 +383,7 @@ public class TrackSelectionParameters implements Parcelable {
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeList(preferredAudioLanguages);
|
||||
dest.writeInt(preferredAudioRoleFlags);
|
||||
dest.writeList(preferredTextLanguages);
|
||||
dest.writeInt(preferredTextRoleFlags);
|
||||
Util.writeBoolean(dest, selectUndeterminedTextLanguage);
|
||||
|
@ -383,6 +383,75 @@ public final class DefaultTrackSelectorTest {
|
||||
assertFixedSelection(result.selections.get(0), trackGroups, enAudioFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that track selector will select audio track with the highest number of matching role
|
||||
* flags given by {@link Parameters}.
|
||||
*/
|
||||
@Test
|
||||
public void selectTracks_withPreferredAudioRoleFlags_selectPreferredTrack() throws Exception {
|
||||
Format.Builder formatBuilder = AUDIO_FORMAT.buildUpon();
|
||||
Format noRoleFlags = formatBuilder.build();
|
||||
Format lessRoleFlags = formatBuilder.setRoleFlags(C.ROLE_FLAG_CAPTION).build();
|
||||
Format moreRoleFlags =
|
||||
formatBuilder
|
||||
.setRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY | C.ROLE_FLAG_DUB)
|
||||
.build();
|
||||
TrackGroupArray trackGroups = wrapFormats(noRoleFlags, moreRoleFlags, lessRoleFlags);
|
||||
|
||||
trackSelector.setParameters(
|
||||
defaultParameters
|
||||
.buildUpon()
|
||||
.setPreferredAudioRoleFlags(C.ROLE_FLAG_CAPTION | C.ROLE_FLAG_COMMENTARY));
|
||||
TrackSelectorResult result =
|
||||
trackSelector.selectTracks(
|
||||
new RendererCapabilities[] {ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES},
|
||||
trackGroups,
|
||||
periodId,
|
||||
TIMELINE);
|
||||
assertFixedSelection(result.selections.get(0), trackGroups, moreRoleFlags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that track selector with select default audio track if no role flag preference is
|
||||
* specified by {@link Parameters}.
|
||||
*/
|
||||
@Test
|
||||
public void selectTracks_withoutPreferredAudioRoleFlags_selectsDefaultTrack() throws Exception {
|
||||
Format firstFormat = AUDIO_FORMAT;
|
||||
Format defaultFormat =
|
||||
AUDIO_FORMAT.buildUpon().setSelectionFlags(C.SELECTION_FLAG_DEFAULT).build();
|
||||
Format roleFlagFormat = AUDIO_FORMAT.buildUpon().setRoleFlags(C.ROLE_FLAG_CAPTION).build();
|
||||
TrackGroupArray trackGroups = wrapFormats(firstFormat, defaultFormat, roleFlagFormat);
|
||||
|
||||
TrackSelectorResult result =
|
||||
trackSelector.selectTracks(
|
||||
new RendererCapabilities[] {ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES},
|
||||
trackGroups,
|
||||
periodId,
|
||||
TIMELINE);
|
||||
assertFixedSelection(result.selections.get(0), trackGroups, defaultFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that track selector with select the first audio track if no role flag preference is
|
||||
* specified by {@link Parameters} and no default track exists.
|
||||
*/
|
||||
@Test
|
||||
public void selectTracks_withoutPreferredAudioRoleFlagsOrDefaultTrack_selectsFirstTrack()
|
||||
throws Exception {
|
||||
Format firstFormat = AUDIO_FORMAT;
|
||||
Format roleFlagFormat = AUDIO_FORMAT.buildUpon().setRoleFlags(C.ROLE_FLAG_CAPTION).build();
|
||||
TrackGroupArray trackGroups = wrapFormats(firstFormat, roleFlagFormat);
|
||||
|
||||
TrackSelectorResult result =
|
||||
trackSelector.selectTracks(
|
||||
new RendererCapabilities[] {ALL_AUDIO_FORMAT_SUPPORTED_RENDERER_CAPABILITIES},
|
||||
trackGroups,
|
||||
periodId,
|
||||
TIMELINE);
|
||||
assertFixedSelection(result.selections.get(0), trackGroups, firstFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that track selector will prefer selecting audio track with language that match preferred
|
||||
* language given by {@link Parameters} over track with {@link C#SELECTION_FLAG_DEFAULT}.
|
||||
@ -1667,6 +1736,7 @@ public final class DefaultTrackSelectorTest {
|
||||
/* preferredVideoMimeTypes= */ ImmutableList.of(MimeTypes.VIDEO_AV1, MimeTypes.VIDEO_H264),
|
||||
// Audio
|
||||
/* preferredAudioLanguages= */ ImmutableList.of("zh", "jp"),
|
||||
/* preferredAudioRoleFlags= */ C.ROLE_FLAG_COMMENTARY,
|
||||
/* maxAudioChannelCount= */ 10,
|
||||
/* maxAudioBitrate= */ 11,
|
||||
/* exceedAudioConstraintsIfNecessary= */ false,
|
||||
|
Loading…
x
Reference in New Issue
Block a user