2222import android .annotation .SuppressLint ;
2323import android .os .Handler ;
2424import android .os .Looper ;
25- import android .os .Message ;
2625import android .util .Pair ;
2726import androidx .annotation .Nullable ;
2827import com .google .android .exoplayer2 .PlayerMessage .Target ;
6766
6867 private final Renderer [] renderers ;
6968 private final TrackSelector trackSelector ;
70- private final PlaybackUpdateListenerImpl playbackUpdateListener ;
69+ private final Handler playbackInfoUpdateHandler ;
70+ private final ExoPlayerImplInternal .PlaybackInfoUpdateListener playbackInfoUpdateListener ;
7171 private final ExoPlayerImplInternal internalPlayer ;
7272 private final Handler internalPlayerHandler ;
7373 private final CopyOnWriteArrayList <ListenerHolder > listeners ;
8787 @ DiscontinuityReason private int pendingDiscontinuityReason ;
8888 @ PlayWhenReadyChangeReason private int pendingPlayWhenReadyChangeReason ;
8989 private boolean foregroundMode ;
90- private int pendingSetPlaybackSpeedAcks ;
91- private float playbackSpeed ;
9290 private SeekParameters seekParameters ;
9391 private ShuffleOrder shuffleOrder ;
9492 private boolean pauseAtEndOfMediaItems ;
@@ -155,9 +153,11 @@ public ExoPlayerImpl(
155153 new TrackSelection [renderers .length ],
156154 null );
157155 period = new Timeline .Period ();
158- playbackSpeed = Player .DEFAULT_PLAYBACK_SPEED ;
159156 maskingWindowIndex = C .INDEX_UNSET ;
160- playbackUpdateListener = new PlaybackUpdateListenerImpl (applicationLooper );
157+ playbackInfoUpdateHandler = new Handler (applicationLooper );
158+ playbackInfoUpdateListener =
159+ playbackInfoUpdate ->
160+ playbackInfoUpdateHandler .post (() -> handlePlaybackInfo (playbackInfoUpdate ));
161161 playbackInfo = PlaybackInfo .createDummy (emptyTrackSelectorResult );
162162 pendingListenerNotifications = new ArrayDeque <>();
163163 if (analyticsCollector != null ) {
@@ -179,7 +179,7 @@ public ExoPlayerImpl(
179179 pauseAtEndOfMediaItems ,
180180 applicationLooper ,
181181 clock ,
182- playbackUpdateListener );
182+ playbackInfoUpdateListener );
183183 internalPlayerHandler = new Handler (internalPlayer .getPlaybackLooper ());
184184 }
185185
@@ -595,7 +595,7 @@ public void seekTo(int windowIndex, long positionMs) {
595595 // general because the midroll ad preceding the seek destination must be played before the
596596 // content position can be played, if a different ad is playing at the moment.
597597 Log .w (TAG , "seekTo ignored because an ad is playing" );
598- playbackUpdateListener .onPlaybackInfoUpdate (
598+ playbackInfoUpdateListener .onPlaybackInfoUpdate (
599599 new ExoPlayerImplInternal .PlaybackInfoUpdate (playbackInfo ));
600600 return ;
601601 }
@@ -632,30 +632,30 @@ public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameter
632632 @ Deprecated
633633 @ Override
634634 public PlaybackParameters getPlaybackParameters () {
635- return new PlaybackParameters (playbackSpeed );
635+ return new PlaybackParameters (playbackInfo . playbackSpeed );
636636 }
637637
638- @ SuppressWarnings ("deprecation" )
639638 @ Override
640639 public void setPlaybackSpeed (float playbackSpeed ) {
641640 checkState (playbackSpeed > 0 );
642- if (this .playbackSpeed == playbackSpeed ) {
641+ if (playbackInfo .playbackSpeed == playbackSpeed ) {
643642 return ;
644643 }
645- pendingSetPlaybackSpeedAcks ++;
646- this .playbackSpeed = playbackSpeed ;
647- PlaybackParameters playbackParameters = new PlaybackParameters (playbackSpeed );
644+ PlaybackInfo newPlaybackInfo = playbackInfo .copyWithPlaybackSpeed (playbackSpeed );
645+ pendingOperationAcks ++;
648646 internalPlayer .setPlaybackSpeed (playbackSpeed );
649- notifyListeners (
650- listener -> {
651- listener .onPlaybackParametersChanged (playbackParameters );
652- listener .onPlaybackSpeedChanged (playbackSpeed );
653- });
647+ updatePlaybackInfo (
648+ newPlaybackInfo ,
649+ /* positionDiscontinuity= */ false ,
650+ /* ignored */ DISCONTINUITY_REASON_INTERNAL ,
651+ /* ignored */ TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED ,
652+ /* ignored */ PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST ,
653+ /* seekProcessed= */ false );
654654 }
655655
656656 @ Override
657657 public float getPlaybackSpeed () {
658- return playbackSpeed ;
658+ return playbackInfo . playbackSpeed ;
659659 }
660660
661661 @ Override
@@ -726,7 +726,7 @@ public void release() {
726726 ExoPlaybackException .createForUnexpected (
727727 new RuntimeException (new TimeoutException ("Player release timed out." )))));
728728 }
729- playbackUpdateListener . handler .removeCallbacksAndMessages (null );
729+ playbackInfoUpdateHandler .removeCallbacksAndMessages (null );
730730 if (analyticsCollector != null ) {
731731 bandwidthMeter .removeEventListener (analyticsCollector );
732732 }
@@ -896,23 +896,6 @@ private List<MediaSource> createMediaSources(List<MediaItem> mediaItems) {
896896 return mediaSources ;
897897 }
898898
899- @ SuppressWarnings ("deprecation" )
900- private void handlePlaybackSpeed (float playbackSpeed , boolean operationAck ) {
901- if (operationAck ) {
902- pendingSetPlaybackSpeedAcks --;
903- }
904- if (pendingSetPlaybackSpeedAcks == 0 ) {
905- if (this .playbackSpeed != playbackSpeed ) {
906- this .playbackSpeed = playbackSpeed ;
907- notifyListeners (
908- listener -> {
909- listener .onPlaybackParametersChanged (new PlaybackParameters (playbackSpeed ));
910- listener .onPlaybackSpeedChanged (playbackSpeed );
911- });
912- }
913- }
914- }
915-
916899 private void handlePlaybackInfo (ExoPlayerImplInternal .PlaybackInfoUpdate playbackInfoUpdate ) {
917900 pendingOperationAcks -= playbackInfoUpdate .operationAcks ;
918901 if (playbackInfoUpdate .positionDiscontinuity ) {
@@ -996,7 +979,7 @@ private Pair<Boolean, Integer> evaluateMediaItemTransitionReason(
996979 PlaybackInfo playbackInfo ,
997980 PlaybackInfo oldPlaybackInfo ,
998981 boolean positionDiscontinuity ,
999- int positionDiscontinuityReason ,
982+ @ DiscontinuityReason int positionDiscontinuityReason ,
1000983 boolean timelineChanged ) {
1001984
1002985 Timeline oldTimeline = oldPlaybackInfo .timeline ;
@@ -1360,49 +1343,6 @@ private long periodPositionUsToWindowPositionMs(MediaPeriodId periodId, long pos
13601343 return positionMs ;
13611344 }
13621345
1363- private final class PlaybackUpdateListenerImpl
1364- implements ExoPlayerImplInternal .PlaybackUpdateListener , Handler .Callback {
1365- private static final int MSG_PLAYBACK_INFO_CHANGED = 0 ;
1366- private static final int MSG_PLAYBACK_SPEED_CHANGED = 1 ;
1367-
1368- private final Handler handler ;
1369-
1370- private PlaybackUpdateListenerImpl (Looper applicationLooper ) {
1371- handler = Util .createHandler (applicationLooper , /* callback= */ this );
1372- }
1373-
1374- @ Override
1375- public void onPlaybackInfoUpdate (ExoPlayerImplInternal .PlaybackInfoUpdate playbackInfo ) {
1376- handler .obtainMessage (MSG_PLAYBACK_INFO_CHANGED , playbackInfo ).sendToTarget ();
1377- }
1378-
1379- @ Override
1380- public void onPlaybackSpeedChange (float playbackSpeed , boolean acknowledgeCommand ) {
1381- handler
1382- .obtainMessage (
1383- MSG_PLAYBACK_SPEED_CHANGED ,
1384- /* arg1= */ acknowledgeCommand ? 1 : 0 ,
1385- /* arg2= */ 0 ,
1386- /* obj= */ playbackSpeed )
1387- .sendToTarget ();
1388- }
1389-
1390- @ Override
1391- public boolean handleMessage (Message msg ) {
1392- switch (msg .what ) {
1393- case MSG_PLAYBACK_INFO_CHANGED :
1394- handlePlaybackInfo ((ExoPlayerImplInternal .PlaybackInfoUpdate ) msg .obj );
1395- break ;
1396- case MSG_PLAYBACK_SPEED_CHANGED :
1397- handlePlaybackSpeed ((Float ) msg .obj , /* operationAck= */ msg .arg1 != 0 );
1398- break ;
1399- default :
1400- throw new IllegalStateException ();
1401- }
1402- return true ;
1403- }
1404- }
1405-
14061346 private static final class PlaybackInfoUpdate implements Runnable {
14071347
14081348 private final PlaybackInfo playbackInfo ;
@@ -1424,6 +1364,7 @@ private static final class PlaybackInfoUpdate implements Runnable {
14241364 private final boolean playWhenReadyChanged ;
14251365 private final boolean playbackSuppressionReasonChanged ;
14261366 private final boolean isPlayingChanged ;
1367+ private final boolean playbackSpeedChanged ;
14271368
14281369 public PlaybackInfoUpdate (
14291370 PlaybackInfo playbackInfo ,
@@ -1461,6 +1402,7 @@ public PlaybackInfoUpdate(
14611402 playbackSuppressionReasonChanged =
14621403 previousPlaybackInfo .playbackSuppressionReason != playbackInfo .playbackSuppressionReason ;
14631404 isPlayingChanged = isPlaying (previousPlaybackInfo ) != isPlaying (playbackInfo );
1405+ playbackSpeedChanged = previousPlaybackInfo .playbackSpeed != playbackInfo .playbackSpeed ;
14641406 }
14651407
14661408 @ SuppressWarnings ("deprecation" )
@@ -1526,6 +1468,15 @@ public void run() {
15261468 invokeAll (
15271469 listenerSnapshot , listener -> listener .onIsPlayingChanged (isPlaying (playbackInfo )));
15281470 }
1471+ if (playbackSpeedChanged ) {
1472+ PlaybackParameters playbackParameters = new PlaybackParameters (playbackInfo .playbackSpeed );
1473+ invokeAll (
1474+ listenerSnapshot ,
1475+ listener -> {
1476+ listener .onPlaybackSpeedChanged (playbackInfo .playbackSpeed );
1477+ listener .onPlaybackParametersChanged (playbackParameters );
1478+ });
1479+ }
15291480 if (seekProcessed ) {
15301481 invokeAll (listenerSnapshot , EventListener ::onSeekProcessed );
15311482 }
0 commit comments