use of androidx.media3.common.IllegalSeekPositionException in project media by androidx.
the class ExoPlayerImpl method seekTo.
@Override
public void seekTo(int mediaItemIndex, long positionMs) {
verifyApplicationThread();
analyticsCollector.notifySeekStarted();
Timeline timeline = playbackInfo.timeline;
if (mediaItemIndex < 0 || (!timeline.isEmpty() && mediaItemIndex >= timeline.getWindowCount())) {
throw new IllegalSeekPositionException(timeline, mediaItemIndex, positionMs);
}
pendingOperationAcks++;
if (isPlayingAd()) {
// TODO: Investigate adding support for seeking during ads. This is complicated to do in
// general because the midroll ad preceding the seek destination must be played before the
// content position can be played, if a different ad is playing at the moment.
Log.w(TAG, "seekTo ignored because an ad is playing");
ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfoUpdate = new ExoPlayerImplInternal.PlaybackInfoUpdate(this.playbackInfo);
playbackInfoUpdate.incrementPendingOperationAcks(1);
playbackInfoUpdateListener.onPlaybackInfoUpdate(playbackInfoUpdate);
return;
}
@Player.State int newPlaybackState = getPlaybackState() == Player.STATE_IDLE ? Player.STATE_IDLE : STATE_BUFFERING;
int oldMaskingMediaItemIndex = getCurrentMediaItemIndex();
PlaybackInfo newPlaybackInfo = playbackInfo.copyWithPlaybackState(newPlaybackState);
newPlaybackInfo = maskTimelineAndPosition(newPlaybackInfo, timeline, maskWindowPositionMsOrGetPeriodPositionUs(timeline, mediaItemIndex, positionMs));
internalPlayer.seekTo(timeline, mediaItemIndex, Util.msToUs(positionMs));
updatePlaybackInfo(newPlaybackInfo, /* ignored */
TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, /* ignored */
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST, /* seekProcessed= */
true, /* positionDiscontinuity= */
true, /* positionDiscontinuityReason= */
DISCONTINUITY_REASON_SEEK, /* discontinuityWindowStartPositionUs= */
getCurrentPositionUsInternal(newPlaybackInfo), oldMaskingMediaItemIndex);
}
use of androidx.media3.common.IllegalSeekPositionException in project media by androidx.
the class MediaControllerImplBase method setMediaItemsInternal.
private void setMediaItemsInternal(List<MediaItem> mediaItems, int startIndex, long startPositionMs, boolean resetToDefaultPosition) {
List<Window> windows = new ArrayList<>();
List<Period> periods = new ArrayList<>();
for (int i = 0; i < mediaItems.size(); i++) {
windows.add(MediaUtils.convertToWindow(mediaItems.get(i), i));
periods.add(MediaUtils.convertToPeriod(i));
}
Timeline newTimeline = createMaskingTimeline(windows, periods);
if (!newTimeline.isEmpty() && startIndex >= newTimeline.getWindowCount()) {
throw new IllegalSeekPositionException(newTimeline, startIndex, startPositionMs);
}
if (resetToDefaultPosition) {
startIndex = newTimeline.getFirstWindowIndex(playerInfo.shuffleModeEnabled);
startPositionMs = C.TIME_UNSET;
} else if (startIndex == C.INDEX_UNSET) {
startIndex = playerInfo.sessionPositionInfo.positionInfo.mediaItemIndex;
startPositionMs = playerInfo.sessionPositionInfo.positionInfo.positionMs;
}
PositionInfo newPositionInfo;
SessionPositionInfo newSessionPositionInfo;
@Nullable PeriodInfo periodInfo = getPeriodInfo(newTimeline, startIndex, startPositionMs);
if (periodInfo == null) {
// Timeline is empty.
newPositionInfo = new PositionInfo(/* windowUid= */
null, startIndex, /* mediaItem= */
null, /* periodUid= */
null, /* periodIndex= */
0, /* positionMs= */
startPositionMs == C.TIME_UNSET ? 0 : startPositionMs, /* contentPositionMs= */
startPositionMs == C.TIME_UNSET ? 0 : startPositionMs, /* adGroupIndex= */
C.INDEX_UNSET, /* adIndexInAdGroup= */
C.INDEX_UNSET);
newSessionPositionInfo = new SessionPositionInfo(newPositionInfo, /* isPlayingAd= */
false, /* eventTimeMs= */
SystemClock.elapsedRealtime(), /* durationMs= */
C.TIME_UNSET, /* bufferedPositionMs= */
startPositionMs == C.TIME_UNSET ? 0 : startPositionMs, /* bufferedPercentage= */
0, /* totalBufferedDurationMs= */
0, /* currentLiveOffsetMs= */
C.TIME_UNSET, /* contentDurationMs= */
C.TIME_UNSET, /* contentBufferedPositionMs= */
startPositionMs == C.TIME_UNSET ? 0 : startPositionMs);
} else {
newPositionInfo = new PositionInfo(/* windowUid= */
null, startIndex, mediaItems.get(startIndex), /* periodUid= */
null, periodInfo.index, /* positionMs= */
usToMs(periodInfo.periodPositionUs), /* contentPositionMs= */
usToMs(periodInfo.periodPositionUs), /* adGroupIndex= */
C.INDEX_UNSET, /* adIndexInAdGroup= */
C.INDEX_UNSET);
newSessionPositionInfo = new SessionPositionInfo(newPositionInfo, /* isPlayingAd= */
false, /* eventTimeMs= */
SystemClock.elapsedRealtime(), /* durationMs= */
C.TIME_UNSET, /* bufferedPositionMs= */
usToMs(periodInfo.periodPositionUs), /* bufferedPercentage= */
0, /* totalBufferedDurationMs= */
0, /* currentLiveOffsetMs= */
C.TIME_UNSET, /* contentDurationMs= */
C.TIME_UNSET, /* contentBufferedPositionMs= */
usToMs(periodInfo.periodPositionUs));
}
PlayerInfo newPlayerInfo = maskTimelineAndPositionInfo(playerInfo, newTimeline, newPositionInfo, newSessionPositionInfo, DISCONTINUITY_REASON_REMOVE);
// Mask the playback state.
int maskingPlaybackState = newPlayerInfo.playbackState;
if (startIndex != C.INDEX_UNSET && newPlayerInfo.playbackState != STATE_IDLE) {
if (newTimeline.isEmpty() || startIndex >= newTimeline.getWindowCount()) {
// Setting an empty timeline or invalid seek transitions to ended.
maskingPlaybackState = STATE_ENDED;
} else {
maskingPlaybackState = STATE_BUFFERING;
}
}
newPlayerInfo = newPlayerInfo.copyWithPlaybackState(maskingPlaybackState, playerInfo.playerError);
updatePlayerInfo(newPlayerInfo, /* timelineChangeReason= */
TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, /* ignored */
PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST, /* positionDiscontinuity= */
!playerInfo.timeline.isEmpty(), DISCONTINUITY_REASON_REMOVE, /* mediaItemTransition= */
!playerInfo.timeline.isEmpty() || !newPlayerInfo.timeline.isEmpty(), MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED);
}
Aggregations