Add dispatchPrepare(player) to ControlDispatcher
Issue: #7882 PiperOrigin-RevId: 341394254
This commit is contained in:
parent
1d4321b86e
commit
b03df4e8b5
@ -29,6 +29,13 @@
|
||||
* UI:
|
||||
* Show overflow button in `StyledPlayerControlView` only when there is not
|
||||
enough space.
|
||||
* Add `dispatchPrepare(Player)` to `ControlDispatcher` and implement it in
|
||||
`DefaultControlDispatcher`. Deprecate `PlaybackPreparer` and
|
||||
`setPlaybackPreparer` in `StyledPlayerView`, `StyledPlayerControlView`,
|
||||
`PlayerView`, `PlayerControlView`, `PlayerNotificationManager` and
|
||||
`LeanbackPlayerAdapter` and use `ControlDispatcher` for dispatching
|
||||
prepare instead
|
||||
([#7882](https://github.com/google/ExoPlayer/issues/7882)).
|
||||
* Audio:
|
||||
* Retry playback after some types of `AudioTrack` error.
|
||||
* Extractors:
|
||||
|
@ -34,7 +34,6 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.PlaybackPreparer;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.RenderersFactory;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
@ -68,7 +67,7 @@ import java.util.List;
|
||||
|
||||
/** An activity that plays media using {@link SimpleExoPlayer}. */
|
||||
public class PlayerActivity extends AppCompatActivity
|
||||
implements OnClickListener, PlaybackPreparer, StyledPlayerControlView.VisibilityListener {
|
||||
implements OnClickListener, StyledPlayerControlView.VisibilityListener {
|
||||
|
||||
// Saved instance state keys.
|
||||
|
||||
@ -250,13 +249,6 @@ public class PlayerActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
// PlaybackPreparer implementation
|
||||
|
||||
@Override
|
||||
public void preparePlayback() {
|
||||
player.prepare();
|
||||
}
|
||||
|
||||
// PlayerControlView.VisibilityListener implementation
|
||||
|
||||
@Override
|
||||
@ -302,7 +294,6 @@ public class PlayerActivity extends AppCompatActivity
|
||||
player.setAudioAttributes(AudioAttributes.DEFAULT, /* handleAudioFocus= */ true);
|
||||
player.setPlayWhenReady(startAutoPlay);
|
||||
playerView.setPlayer(player);
|
||||
playerView.setPlaybackPreparer(this);
|
||||
debugViewHelper = new DebugTextViewHelper(player, debugTextView);
|
||||
debugViewHelper.start();
|
||||
}
|
||||
|
@ -78,10 +78,15 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PlaybackPreparer}.
|
||||
*
|
||||
* @param playbackPreparer The {@link PlaybackPreparer}.
|
||||
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} instead. The adapter calls
|
||||
* {@link ControlDispatcher#dispatchPrepare(Player)} instead of {@link
|
||||
* PlaybackPreparer#preparePlayback()}. The {@link DefaultControlDispatcher} that the adapter
|
||||
* uses by default, calls {@link Player#prepare()}. If you wish to customize this behaviour,
|
||||
* you can provide a custom implementation of {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void setPlaybackPreparer(@Nullable PlaybackPreparer playbackPreparer) {
|
||||
this.playbackPreparer = playbackPreparer;
|
||||
}
|
||||
@ -167,11 +172,15 @@ public final class LeanbackPlayerAdapter extends PlayerAdapter implements Runnab
|
||||
return player.getPlaybackState() == Player.STATE_IDLE ? -1 : player.getCurrentPosition();
|
||||
}
|
||||
|
||||
// Calls deprecated method to provide backwards compatibility.
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void play() {
|
||||
if (player.getPlaybackState() == Player.STATE_IDLE) {
|
||||
if (playbackPreparer != null) {
|
||||
playbackPreparer.preparePlayback();
|
||||
} else {
|
||||
controlDispatcher.dispatchPrepare(player);
|
||||
}
|
||||
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
|
||||
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
|
||||
|
@ -1147,6 +1147,8 @@ public final class MediaSessionConnector {
|
||||
if (player.getPlaybackState() == Player.STATE_IDLE) {
|
||||
if (playbackPreparer != null) {
|
||||
playbackPreparer.onPrepare(/* playWhenReady= */ true);
|
||||
} else {
|
||||
controlDispatcher.dispatchPrepare(player);
|
||||
}
|
||||
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
|
||||
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
|
||||
|
@ -26,6 +26,14 @@ import com.google.android.exoplayer2.Player.RepeatMode;
|
||||
*/
|
||||
public interface ControlDispatcher {
|
||||
|
||||
/**
|
||||
* Dispatches a {@link Player#prepare()} operation.
|
||||
*
|
||||
* @param player The {@link Player} to which the operation should be dispatched.
|
||||
* @return True if the operation was dispatched. False if suppressed.
|
||||
*/
|
||||
boolean dispatchPrepare(Player player);
|
||||
|
||||
/**
|
||||
* Dispatches a {@link Player#setPlayWhenReady(boolean)} operation.
|
||||
*
|
||||
|
@ -52,6 +52,12 @@ public class DefaultControlDispatcher implements ControlDispatcher {
|
||||
window = new Timeline.Window();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchPrepare(Player player) {
|
||||
player.prepare();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchSetPlayWhenReady(Player player, boolean playWhenReady) {
|
||||
player.setPlayWhenReady(playWhenReady);
|
||||
|
@ -15,9 +15,11 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2;
|
||||
|
||||
/** Called to prepare a playback. */
|
||||
/** @deprecated Use {@link ControlDispatcher} instead. */
|
||||
@Deprecated
|
||||
public interface PlaybackPreparer {
|
||||
|
||||
/** Called to prepare a playback. */
|
||||
/** @deprecated Use {@link ControlDispatcher#dispatchPrepare(Player)} instead. */
|
||||
@Deprecated
|
||||
void preparePlayback();
|
||||
}
|
||||
|
@ -611,11 +611,15 @@ public class PlayerControlView extends FrameLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PlaybackPreparer}.
|
||||
*
|
||||
* @param playbackPreparer The {@link PlaybackPreparer}, or null to remove the current playback
|
||||
* preparer.
|
||||
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} instead. The view calls {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)} instead of {@link
|
||||
* PlaybackPreparer#preparePlayback()}. The {@link DefaultControlDispatcher} that the view
|
||||
* uses by default, calls {@link Player#prepare()}. If you wish to customize this behaviour,
|
||||
* you can provide a custom implementation of {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void setPlaybackPreparer(@Nullable PlaybackPreparer playbackPreparer) {
|
||||
this.playbackPreparer = playbackPreparer;
|
||||
}
|
||||
@ -1254,11 +1258,14 @@ public class PlayerControlView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void dispatchPlay(Player player) {
|
||||
@State int state = player.getPlaybackState();
|
||||
if (state == Player.STATE_IDLE) {
|
||||
if (playbackPreparer != null) {
|
||||
playbackPreparer.preparePlayback();
|
||||
} else {
|
||||
controlDispatcher.dispatchPrepare(player);
|
||||
}
|
||||
} else if (state == Player.STATE_ENDED) {
|
||||
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
|
||||
|
@ -682,10 +682,16 @@ public class PlayerNotificationManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PlaybackPreparer}.
|
||||
*
|
||||
* @param playbackPreparer The {@link PlaybackPreparer}.
|
||||
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} instead. The manager calls
|
||||
* {@link ControlDispatcher#dispatchPrepare(Player)} instead of {@link
|
||||
* PlaybackPreparer#preparePlayback()}. The {@link DefaultControlDispatcher} that this manager
|
||||
* uses by default, calls {@link Player#prepare()}. If you wish to intercept or customize this
|
||||
* behaviour, you can provide a custom implementation of {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)} and pass it to {@link
|
||||
* #setControlDispatcher(ControlDispatcher)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void setPlaybackPreparer(@Nullable PlaybackPreparer playbackPreparer) {
|
||||
this.playbackPreparer = playbackPreparer;
|
||||
}
|
||||
@ -1039,8 +1045,7 @@ public class PlayerNotificationManager {
|
||||
@Nullable NotificationCompat.Builder builder,
|
||||
boolean ongoing,
|
||||
@Nullable Bitmap largeIcon) {
|
||||
if (player.getPlaybackState() == Player.STATE_IDLE
|
||||
&& (player.getCurrentTimeline().isEmpty() || playbackPreparer == null)) {
|
||||
if (player.getPlaybackState() == Player.STATE_IDLE && player.getCurrentTimeline().isEmpty()) {
|
||||
builderActions = null;
|
||||
return null;
|
||||
}
|
||||
@ -1369,6 +1374,7 @@ public class PlayerNotificationManager {
|
||||
|
||||
private class NotificationBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Player player = PlayerNotificationManager.this.player;
|
||||
@ -1382,6 +1388,8 @@ public class PlayerNotificationManager {
|
||||
if (player.getPlaybackState() == Player.STATE_IDLE) {
|
||||
if (playbackPreparer != null) {
|
||||
playbackPreparer.preparePlayback();
|
||||
} else {
|
||||
controlDispatcher.dispatchPrepare(player);
|
||||
}
|
||||
} else if (player.getPlaybackState() == Player.STATE_ENDED) {
|
||||
controlDispatcher.dispatchSeekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
|
||||
|
@ -982,11 +982,15 @@ public class PlayerView extends FrameLayout implements AdsLoader.AdViewProvider
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PlaybackPreparer}.
|
||||
*
|
||||
* @param playbackPreparer The {@link PlaybackPreparer}, or null to remove the current playback
|
||||
* preparer.
|
||||
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} instead. The view calls {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)} instead of {@link
|
||||
* PlaybackPreparer#preparePlayback()}. The {@link DefaultControlDispatcher} that the view
|
||||
* uses by default, calls {@link Player#prepare()}. If you wish to customize this behaviour,
|
||||
* you can provide a custom implementation of {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void setPlaybackPreparer(@Nullable PlaybackPreparer playbackPreparer) {
|
||||
Assertions.checkStateNotNull(controller);
|
||||
controller.setPlaybackPreparer(playbackPreparer);
|
||||
|
@ -834,11 +834,15 @@ public class StyledPlayerControlView extends FrameLayout {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PlaybackPreparer}.
|
||||
*
|
||||
* @param playbackPreparer The {@link PlaybackPreparer}, or null to remove the current playback
|
||||
* preparer.
|
||||
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} instead. The view calls {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)} instead of {@link
|
||||
* PlaybackPreparer#preparePlayback()}. The {@link DefaultControlDispatcher} that the view
|
||||
* uses by default, calls {@link Player#prepare()}. If you wish to customize this behaviour,
|
||||
* you can provide a custom implementation of {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void setPlaybackPreparer(@Nullable PlaybackPreparer playbackPreparer) {
|
||||
this.playbackPreparer = playbackPreparer;
|
||||
}
|
||||
@ -1698,11 +1702,14 @@ public class StyledPlayerControlView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void dispatchPlay(Player player) {
|
||||
@State int state = player.getPlaybackState();
|
||||
if (state == Player.STATE_IDLE) {
|
||||
if (playbackPreparer != null) {
|
||||
playbackPreparer.preparePlayback();
|
||||
} else {
|
||||
controlDispatcher.dispatchPrepare(player);
|
||||
}
|
||||
} else if (state == Player.STATE_ENDED) {
|
||||
seekTo(player, player.getCurrentWindowIndex(), C.TIME_UNSET);
|
||||
|
@ -45,6 +45,7 @@ import androidx.annotation.RequiresApi;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ControlDispatcher;
|
||||
import com.google.android.exoplayer2.DefaultControlDispatcher;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.PlaybackPreparer;
|
||||
import com.google.android.exoplayer2.Player;
|
||||
@ -977,11 +978,15 @@ public class StyledPlayerView extends FrameLayout implements AdsLoader.AdViewPro
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PlaybackPreparer}.
|
||||
*
|
||||
* @param playbackPreparer The {@link PlaybackPreparer}, or null to remove the current playback
|
||||
* preparer.
|
||||
* @deprecated Use {@link #setControlDispatcher(ControlDispatcher)} instead. The view calls {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)} instead of {@link
|
||||
* PlaybackPreparer#preparePlayback()}. The {@link DefaultControlDispatcher} that the view
|
||||
* uses by default, calls {@link Player#prepare()}. If you wish to customize this behaviour,
|
||||
* you can provide a custom implementation of {@link
|
||||
* ControlDispatcher#dispatchPrepare(Player)}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public void setPlaybackPreparer(@Nullable PlaybackPreparer playbackPreparer) {
|
||||
Assertions.checkStateNotNull(controller);
|
||||
controller.setPlaybackPreparer(playbackPreparer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user