use of com.google.android.exoplayer2.Player.PositionInfo in project ExoPlayer by google.
the class CastPlayer method updateInternalStateAndNotifyIfChanged.
// Internal methods.
// Call deprecated callbacks.
@SuppressWarnings("deprecation")
private void updateInternalStateAndNotifyIfChanged() {
if (remoteMediaClient == null) {
// There is no session. We leave the state of the player as it is now.
return;
}
int oldWindowIndex = this.currentWindowIndex;
@Nullable Object oldPeriodUid = !getCurrentTimeline().isEmpty() ? getCurrentTimeline().getPeriod(oldWindowIndex, period, /* setIds= */
true).uid : null;
updatePlayerStateAndNotifyIfChanged(/* resultCallback= */
null);
updateRepeatModeAndNotifyIfChanged(/* resultCallback= */
null);
updatePlaybackRateAndNotifyIfChanged(/* resultCallback= */
null);
boolean playingPeriodChangedByTimelineChange = updateTimelineAndNotifyIfChanged();
Timeline currentTimeline = getCurrentTimeline();
currentWindowIndex = fetchCurrentWindowIndex(remoteMediaClient, currentTimeline);
@Nullable Object currentPeriodUid = !currentTimeline.isEmpty() ? currentTimeline.getPeriod(currentWindowIndex, period, /* setIds= */
true).uid : null;
if (!playingPeriodChangedByTimelineChange && !Util.areEqual(oldPeriodUid, currentPeriodUid) && pendingSeekCount == 0) {
// Report discontinuity and media item auto transition.
currentTimeline.getPeriod(oldWindowIndex, period, /* setIds= */
true);
currentTimeline.getWindow(oldWindowIndex, window);
long windowDurationMs = window.getDurationMs();
PositionInfo oldPosition = new PositionInfo(window.uid, period.windowIndex, window.mediaItem, period.uid, period.windowIndex, /* positionMs= */
windowDurationMs, /* contentPositionMs= */
windowDurationMs, /* adGroupIndex= */
C.INDEX_UNSET, /* adIndexInAdGroup= */
C.INDEX_UNSET);
currentTimeline.getPeriod(currentWindowIndex, period, /* setIds= */
true);
currentTimeline.getWindow(currentWindowIndex, window);
PositionInfo newPosition = new PositionInfo(window.uid, period.windowIndex, window.mediaItem, period.uid, period.windowIndex, /* positionMs= */
window.getDefaultPositionMs(), /* contentPositionMs= */
window.getDefaultPositionMs(), /* adGroupIndex= */
C.INDEX_UNSET, /* adIndexInAdGroup= */
C.INDEX_UNSET);
listeners.queueEvent(Player.EVENT_POSITION_DISCONTINUITY, listener -> {
listener.onPositionDiscontinuity(DISCONTINUITY_REASON_AUTO_TRANSITION);
listener.onPositionDiscontinuity(oldPosition, newPosition, DISCONTINUITY_REASON_AUTO_TRANSITION);
});
listeners.queueEvent(Player.EVENT_MEDIA_ITEM_TRANSITION, listener -> listener.onMediaItemTransition(getCurrentMediaItem(), MEDIA_ITEM_TRANSITION_REASON_AUTO));
}
if (updateTracksAndSelectionsAndNotifyIfChanged()) {
listeners.queueEvent(Player.EVENT_TRACKS_CHANGED, listener -> listener.onTracksChanged(currentTrackGroups, currentTrackSelection));
listeners.queueEvent(Player.EVENT_TRACKS_CHANGED, listener -> listener.onTracksInfoChanged(currentTracksInfo));
}
updateAvailableCommandsAndNotifyIfChanged();
listeners.flushEvents();
}
use of com.google.android.exoplayer2.Player.PositionInfo in project ExoPlayer by google.
the class CastPlayer method updateTimelineAndNotifyIfChanged.
/**
* Updates the timeline and notifies {@link Player.Listener event listeners} if required.
*
* @return Whether the timeline change has caused a change of the period currently being played.
*/
// Calling deprecated listener method.
@SuppressWarnings("deprecation")
private boolean updateTimelineAndNotifyIfChanged() {
Timeline oldTimeline = currentTimeline;
int oldWindowIndex = currentWindowIndex;
boolean playingPeriodChanged = false;
if (updateTimeline()) {
// TODO: Differentiate TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED and
// TIMELINE_CHANGE_REASON_SOURCE_UPDATE [see internal: b/65152553].
Timeline timeline = currentTimeline;
// Call onTimelineChanged.
listeners.queueEvent(Player.EVENT_TIMELINE_CHANGED, listener -> listener.onTimelineChanged(timeline, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE));
// Call onPositionDiscontinuity if required.
Timeline currentTimeline = getCurrentTimeline();
boolean playingPeriodRemoved = false;
if (!oldTimeline.isEmpty()) {
Object oldPeriodUid = castNonNull(oldTimeline.getPeriod(oldWindowIndex, period, /* setIds= */
true).uid);
playingPeriodRemoved = currentTimeline.getIndexOfPeriod(oldPeriodUid) == C.INDEX_UNSET;
}
if (playingPeriodRemoved) {
PositionInfo oldPosition;
if (pendingMediaItemRemovalPosition != null) {
oldPosition = pendingMediaItemRemovalPosition;
pendingMediaItemRemovalPosition = null;
} else {
// If the media item has been removed by another client, we don't know the removal
// position. We use the current position as a fallback.
oldTimeline.getPeriod(oldWindowIndex, period, /* setIds= */
true);
oldTimeline.getWindow(period.windowIndex, window);
oldPosition = new PositionInfo(window.uid, period.windowIndex, window.mediaItem, period.uid, period.windowIndex, getCurrentPosition(), getContentPosition(), /* adGroupIndex= */
C.INDEX_UNSET, /* adIndexInAdGroup= */
C.INDEX_UNSET);
}
PositionInfo newPosition = getCurrentPositionInfo();
listeners.queueEvent(Player.EVENT_POSITION_DISCONTINUITY, listener -> {
listener.onPositionDiscontinuity(DISCONTINUITY_REASON_REMOVE);
listener.onPositionDiscontinuity(oldPosition, newPosition, DISCONTINUITY_REASON_REMOVE);
});
}
// Call onMediaItemTransition if required.
playingPeriodChanged = currentTimeline.isEmpty() != oldTimeline.isEmpty() || playingPeriodRemoved;
if (playingPeriodChanged) {
listeners.queueEvent(Player.EVENT_MEDIA_ITEM_TRANSITION, listener -> listener.onMediaItemTransition(getCurrentMediaItem(), MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED));
}
updateAvailableCommandsAndNotifyIfChanged();
}
return playingPeriodChanged;
}
use of com.google.android.exoplayer2.Player.PositionInfo in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_beyondSSAIMidRolls_seekAdjustedAndRequestedContentPositionKept.
@Test
public void seekTo_beyondSSAIMidRolls_seekAdjustedAndRequestedContentPositionKept() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
0, /* isAdPeriodFlags...= */
false, true, true, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(/* positionMs= */
4000);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(6)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1, 2, 0, 0, 0, 0).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek discontinuities
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).periodIndex).isEqualTo(3);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).positionMs).isEqualTo(4000);
// seek adjustment
assertThat(oldPositions.get(1).periodIndex).isEqualTo(3);
assertThat(oldPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(1).positionMs).isEqualTo(4000);
assertThat(newPositions.get(1).periodIndex).isEqualTo(1);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(1).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(4000);
// auto transition from ad to end of period
assertThat(oldPositions.get(2).periodIndex).isEqualTo(1);
assertThat(oldPositions.get(2).adGroupIndex).isEqualTo(0);
assertThat(oldPositions.get(2).adIndexInAdGroup).isEqualTo(0);
assertThat(oldPositions.get(2).positionMs).isEqualTo(2500);
assertThat(oldPositions.get(2).contentPositionMs).isEqualTo(4000);
assertThat(newPositions.get(2).periodIndex).isEqualTo(1);
assertThat(newPositions.get(2).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(2).positionMs).isEqualTo(2500);
// auto transition to next ad period
assertThat(oldPositions.get(3).periodIndex).isEqualTo(1);
assertThat(oldPositions.get(3).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(3).periodIndex).isEqualTo(2);
assertThat(newPositions.get(3).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(3).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(3).contentPositionMs).isEqualTo(4000);
// auto transition from ad to end of period
assertThat(oldPositions.get(4).periodIndex).isEqualTo(2);
assertThat(oldPositions.get(4).adGroupIndex).isEqualTo(0);
assertThat(oldPositions.get(4).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(4).periodIndex).isEqualTo(2);
assertThat(newPositions.get(4).adGroupIndex).isEqualTo(-1);
// auto transition to final content period with seek position
assertThat(oldPositions.get(5).periodIndex).isEqualTo(2);
assertThat(oldPositions.get(5).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(5).periodIndex).isEqualTo(3);
assertThat(newPositions.get(5).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(5).contentPositionMs).isEqualTo(4000);
}
use of com.google.android.exoplayer2.Player.PositionInfo in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_toPlayedSAIMidRolls_requestedContentPositionNotPropagatedIntoAds.
@Test
public void seekTo_toPlayedSAIMidRolls_requestedContentPositionNotPropagatedIntoAds() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
2, /* isAdPeriodFlags...= */
false, true, true, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(2500);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(1)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek discontinuity
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
// TODO(bachinger): Incorrect masking. Skipped played prerolls not taken into account by masking
assertThat(newPositions.get(0).periodIndex).isEqualTo(1);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
}
use of com.google.android.exoplayer2.Player.PositionInfo in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_beyondSSAIMidRollsConsecutiveContentPeriods_seekAdjusted.
@Test
public void seekTo_beyondSSAIMidRollsConsecutiveContentPeriods_seekAdjusted() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
0, /* isAdPeriodFlags...= */
false, true, false, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(/* positionMs= */
7000);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(5)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1, 2, 0, 0, 0).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).periodIndex).isEqualTo(3);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).positionMs).isEqualTo(7000);
// seek adjustment
assertThat(oldPositions.get(1).periodIndex).isEqualTo(3);
assertThat(oldPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(1).positionMs).isEqualTo(7000);
assertThat(newPositions.get(1).periodIndex).isEqualTo(1);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
}
Aggregations