Search in sources :

Example 16 with MediaPeriodId

use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.

the class ExoPlayerImplInternal method seekToCurrentPosition.

private void seekToCurrentPosition(boolean sendDiscontinuity) throws ExoPlaybackException {
    // Renderers may have read from a period that's been removed. Seek back to the current
    // position of the playing period to make sure none of the removed period is played.
    MediaPeriodId periodId = queue.getPlayingPeriod().info.id;
    long newPositionUs = seekToPeriodPosition(periodId, playbackInfo.positionUs, /* forceDisableRenderers= */
    true, /* forceBufferingState= */
    false);
    if (newPositionUs != playbackInfo.positionUs) {
        playbackInfo = handlePositionDiscontinuity(periodId, newPositionUs, playbackInfo.requestedContentPositionUs, playbackInfo.discontinuityStartPositionUs, sendDiscontinuity, Player.DISCONTINUITY_REASON_INTERNAL);
    }
}
Also used : MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)

Example 17 with MediaPeriodId

use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.

the class ExoPlayerImpl method maskTimelineAndPosition.

private PlaybackInfo maskTimelineAndPosition(PlaybackInfo playbackInfo, Timeline timeline, @Nullable Pair<Object, Long> periodPositionUs) {
    Assertions.checkArgument(timeline.isEmpty() || periodPositionUs != null);
    Timeline oldTimeline = playbackInfo.timeline;
    // Mask the timeline.
    playbackInfo = playbackInfo.copyWithTimeline(timeline);
    if (timeline.isEmpty()) {
        // Reset periodId and loadingPeriodId.
        MediaPeriodId dummyMediaPeriodId = PlaybackInfo.getDummyPeriodForEmptyTimeline();
        long positionUs = Util.msToUs(maskingWindowPositionMs);
        playbackInfo = playbackInfo.copyWithNewPosition(dummyMediaPeriodId, positionUs, /* requestedContentPositionUs= */
        positionUs, /* discontinuityStartPositionUs= */
        positionUs, /* totalBufferedDurationUs= */
        0, TrackGroupArray.EMPTY, emptyTrackSelectorResult, /* staticMetadata= */
        ImmutableList.of());
        playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(dummyMediaPeriodId);
        playbackInfo.bufferedPositionUs = playbackInfo.positionUs;
        return playbackInfo;
    }
    Object oldPeriodUid = playbackInfo.periodId.periodUid;
    boolean playingPeriodChanged = !oldPeriodUid.equals(castNonNull(periodPositionUs).first);
    MediaPeriodId newPeriodId = playingPeriodChanged ? new MediaPeriodId(periodPositionUs.first) : playbackInfo.periodId;
    long newContentPositionUs = periodPositionUs.second;
    long oldContentPositionUs = Util.msToUs(getContentPosition());
    if (!oldTimeline.isEmpty()) {
        oldContentPositionUs -= oldTimeline.getPeriodByUid(oldPeriodUid, period).getPositionInWindowUs();
    }
    if (playingPeriodChanged || newContentPositionUs < oldContentPositionUs) {
        checkState(!newPeriodId.isAd());
        // The playing period changes or a backwards seek within the playing period occurs.
        playbackInfo = playbackInfo.copyWithNewPosition(newPeriodId, /* positionUs= */
        newContentPositionUs, /* requestedContentPositionUs= */
        newContentPositionUs, /* discontinuityStartPositionUs= */
        newContentPositionUs, /* totalBufferedDurationUs= */
        0, playingPeriodChanged ? TrackGroupArray.EMPTY : playbackInfo.trackGroups, playingPeriodChanged ? emptyTrackSelectorResult : playbackInfo.trackSelectorResult, playingPeriodChanged ? ImmutableList.of() : playbackInfo.staticMetadata);
        playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(newPeriodId);
        playbackInfo.bufferedPositionUs = newContentPositionUs;
    } else if (newContentPositionUs == oldContentPositionUs) {
        // Period position remains unchanged.
        int loadingPeriodIndex = timeline.getIndexOfPeriod(playbackInfo.loadingMediaPeriodId.periodUid);
        if (loadingPeriodIndex == C.INDEX_UNSET || timeline.getPeriod(loadingPeriodIndex, period).windowIndex != timeline.getPeriodByUid(newPeriodId.periodUid, period).windowIndex) {
            // Discard periods after the playing period, if the loading period is discarded or the
            // playing and loading period are not in the same window.
            timeline.getPeriodByUid(newPeriodId.periodUid, period);
            long maskedBufferedPositionUs = newPeriodId.isAd() ? period.getAdDurationUs(newPeriodId.adGroupIndex, newPeriodId.adIndexInAdGroup) : period.durationUs;
            playbackInfo = playbackInfo.copyWithNewPosition(newPeriodId, /* positionUs= */
            playbackInfo.positionUs, /* requestedContentPositionUs= */
            playbackInfo.positionUs, playbackInfo.discontinuityStartPositionUs, /* totalBufferedDurationUs= */
            maskedBufferedPositionUs - playbackInfo.positionUs, playbackInfo.trackGroups, playbackInfo.trackSelectorResult, playbackInfo.staticMetadata);
            playbackInfo = playbackInfo.copyWithLoadingMediaPeriodId(newPeriodId);
            playbackInfo.bufferedPositionUs = maskedBufferedPositionUs;
        }
    } else {
        checkState(!newPeriodId.isAd());
        // A forward seek within the playing period (timeline did not change).
        long maskedTotalBufferedDurationUs = max(0, playbackInfo.totalBufferedDurationUs - (newContentPositionUs - oldContentPositionUs));
        long maskedBufferedPositionUs = playbackInfo.bufferedPositionUs;
        if (playbackInfo.loadingMediaPeriodId.equals(playbackInfo.periodId)) {
            maskedBufferedPositionUs = newContentPositionUs + maskedTotalBufferedDurationUs;
        }
        playbackInfo = playbackInfo.copyWithNewPosition(newPeriodId, /* positionUs= */
        newContentPositionUs, /* requestedContentPositionUs= */
        newContentPositionUs, /* discontinuityStartPositionUs= */
        newContentPositionUs, maskedTotalBufferedDurationUs, playbackInfo.trackGroups, playbackInfo.trackSelectorResult, playbackInfo.staticMetadata);
        playbackInfo.bufferedPositionUs = maskedBufferedPositionUs;
    }
    return playbackInfo;
}
Also used : MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)

Example 18 with MediaPeriodId

use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.

the class MediaPeriodQueue method getUpdatedMediaPeriodInfo.

/**
 * Returns new media period info based on specified {@code mediaPeriodInfo} but taking into
 * account the current timeline. This method must only be called if the period is still part of
 * the current timeline.
 *
 * @param timeline The current timeline used to update the media period.
 * @param info Media period info for a media period based on an old timeline.
 * @return The updated media period info for the current timeline.
 */
public MediaPeriodInfo getUpdatedMediaPeriodInfo(Timeline timeline, MediaPeriodInfo info) {
    MediaPeriodId id = info.id;
    boolean isLastInPeriod = isLastInPeriod(id);
    boolean isLastInWindow = isLastInWindow(timeline, id);
    boolean isLastInTimeline = isLastInTimeline(timeline, id, isLastInPeriod);
    timeline.getPeriodByUid(info.id.periodUid, period);
    long endPositionUs = id.isAd() || id.nextAdGroupIndex == C.INDEX_UNSET ? C.TIME_UNSET : period.getAdGroupTimeUs(id.nextAdGroupIndex);
    long durationUs = id.isAd() ? period.getAdDurationUs(id.adGroupIndex, id.adIndexInAdGroup) : (endPositionUs == C.TIME_UNSET || endPositionUs == C.TIME_END_OF_SOURCE ? period.getDurationUs() : endPositionUs);
    boolean isFollowedByTransitionToSameStream = id.isAd() ? period.isServerSideInsertedAdGroup(id.adGroupIndex) : (id.nextAdGroupIndex != C.INDEX_UNSET && period.isServerSideInsertedAdGroup(id.nextAdGroupIndex));
    return new MediaPeriodInfo(id, info.startPositionUs, info.requestedContentPositionUs, endPositionUs, durationUs, isFollowedByTransitionToSameStream, isLastInPeriod, isLastInWindow, isLastInTimeline);
}
Also used : MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)

Example 19 with MediaPeriodId

use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.

the class MediaPeriodQueue method notifyQueueUpdate.

// Internal methods.
private void notifyQueueUpdate() {
    ImmutableList.Builder<MediaPeriodId> builder = ImmutableList.builder();
    @Nullable MediaPeriodHolder period = playing;
    while (period != null) {
        builder.add(period.info.id);
        period = period.getNext();
    }
    @Nullable MediaPeriodId readingPeriodId = reading == null ? null : reading.info.id;
    analyticsCollectorHandler.post(() -> analyticsCollector.updateMediaPeriodQueueInfo(builder.build(), readingPeriodId));
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) Nullable(androidx.annotation.Nullable)

Example 20 with MediaPeriodId

use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.

the class AdsMediaSource method releasePeriod.

@Override
public void releasePeriod(MediaPeriod mediaPeriod) {
    MaskingMediaPeriod maskingMediaPeriod = (MaskingMediaPeriod) mediaPeriod;
    MediaPeriodId id = maskingMediaPeriod.id;
    if (id.isAd()) {
        AdMediaSourceHolder adMediaSourceHolder = checkNotNull(adMediaSourceHolders[id.adGroupIndex][id.adIndexInAdGroup]);
        adMediaSourceHolder.releaseMediaPeriod(maskingMediaPeriod);
        if (adMediaSourceHolder.isInactive()) {
            adMediaSourceHolder.release();
            adMediaSourceHolders[id.adGroupIndex][id.adIndexInAdGroup] = null;
        }
    } else {
        maskingMediaPeriod.releasePeriod();
    }
}
Also used : MaskingMediaPeriod(com.google.android.exoplayer2.source.MaskingMediaPeriod) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)

Aggregations

MediaPeriodId (com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)106 Test (org.junit.Test)85 FakeTimeline (com.google.android.exoplayer2.testutil.FakeTimeline)75 Timeline (com.google.android.exoplayer2.Timeline)50 EventTime (com.google.android.exoplayer2.analytics.AnalyticsListener.EventTime)48 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)28 TimelineWindowDefinition (com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition)28 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)27 Nullable (androidx.annotation.Nullable)26 Allocator (com.google.android.exoplayer2.upstream.Allocator)22 SinglePeriodTimeline (com.google.android.exoplayer2.source.SinglePeriodTimeline)19 DrmSessionManager (com.google.android.exoplayer2.drm.DrmSessionManager)17 TransferListener (com.google.android.exoplayer2.upstream.TransferListener)16 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)15 AdPlaybackState (com.google.android.exoplayer2.source.ads.AdPlaybackState)15 FakeMediaPeriod (com.google.android.exoplayer2.testutil.FakeMediaPeriod)15 TestExoPlayerBuilder (com.google.android.exoplayer2.testutil.TestExoPlayerBuilder)15 ActionSchedule (com.google.android.exoplayer2.testutil.ActionSchedule)13 DrmSessionEventListener (com.google.android.exoplayer2.drm.DrmSessionEventListener)12 MediaPeriod (com.google.android.exoplayer2.source.MediaPeriod)11