Fix spurious unsupported tracks toast in demo apps

PiperOrigin-RevId: 424062588
This commit is contained in:
olly 2022-01-25 14:07:21 +00:00 committed by Ian Baker
parent abef4f4e14
commit aceacb05ca
3 changed files with 87 additions and 31 deletions

View File

@ -223,10 +223,12 @@ import java.util.ArrayList;
if (currentPlayer != localPlayer || tracksInfo == lastSeenTrackGroupInfo) { if (currentPlayer != localPlayer || tracksInfo == lastSeenTrackGroupInfo) {
return; return;
} }
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)) { if (!tracksInfo.isTypeSupportedOrEmpty(
C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true)) {
listener.onUnsupportedTrack(C.TRACK_TYPE_VIDEO); listener.onUnsupportedTrack(C.TRACK_TYPE_VIDEO);
} }
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)) { if (!tracksInfo.isTypeSupportedOrEmpty(
C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true)) {
listener.onUnsupportedTrack(C.TRACK_TYPE_AUDIO); listener.onUnsupportedTrack(C.TRACK_TYPE_AUDIO);
} }
lastSeenTrackGroupInfo = tracksInfo; lastSeenTrackGroupInfo = tracksInfo;

View File

@ -441,10 +441,12 @@ public class PlayerActivity extends AppCompatActivity
if (tracksInfo == lastSeenTracksInfo) { if (tracksInfo == lastSeenTracksInfo) {
return; return;
} }
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)) { if (!tracksInfo.isTypeSupportedOrEmpty(
C.TRACK_TYPE_VIDEO, /* allowExceedsCapabilities= */ true)) {
showToast(R.string.error_unsupported_video); showToast(R.string.error_unsupported_video);
} }
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)) { if (!tracksInfo.isTypeSupportedOrEmpty(
C.TRACK_TYPE_AUDIO, /* allowExceedsCapabilities= */ true)) {
showToast(R.string.error_unsupported_audio); showToast(R.string.error_unsupported_audio);
} }
lastSeenTracksInfo = tracksInfo; lastSeenTracksInfo = tracksInfo;

View File

@ -25,7 +25,6 @@ import android.os.Bundle;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.trackselection.TrackSelectionParameters;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Booleans; import com.google.common.primitives.Booleans;
@ -35,11 +34,12 @@ import java.lang.annotation.RetentionPolicy;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
/** Immutable information ({@link TrackGroupInfo}) about tracks. */ /** Information about groups of tracks. */
public final class TracksInfo implements Bundleable { public final class TracksInfo implements Bundleable {
/** /**
* Information about tracks in a {@link TrackGroup}: their {@link C.TrackType}, if their format is * Information about a single group of tracks, including the underlying {@link TrackGroup}, the
* supported by the player and if they are selected for playback. * {@link C.TrackType type} of tracks it contains, and the level to which each track is supported
* by the player.
*/ */
public static final class TrackGroupInfo implements Bundleable { public static final class TrackGroupInfo implements Bundleable {
private final TrackGroup trackGroup; private final TrackGroup trackGroup;
@ -74,7 +74,7 @@ public final class TracksInfo implements Bundleable {
} }
/** /**
* Returns the level of support for a track in a {@link TrackGroup}. * Returns the level of support for a specified track.
* *
* @param trackIndex The index of the track in the {@link TrackGroup}. * @param trackIndex The index of the track in the {@link TrackGroup}.
* @return The {@link C.FormatSupport} of the track. * @return The {@link C.FormatSupport} of the track.
@ -85,24 +85,58 @@ public final class TracksInfo implements Bundleable {
} }
/** /**
* Returns if a track in a {@link TrackGroup} is supported for playback. * Returns whether a specified track is supported for playback, without exceeding the advertised
* capabilities of the device. Equivalent to {@code isTrackSupported(trackIndex, false)}.
* *
* @param trackIndex The index of the track in the {@link TrackGroup}. * @param trackIndex The index of the track in the {@link TrackGroup}.
* @return True if the track's format can be played, false otherwise. * @return True if the track's format can be played, false otherwise.
*/ */
public boolean isTrackSupported(int trackIndex) { public boolean isTrackSupported(int trackIndex) {
return trackSupport[trackIndex] == C.FORMAT_HANDLED; return isTrackSupported(trackIndex, /* allowExceedsCapabilities= */ false);
} }
/** Returns if at least one track in a {@link TrackGroup} is selected for playback. */ /**
* Returns whether a specified track is supported for playback.
*
* @param trackIndex The index of the track in the {@link TrackGroup}.
* @param allowExceedsCapabilities Whether to consider the track as supported if it has a
* supported {@link Format#sampleMimeType MIME type}, but otherwise exceeds the advertised
* capabilities of the device. For example, a video track for which there's a corresponding
* decoder whose maximum advertised resolution is exceeded by the resolution of the track.
* Such tracks may be playable in some cases.
* @return True if the track's format can be played, false otherwise.
*/
public boolean isTrackSupported(int trackIndex, boolean allowExceedsCapabilities) {
return trackSupport[trackIndex] == C.FORMAT_HANDLED
|| (allowExceedsCapabilities
&& trackSupport[trackIndex] == C.FORMAT_EXCEEDS_CAPABILITIES);
}
/** Returns whether at least one track in the group is selected for playback. */
public boolean isSelected() { public boolean isSelected() {
return Booleans.contains(trackSelected, true); return Booleans.contains(trackSelected, true);
} }
/** Returns if at least one track in a {@link TrackGroup} is supported. */ /**
* Returns whether at least one track in the group is supported for playback, without exceeding
* the advertised capabilities of the device. Equivalent to {@code isSupported(false)}.
*/
public boolean isSupported() { public boolean isSupported() {
return isSupported(/* allowExceedsCapabilities= */ false);
}
/**
* Returns whether at least one track in the group is supported for playback.
*
* @param allowExceedsCapabilities Whether to consider a track as supported if it has a
* supported {@link Format#sampleMimeType MIME type}, but otherwise exceeds the advertised
* capabilities of the device. For example, a video track for which there's a corresponding
* decoder whose maximum advertised resolution is exceeded by the resolution of the track.
* Such tracks may be playable in some cases.
*/
public boolean isSupported(boolean allowExceedsCapabilities) {
for (int i = 0; i < trackSupport.length; i++) { for (int i = 0; i < trackSupport.length; i++) {
if (isTrackSupported(i)) { if (isTrackSupported(i, allowExceedsCapabilities)) {
return true; return true;
} }
} }
@ -110,27 +144,24 @@ public final class TracksInfo implements Bundleable {
} }
/** /**
* Returns if a track in a {@link TrackGroup} is selected for playback. * Returns whether a specified track is selected for playback.
* *
* <p>Multiple tracks of a track group may be selected. This is common in adaptive streaming, * <p>Note that multiple tracks in the group may be selected. This is common in adaptive
* where multiple tracks of different quality are selected and the player switches between them * streaming, where tracks of different qualities are selected and the player switches between
* depending on the network and the {@link TrackSelectionParameters}. * them during playback (e.g., based on the available network bandwidth).
* *
* <p>While this class doesn't provide which selected track is currently playing, some player * <p>This class doesn't provide a way to determine which of the selected tracks is currently
* implementations have ways of getting such information. For example ExoPlayer provides this * playing, however some player implementations have ways of getting such information. For
* information in {@code ExoTrackSelection.getSelectedFormat}. * example, ExoPlayer provides this information via {@code ExoTrackSelection.getSelectedFormat}.
* *
* @param trackIndex The index of the track in the {@link TrackGroup}. * @param trackIndex The index of the track in the {@link TrackGroup}.
* @return true if the track is selected, false otherwise. * @return True if the track is selected, false otherwise.
*/ */
public boolean isTrackSelected(int trackIndex) { public boolean isTrackSelected(int trackIndex) {
return trackSelected[trackIndex]; return trackSelected[trackIndex];
} }
/** /** Returns the {@link C.TrackType} of the group. */
* Returns the {@link C.TrackType} of the tracks in the {@link TrackGroup}. Tracks in a group
* are all of the same type.
*/
public @C.TrackType int getTrackType() { public @C.TrackType int getTrackType() {
return trackType; return trackType;
} }
@ -212,28 +243,49 @@ public final class TracksInfo implements Bundleable {
private final ImmutableList<TrackGroupInfo> trackGroupInfos; private final ImmutableList<TrackGroupInfo> trackGroupInfos;
/** An empty {@code TrackInfo} containing no {@link TrackGroupInfo}. */ /** An {@code TrackInfo} that contains no tracks. */
public static final TracksInfo EMPTY = new TracksInfo(ImmutableList.of()); public static final TracksInfo EMPTY = new TracksInfo(ImmutableList.of());
/** Constructs {@code TracksInfo} from the provided {@link TrackGroupInfo}. */ /**
* Constructs an instance.
*
* @param trackGroupInfos The {@link TrackGroupInfo TrackGroupInfos} describing the groups of
* tracks.
*/
public TracksInfo(List<TrackGroupInfo> trackGroupInfos) { public TracksInfo(List<TrackGroupInfo> trackGroupInfos) {
this.trackGroupInfos = ImmutableList.copyOf(trackGroupInfos); this.trackGroupInfos = ImmutableList.copyOf(trackGroupInfos);
} }
/** Returns the {@link TrackGroupInfo TrackGroupInfos}, describing each {@link TrackGroup}. */ /** Returns the {@link TrackGroupInfo TrackGroupInfos} describing the groups of tracks. */
public ImmutableList<TrackGroupInfo> getTrackGroupInfos() { public ImmutableList<TrackGroupInfo> getTrackGroupInfos() {
return trackGroupInfos; return trackGroupInfos;
} }
/** /**
* Returns true if at least one track of type {@code trackType} is {@link * Returns true if at least one track of type {@code trackType} is {@link
* TrackGroupInfo#isTrackSupported(int) supported}, or there are no tracks of this type. * TrackGroupInfo#isTrackSupported(int) supported} or if there are no tracks of this type.
*/ */
public boolean isTypeSupportedOrEmpty(@C.TrackType int trackType) { public boolean isTypeSupportedOrEmpty(@C.TrackType int trackType) {
return isTypeSupportedOrEmpty(trackType, /* allowExceedsCapabilities= */ false);
}
/**
* Returns true if at least one track of type {@code trackType} is {@link
* TrackGroupInfo#isTrackSupported(int, boolean) supported} or if there are no tracks of this
* type.
*
* @param allowExceedsCapabilities Whether to consider the track as supported if it has a
* supported {@link Format#sampleMimeType MIME type}, but otherwise exceeds the advertised
* capabilities of the device. For example, a video track for which there's a corresponding
* decoder whose maximum advertised resolution is exceeded by the resolution of the track.
* Such tracks may be playable in some cases.
*/
public boolean isTypeSupportedOrEmpty(
@C.TrackType int trackType, boolean allowExceedsCapabilities) {
boolean supported = true; boolean supported = true;
for (int i = 0; i < trackGroupInfos.size(); i++) { for (int i = 0; i < trackGroupInfos.size(); i++) {
if (trackGroupInfos.get(i).trackType == trackType) { if (trackGroupInfos.get(i).trackType == trackType) {
if (trackGroupInfos.get(i).isSupported()) { if (trackGroupInfos.get(i).isSupported(allowExceedsCapabilities)) {
return true; return true;
} else { } else {
supported = false; supported = false;