Skip to content

Commit

Permalink
Use TracksInfo and selection override in users
Browse files Browse the repository at this point in the history
Update the UI module, the demos and most other users
to make use of the new player TracksInfo and track
selection override APIs.

PiperOrigin-RevId: 402817857
  • Loading branch information
krocard authored and ojw28 committed Oct 14, 2021
1 parent fe0a566 commit 98ee159
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 314 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import android.view.KeyEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.MediaItem;
Expand All @@ -28,12 +27,9 @@
import com.google.android.exoplayer2.Player.TimelineChangeReason;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.ext.cast.CastPlayer;
import com.google.android.exoplayer2.ext.cast.SessionAvailabilityListener;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.gms.cast.framework.CastContext;
Expand All @@ -58,13 +54,12 @@ interface Listener {

private final PlayerView localPlayerView;
private final PlayerControlView castControlView;
private final DefaultTrackSelector trackSelector;
private final SimpleExoPlayer exoPlayer;
private final Player localPlayer;
private final CastPlayer castPlayer;
private final ArrayList<MediaItem> mediaQueue;
private final Listener listener;

private TrackGroupArray lastSeenTrackGroupArray;
private TracksInfo lastSeenTrackGroupInfo;
private int currentItemIndex;
private Player currentPlayer;

Expand All @@ -89,17 +84,16 @@ public PlayerManager(
mediaQueue = new ArrayList<>();
currentItemIndex = C.INDEX_UNSET;

trackSelector = new DefaultTrackSelector(context);
exoPlayer = new ExoPlayer.Builder(context).setTrackSelector(trackSelector).build();
exoPlayer.addListener(this);
localPlayerView.setPlayer(exoPlayer);
localPlayer = new ExoPlayer.Builder(context).build();
localPlayer.addListener(this);
localPlayerView.setPlayer(localPlayer);

castPlayer = new CastPlayer(castContext);
castPlayer.addListener(this);
castPlayer.setSessionAvailabilityListener(this);
castControlView.setPlayer(castPlayer);

setCurrentPlayer(castPlayer.isCastSessionAvailable() ? castPlayer : exoPlayer);
setCurrentPlayer(castPlayer.isCastSessionAvailable() ? castPlayer : localPlayer);
}

// Queue manipulation methods.
Expand Down Expand Up @@ -200,7 +194,7 @@ public boolean moveItem(MediaItem item, int newIndex) {
* @return Whether the event was handled by the target view.
*/
public boolean dispatchKeyEvent(KeyEvent event) {
if (currentPlayer == exoPlayer) {
if (currentPlayer == localPlayer) {
return localPlayerView.dispatchKeyEvent(event);
} else /* currentPlayer == castPlayer */ {
return castControlView.dispatchKeyEvent(event);
Expand All @@ -214,7 +208,7 @@ public void release() {
castPlayer.setSessionAvailabilityListener(null);
castPlayer.release();
localPlayerView.setPlayer(null);
exoPlayer.release();
localPlayer.release();
}

// Player.Listener implementation.
Expand All @@ -238,24 +232,17 @@ public void onTimelineChanged(@NonNull Timeline timeline, @TimelineChangeReason
}

@Override
public void onTracksChanged(
@NonNull TrackGroupArray trackGroups, @NonNull TrackSelectionArray trackSelections) {
if (currentPlayer == exoPlayer && trackGroups != lastSeenTrackGroupArray) {
@Nullable
MappingTrackSelector.MappedTrackInfo mappedTrackInfo =
trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO)
== MappingTrackSelector.MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
listener.onUnsupportedTrack(C.TRACK_TYPE_VIDEO);
}
if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_AUDIO)
== MappingTrackSelector.MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
listener.onUnsupportedTrack(C.TRACK_TYPE_AUDIO);
}
}
lastSeenTrackGroupArray = trackGroups;
public void onTracksInfoChanged(TracksInfo tracksInfo) {
if (currentPlayer != localPlayer || tracksInfo == lastSeenTrackGroupInfo) {
return;
}
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)) {
listener.onUnsupportedTrack(C.TRACK_TYPE_VIDEO);
}
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)) {
listener.onUnsupportedTrack(C.TRACK_TYPE_AUDIO);
}
lastSeenTrackGroupInfo = tracksInfo;
}

// CastPlayer.SessionAvailabilityListener implementation.
Expand All @@ -267,7 +254,7 @@ public void onCastSessionAvailable() {

@Override
public void onCastSessionUnavailable() {
setCurrentPlayer(exoPlayer);
setCurrentPlayer(localPlayer);
}

// Internal methods.
Expand All @@ -286,7 +273,7 @@ private void setCurrentPlayer(Player currentPlayer) {
}

// View management.
if (currentPlayer == exoPlayer) {
if (currentPlayer == localPlayer) {
localPlayerView.setVisibility(View.VISIBLE);
castControlView.hide();
} else /* currentPlayer == castPlayer */ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
import com.google.android.exoplayer2.ext.ima.ImaAdsLoader;
Expand All @@ -46,11 +47,8 @@
import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.StyledPlayerControlView;
import com.google.android.exoplayer2.ui.StyledPlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
Expand All @@ -69,7 +67,7 @@ public class PlayerActivity extends AppCompatActivity

// Saved instance state keys.

private static final String KEY_TRACK_SELECTOR_PARAMETERS = "track_selector_parameters";
private static final String KEY_TRACK_SELECTION_PARAMETERS = "track_selection_parameters";
private static final String KEY_WINDOW = "window";
private static final String KEY_POSITION = "position";
private static final String KEY_AUTO_PLAY = "auto_play";
Expand All @@ -84,9 +82,9 @@ public class PlayerActivity extends AppCompatActivity
private DataSource.Factory dataSourceFactory;
private List<MediaItem> mediaItems;
private DefaultTrackSelector trackSelector;
private DefaultTrackSelector.Parameters trackSelectorParameters;
private DefaultTrackSelector.Parameters trackSelectionParameters;
private DebugTextViewHelper debugViewHelper;
private TrackGroupArray lastSeenTrackGroupArray;
private TracksInfo lastSeenTracksInfo;
private boolean startAutoPlay;
private int startWindow;
private long startPosition;
Expand Down Expand Up @@ -114,16 +112,16 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
playerView.requestFocus();

if (savedInstanceState != null) {
trackSelectorParameters =
// Restore as DefaultTrackSelector.Parameters in case ExoPlayer specific parameters were set.
trackSelectionParameters =
DefaultTrackSelector.Parameters.CREATOR.fromBundle(
savedInstanceState.getBundle(KEY_TRACK_SELECTOR_PARAMETERS));
savedInstanceState.getBundle(KEY_TRACK_SELECTION_PARAMETERS));
startAutoPlay = savedInstanceState.getBoolean(KEY_AUTO_PLAY);
startWindow = savedInstanceState.getInt(KEY_WINDOW);
startPosition = savedInstanceState.getLong(KEY_POSITION);
} else {
DefaultTrackSelector.ParametersBuilder builder =
new DefaultTrackSelector.ParametersBuilder(/* context= */ this);
trackSelectorParameters = builder.build();
trackSelectionParameters =
new DefaultTrackSelector.ParametersBuilder(/* context= */ this).build();
clearStartPosition();
}
}
Expand Down Expand Up @@ -209,7 +207,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
updateTrackSelectorParameters();
updateStartPosition();
outState.putBundle(KEY_TRACK_SELECTOR_PARAMETERS, trackSelectorParameters.toBundle());
outState.putBundle(KEY_TRACK_SELECTION_PARAMETERS, trackSelectionParameters.toBundle());
outState.putBoolean(KEY_AUTO_PLAY, startAutoPlay);
outState.putInt(KEY_WINDOW, startWindow);
outState.putLong(KEY_POSITION, startPosition);
Expand Down Expand Up @@ -272,13 +270,13 @@ protected boolean initializePlayer() {
.setAdViewProvider(playerView);

trackSelector = new DefaultTrackSelector(/* context= */ this);
trackSelector.setParameters(trackSelectorParameters);
lastSeenTrackGroupArray = null;
lastSeenTracksInfo = TracksInfo.EMPTY;
player =
new ExoPlayer.Builder(/* context= */ this, renderersFactory)
.setMediaSourceFactory(mediaSourceFactory)
.setTrackSelector(trackSelector)
.build();
player.setTrackSelectionParameters(trackSelectionParameters);
player.addListener(new PlayerEventListener());
player.addAnalyticsListener(new EventLogger(trackSelector));
player.setAudioAttributes(AudioAttributes.DEFAULT, /* handleAudioFocus= */ true);
Expand Down Expand Up @@ -361,7 +359,6 @@ protected void releasePlayer() {
player.release();
player = null;
mediaItems = Collections.emptyList();
trackSelector = null;
}
if (adsLoader != null) {
adsLoader.setPlayer(null);
Expand All @@ -377,8 +374,11 @@ private void releaseAdsLoader() {
}

private void updateTrackSelectorParameters() {
if (trackSelector != null) {
trackSelectorParameters = trackSelector.getParameters();
if (player != null) {
// Until the demo app is fully migrated to TrackSelectionParameters, rely on ExoPlayer to use
// DefaultTrackSelector by default.
trackSelectionParameters =
(DefaultTrackSelector.Parameters) player.getTrackSelectionParameters();
}
}

Expand Down Expand Up @@ -438,23 +438,18 @@ public void onPlayerError(@NonNull PlaybackException error) {

@Override
@SuppressWarnings("ReferenceEquality")
public void onTracksChanged(
@NonNull TrackGroupArray trackGroups, @NonNull TrackSelectionArray trackSelections) {
public void onTracksInfoChanged(TracksInfo tracksInfo) {
updateButtonVisibility();
if (trackGroups != lastSeenTrackGroupArray) {
MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_VIDEO)
== MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
showToast(R.string.error_unsupported_video);
}
if (mappedTrackInfo.getTypeSupport(C.TRACK_TYPE_AUDIO)
== MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
showToast(R.string.error_unsupported_audio);
}
}
lastSeenTrackGroupArray = trackGroups;
if (tracksInfo == lastSeenTracksInfo) {
return;
}
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_VIDEO)) {
showToast(R.string.error_unsupported_video);
}
if (!tracksInfo.isTypeSupportedOrEmpty(C.TRACK_TYPE_AUDIO)) {
showToast(R.string.error_unsupported_audio);
}
lastSeenTracksInfo = tracksInfo;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
import com.google.android.exoplayer2.source.ads.AdsLoader.EventListener;
import com.google.android.exoplayer2.source.ads.AdsMediaSource.AdLoadException;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.trackselection.TrackSelectionUtil;
import com.google.android.exoplayer2.ui.AdOverlayInfo;
import com.google.android.exoplayer2.ui.AdViewProvider;
import com.google.android.exoplayer2.upstream.DataSpec;
Expand Down Expand Up @@ -706,8 +704,7 @@ private int getPlayerVolumePercent() {
}

// Check for a selected track using an audio renderer.
TrackSelectionArray trackSelections = player.getCurrentTrackSelections();
return TrackSelectionUtil.hasTrackOfType(trackSelections, C.TRACK_TYPE_AUDIO) ? 100 : 0;
return player.getCurrentTracksInfo().isTypeSelected(C.TRACK_TYPE_AUDIO) ? 100 : 0;
}

private void handleAdEvent(AdEvent adEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,13 @@ public boolean isSupported() {
/**
* Returns if a track in a {@link TrackGroup} is selected for playback.
*
* <p>Multiple tracks of a track group may be selected, in which case the the active one
* (currently playing) is undefined. This is common in adaptive streaming, where multiple tracks
* of different quality are selected and the active one changes depending on the network and the
* {@link TrackSelectionParameters}.
* <p>Multiple tracks of a track group may be selected. This is common in adaptive streaming,
* where multiple tracks of different quality are selected and the player switches between them
* depending on the network and the {@link TrackSelectionParameters}.
*
* <p>While this class doesn't provide which selected track is currently playing, some player
* implementations have ways of getting such information. For example ExoPlayer provides this
* information in {@code ExoTrackSelection.getSelectedFormat}.
*
* @param trackIndex The index of the track in the {@link TrackGroup}.
* @return true if the track is selected, false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,15 @@
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Timeline.Period;
import com.google.android.exoplayer2.TracksInfo;
import com.google.android.exoplayer2.analytics.PlaybackStats.EventTimeAndException;
import com.google.android.exoplayer2.analytics.PlaybackStats.EventTimeAndFormat;
import com.google.android.exoplayer2.analytics.PlaybackStats.EventTimeAndPlaybackState;
import com.google.android.exoplayer2.analytics.PlaybackStats.PlaybackState;
import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoSize;
import java.io.IOException;
Expand Down Expand Up @@ -523,23 +522,11 @@ public void onEvents(
hasFatalError = false;
}
if (isForeground && !isInterruptedByAd) {
boolean videoEnabled = false;
boolean audioEnabled = false;
for (TrackSelection trackSelection : player.getCurrentTrackSelections().getAll()) {
if (trackSelection != null && trackSelection.length() > 0) {
@C.TrackType
int trackType = MimeTypes.getTrackType(trackSelection.getFormat(0).sampleMimeType);
if (trackType == C.TRACK_TYPE_VIDEO) {
videoEnabled = true;
} else if (trackType == C.TRACK_TYPE_AUDIO) {
audioEnabled = true;
}
}
}
if (!videoEnabled) {
TracksInfo currentTracksInfo = player.getCurrentTracksInfo();
if (!currentTracksInfo.isTypeSelected(C.TRACK_TYPE_VIDEO)) {
maybeUpdateVideoFormat(eventTime, /* newFormat= */ null);
}
if (!audioEnabled) {
if (!currentTracksInfo.isTypeSelected(C.TRACK_TYPE_AUDIO)) {
maybeUpdateAudioFormat(eventTime, /* newFormat= */ null);
}
}
Expand Down
Loading

0 comments on commit 98ee159

Please sign in to comment.