Search in sources :

Example 6 with IllegalSeekPositionException

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);
}
Also used : Timeline(androidx.media3.common.Timeline) SuppressLint(android.annotation.SuppressLint) IllegalSeekPositionException(androidx.media3.common.IllegalSeekPositionException)

Example 7 with IllegalSeekPositionException

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);
}
Also used : Window(androidx.media3.common.Timeline.Window) ArrayList(java.util.ArrayList) Period(androidx.media3.common.Timeline.Period) IllegalSeekPositionException(androidx.media3.common.IllegalSeekPositionException) Timeline(androidx.media3.common.Timeline) RemotableTimeline(androidx.media3.common.Timeline.RemotableTimeline) PositionInfo(androidx.media3.common.Player.PositionInfo) Nullable(androidx.annotation.Nullable)

Aggregations

IllegalSeekPositionException (androidx.media3.common.IllegalSeekPositionException)6 Timeline (androidx.media3.common.Timeline)6 Nullable (androidx.annotation.Nullable)4 PositionInfo (androidx.media3.common.Player.PositionInfo)3 SuppressLint (android.annotation.SuppressLint)2 RemotableTimeline (androidx.media3.common.Timeline.RemotableTimeline)2 Window (androidx.media3.common.Timeline.Window)2 DiscontinuityReason (androidx.media3.common.Player.DiscontinuityReason)1 MediaItemTransitionReason (androidx.media3.common.Player.MediaItemTransitionReason)1 Period (androidx.media3.common.Timeline.Period)1 ActionSchedule (androidx.media3.test.utils.ActionSchedule)1 PlayerRunnable (androidx.media3.test.utils.ActionSchedule.PlayerRunnable)1 ExoPlayerTestRunner (androidx.media3.test.utils.ExoPlayerTestRunner)1 TestExoPlayerBuilder (androidx.media3.test.utils.TestExoPlayerBuilder)1 ArrayList (java.util.ArrayList)1 Test (org.junit.Test)1