Java Code Examples for com.google.android.exoplayer2.Timeline#getWindow()
The following examples show how to use
com.google.android.exoplayer2.Timeline#getWindow() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CustomizeControlView.java From bcm-android with GNU General Public License v3.0 | 6 votes |
private void updateNavigation() { if (!isVisible() || !isAttachedToWindow) { return; } Timeline timeline = player != null ? player.getCurrentTimeline() : null; boolean haveNonEmptyTimeline = timeline != null && !timeline.isEmpty(); boolean isSeekable = false; boolean enablePrevious = false; boolean enableNext = false; if (haveNonEmptyTimeline && !player.isPlayingAd()) { int windowIndex = player.getCurrentWindowIndex(); timeline.getWindow(windowIndex, window); isSeekable = window.isSeekable; enablePrevious = isSeekable || !window.isDynamic || player.getPreviousWindowIndex() != C.INDEX_UNSET; enableNext = window.isDynamic || player.getNextWindowIndex() != C.INDEX_UNSET; } setButtonEnabled(enablePrevious, previousButton); setButtonEnabled(enableNext, nextButton); setButtonEnabled(fastForwardMs > 0 && isSeekable, fastForwardButton); setButtonEnabled(rewindMs > 0 && isSeekable, rewindButton); if (timeBar != null) { timeBar.setEnabled(isSeekable); } }
Example 2
Source File: PlaybackControlView.java From K-Sonic with MIT License | 6 votes |
private void updateNavigation() { if (!isVisible() || !isAttachedToWindow) { return; } Timeline currentTimeline = player != null ? player.getCurrentTimeline() : null; boolean haveNonEmptyTimeline = currentTimeline != null && !currentTimeline.isEmpty(); boolean isSeekable = false; boolean enablePrevious = false; boolean enableNext = false; if (haveNonEmptyTimeline) { int currentWindowIndex = player.getCurrentWindowIndex(); currentTimeline.getWindow(currentWindowIndex, currentWindow); isSeekable = currentWindow.isSeekable; enablePrevious = currentWindowIndex > 0 || isSeekable || !currentWindow.isDynamic; enableNext = (currentWindowIndex < currentTimeline.getWindowCount() - 1) || currentWindow.isDynamic; } setButtonEnabled(enablePrevious , previousButton); setButtonEnabled(enableNext, nextButton); setButtonEnabled(fastForwardMs > 0 && isSeekable, fastForwardButton); setButtonEnabled(rewindMs > 0 && isSeekable, rewindButton); if (progressBar != null) { progressBar.setEnabled(isSeekable); } }
Example 3
Source File: GSYExo2MediaPlayer.java From GSYVideoPlayer with Apache License 2.0 | 6 votes |
/** * 下一集 */ public void next() { if (mInternalPlayer == null) { return; } Timeline timeline = mInternalPlayer.getCurrentTimeline(); if (timeline.isEmpty()) { return; } int windowIndex = mInternalPlayer.getCurrentWindowIndex(); int nextWindowIndex = mInternalPlayer.getNextWindowIndex(); if (nextWindowIndex != C.INDEX_UNSET) { mInternalPlayer.seekTo(nextWindowIndex, C.TIME_UNSET); } else if (timeline.getWindow(windowIndex, window, false).isDynamic) { mInternalPlayer.seekTo(windowIndex, C.TIME_UNSET); } }
Example 4
Source File: EventLogger.java From mimi-reader with Apache License 2.0 | 6 votes |
@Override public void onTimelineChanged(Timeline timeline, Object manifest, int reason) { int periodCount = timeline.getPeriodCount(); int windowCount = timeline.getWindowCount(); Log.d(TAG, "sourceInfo [periodCount=" + periodCount + ", windowCount=" + windowCount); for (int i = 0; i < Math.min(periodCount, MAX_TIMELINE_ITEM_LINES); i++) { timeline.getPeriod(i, period); Log.d(TAG, " " + "period [" + getTimeString(period.getDurationMs()) + "]"); } if (periodCount > MAX_TIMELINE_ITEM_LINES) { Log.d(TAG, " ..."); } for (int i = 0; i < Math.min(windowCount, MAX_TIMELINE_ITEM_LINES); i++) { timeline.getWindow(i, window); Log.d(TAG, " " + "window [" + getTimeString(window.getDurationMs()) + ", " + window.isSeekable + ", " + window.isDynamic + "]"); } if (windowCount > MAX_TIMELINE_ITEM_LINES) { Log.d(TAG, " ..."); } Log.d(TAG, "]"); }
Example 5
Source File: ClippingMediaSource.java From MediaSDK with Apache License 2.0 | 5 votes |
private void refreshClippedTimeline(Timeline timeline) { long windowStartUs; long windowEndUs; timeline.getWindow(/* windowIndex= */ 0, window); long windowPositionInPeriodUs = window.getPositionInFirstPeriodUs(); if (clippingTimeline == null || mediaPeriods.isEmpty() || allowDynamicClippingUpdates) { windowStartUs = startUs; windowEndUs = endUs; if (relativeToDefaultPosition) { long windowDefaultPositionUs = window.getDefaultPositionUs(); windowStartUs += windowDefaultPositionUs; windowEndUs += windowDefaultPositionUs; } periodStartUs = windowPositionInPeriodUs + windowStartUs; periodEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : windowPositionInPeriodUs + windowEndUs; int count = mediaPeriods.size(); for (int i = 0; i < count; i++) { mediaPeriods.get(i).updateClipping(periodStartUs, periodEndUs); } } else { // Keep window fixed at previous period position. windowStartUs = periodStartUs - windowPositionInPeriodUs; windowEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : periodEndUs - windowPositionInPeriodUs; } try { clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); } catch (IllegalClippingException e) { clippingError = e; return; } refreshSourceInfo(clippingTimeline); }
Example 6
Source File: ClippingMediaSource.java From Telegram with GNU General Public License v2.0 | 5 votes |
/** * Creates a new clipping timeline that wraps the specified timeline. * * @param timeline The timeline to clip. * @param startUs The number of microseconds to clip from the start of {@code timeline}. * @param endUs The end position in microseconds for the clipped timeline relative to the start * of {@code timeline}, or {@link C#TIME_END_OF_SOURCE} to clip no samples from the end. * @throws IllegalClippingException If the timeline could not be clipped. */ public ClippingTimeline(Timeline timeline, long startUs, long endUs) throws IllegalClippingException { super(timeline); if (timeline.getPeriodCount() != 1) { throw new IllegalClippingException(IllegalClippingException.REASON_INVALID_PERIOD_COUNT); } Window window = timeline.getWindow(0, new Window()); startUs = Math.max(0, startUs); long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : Math.max(0, endUs); if (window.durationUs != C.TIME_UNSET) { if (resolvedEndUs > window.durationUs) { resolvedEndUs = window.durationUs; } if (startUs != 0 && !window.isSeekable) { throw new IllegalClippingException(IllegalClippingException.REASON_NOT_SEEKABLE_TO_START); } if (startUs > resolvedEndUs) { throw new IllegalClippingException(IllegalClippingException.REASON_START_EXCEEDS_END); } } this.startUs = startUs; this.endUs = resolvedEndUs; durationUs = resolvedEndUs == C.TIME_UNSET ? C.TIME_UNSET : (resolvedEndUs - startUs); isDynamic = window.isDynamic && (resolvedEndUs == C.TIME_UNSET || (window.durationUs != C.TIME_UNSET && resolvedEndUs == window.durationUs)); }
Example 7
Source File: ExoMediaPlayer.java From ExoMedia with Apache License 2.0 | 5 votes |
/** * TODO: Expose this * Seeks to the specified position in the media currently loaded specified by <code>positionMs</code>. * If <code>limitToCurrentWindow</code> is true then a seek won't be allowed to span across windows. * This should only be different if the media in playback has multiple windows (e.g. in the case of using a * <code>ConcatenatingMediaSource</code> with more than 1 source) * * @param positionMs The position to seek to in the media * @param limitToCurrentWindow <code>true</code> to only seek in the current window */ public void seekTo(long positionMs, boolean limitToCurrentWindow) { analyticsCollector.notifySeekStarted(); if (limitToCurrentWindow) { player.seekTo(positionMs); stateStore.setMostRecentState(stateStore.isLastReportedPlayWhenReady(), StateStore.STATE_SEEKING); return; } // We seek to the position in the timeline (may be across windows) Timeline timeline = player.getCurrentTimeline(); int windowCount = timeline.getWindowCount(); long cumulativePositionMs = 0; Timeline.Window window = new Timeline.Window(); for (int index = 0; index < windowCount; index++) { timeline.getWindow(index, window); long windowDurationMs = window.getDurationMs(); if (cumulativePositionMs < positionMs && positionMs <= (cumulativePositionMs + windowDurationMs)) { player.seekTo(index, positionMs - cumulativePositionMs); stateStore.setMostRecentState(stateStore.isLastReportedPlayWhenReady(), StateStore.STATE_SEEKING); return; } cumulativePositionMs += windowDurationMs; } Log.e(TAG, "Unable to seek across windows, falling back to in-window seeking"); player.seekTo(positionMs); stateStore.setMostRecentState(stateStore.isLastReportedPlayWhenReady(), StateStore.STATE_SEEKING); }
Example 8
Source File: ClippingMediaSource.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
/** * Creates a new clipping timeline that wraps the specified timeline. * * @param timeline The timeline to clip. * @param startUs The number of microseconds to clip from the start of {@code timeline}. * @param endUs The end position in microseconds for the clipped timeline relative to the start * of {@code timeline}, or {@link C#TIME_END_OF_SOURCE} to clip no samples from the end. * @throws IllegalClippingException If the timeline could not be clipped. */ public ClippingTimeline(Timeline timeline, long startUs, long endUs) throws IllegalClippingException { super(timeline); if (timeline.getPeriodCount() != 1) { throw new IllegalClippingException(IllegalClippingException.REASON_INVALID_PERIOD_COUNT); } Window window = timeline.getWindow(0, new Window(), false); startUs = Math.max(0, startUs); long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : Math.max(0, endUs); if (window.durationUs != C.TIME_UNSET) { if (resolvedEndUs > window.durationUs) { resolvedEndUs = window.durationUs; } if (startUs != 0 && !window.isSeekable) { throw new IllegalClippingException(IllegalClippingException.REASON_NOT_SEEKABLE_TO_START); } if (startUs > resolvedEndUs) { throw new IllegalClippingException(IllegalClippingException.REASON_START_EXCEEDS_END); } } this.startUs = startUs; this.endUs = resolvedEndUs; durationUs = resolvedEndUs == C.TIME_UNSET ? C.TIME_UNSET : (resolvedEndUs - startUs); isDynamic = window.isDynamic && (resolvedEndUs == C.TIME_UNSET || (window.durationUs != C.TIME_UNSET && resolvedEndUs == window.durationUs)); }
Example 9
Source File: ClippingMediaSource.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
private void refreshClippedTimeline(Timeline timeline) { long windowStartUs; long windowEndUs; timeline.getWindow(/* windowIndex= */ 0, window); long windowPositionInPeriodUs = window.getPositionInFirstPeriodUs(); if (clippingTimeline == null || mediaPeriods.isEmpty() || allowDynamicClippingUpdates) { windowStartUs = startUs; windowEndUs = endUs; if (relativeToDefaultPosition) { long windowDefaultPositionUs = window.getDefaultPositionUs(); windowStartUs += windowDefaultPositionUs; windowEndUs += windowDefaultPositionUs; } periodStartUs = windowPositionInPeriodUs + windowStartUs; periodEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : windowPositionInPeriodUs + windowEndUs; int count = mediaPeriods.size(); for (int i = 0; i < count; i++) { mediaPeriods.get(i).updateClipping(periodStartUs, periodEndUs); } } else { // Keep window fixed at previous period position. windowStartUs = periodStartUs - windowPositionInPeriodUs; windowEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : periodEndUs - windowPositionInPeriodUs; } try { clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); } catch (IllegalClippingException e) { clippingError = e; return; } refreshSourceInfo(clippingTimeline, manifest); }
Example 10
Source File: ConcatenatingMediaSource.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
private void updateMediaSourceInternal(MediaSourceHolder mediaSourceHolder, Timeline timeline) { if (mediaSourceHolder == null) { throw new IllegalArgumentException(); } DeferredTimeline deferredTimeline = mediaSourceHolder.timeline; if (deferredTimeline.getTimeline() == timeline) { return; } int windowOffsetUpdate = timeline.getWindowCount() - deferredTimeline.getWindowCount(); int periodOffsetUpdate = timeline.getPeriodCount() - deferredTimeline.getPeriodCount(); if (windowOffsetUpdate != 0 || periodOffsetUpdate != 0) { correctOffsets( mediaSourceHolder.childIndex + 1, /* childIndexUpdate= */ 0, windowOffsetUpdate, periodOffsetUpdate); } mediaSourceHolder.timeline = deferredTimeline.cloneWithNewTimeline(timeline); if (!mediaSourceHolder.isPrepared && !timeline.isEmpty()) { timeline.getWindow(/* windowIndex= */ 0, window); long defaultPeriodPositionUs = window.getPositionInFirstPeriodUs() + window.getDefaultPositionUs(); for (int i = 0; i < mediaSourceHolder.activeMediaPeriods.size(); i++) { DeferredMediaPeriod deferredMediaPeriod = mediaSourceHolder.activeMediaPeriods.get(i); deferredMediaPeriod.setDefaultPreparePositionUs(defaultPeriodPositionUs); MediaPeriodId idInSource = deferredMediaPeriod.id.copyWithPeriodIndex( deferredMediaPeriod.id.periodIndex - mediaSourceHolder.firstPeriodIndexInChild); deferredMediaPeriod.createPeriod(idInSource); } mediaSourceHolder.isPrepared = true; } scheduleListenerNotification(/* actionOnCompletion= */ null); }
Example 11
Source File: ClippingMediaSource.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
/** * Creates a new clipping timeline that wraps the specified timeline. * * @param timeline The timeline to clip. * @param startUs The number of microseconds to clip from the start of {@code timeline}. * @param endUs The end position in microseconds for the clipped timeline relative to the start * of {@code timeline}, or {@link C#TIME_END_OF_SOURCE} to clip no samples from the end. * @throws IllegalClippingException If the timeline could not be clipped. */ public ClippingTimeline(Timeline timeline, long startUs, long endUs) throws IllegalClippingException { super(timeline); if (timeline.getPeriodCount() != 1) { throw new IllegalClippingException(IllegalClippingException.REASON_INVALID_PERIOD_COUNT); } Window window = timeline.getWindow(0, new Window(), false); startUs = Math.max(0, startUs); long resolvedEndUs = endUs == C.TIME_END_OF_SOURCE ? window.durationUs : Math.max(0, endUs); if (window.durationUs != C.TIME_UNSET) { if (resolvedEndUs > window.durationUs) { resolvedEndUs = window.durationUs; } if (startUs != 0 && !window.isSeekable) { throw new IllegalClippingException(IllegalClippingException.REASON_NOT_SEEKABLE_TO_START); } if (startUs > resolvedEndUs) { throw new IllegalClippingException(IllegalClippingException.REASON_START_EXCEEDS_END); } } this.startUs = startUs; this.endUs = resolvedEndUs; durationUs = resolvedEndUs == C.TIME_UNSET ? C.TIME_UNSET : (resolvedEndUs - startUs); isDynamic = window.isDynamic && (resolvedEndUs == C.TIME_UNSET || (window.durationUs != C.TIME_UNSET && resolvedEndUs == window.durationUs)); }
Example 12
Source File: ClippingMediaSource.java From TelePlus-Android with GNU General Public License v2.0 | 5 votes |
private void refreshClippedTimeline(Timeline timeline) { long windowStartUs; long windowEndUs; timeline.getWindow(/* windowIndex= */ 0, window); long windowPositionInPeriodUs = window.getPositionInFirstPeriodUs(); if (clippingTimeline == null || mediaPeriods.isEmpty() || allowDynamicClippingUpdates) { windowStartUs = startUs; windowEndUs = endUs; if (relativeToDefaultPosition) { long windowDefaultPositionUs = window.getDefaultPositionUs(); windowStartUs += windowDefaultPositionUs; windowEndUs += windowDefaultPositionUs; } periodStartUs = windowPositionInPeriodUs + windowStartUs; periodEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : windowPositionInPeriodUs + windowEndUs; int count = mediaPeriods.size(); for (int i = 0; i < count; i++) { mediaPeriods.get(i).updateClipping(periodStartUs, periodEndUs); } } else { // Keep window fixed at previous period position. windowStartUs = periodStartUs - windowPositionInPeriodUs; windowEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : periodEndUs - windowPositionInPeriodUs; } try { clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); } catch (IllegalClippingException e) { clippingError = e; return; } refreshSourceInfo(clippingTimeline, manifest); }
Example 13
Source File: ExoVideoPlaybackControlView.java From ExoVideoView with Apache License 2.0 | 5 votes |
/** * Returns whether the specified {@code timeline} can be shown on a multi-window time bar. * * @param timeline The {@link Timeline} to check. * @param window A scratch {@link Timeline.Window} instance. * @return Whether the specified timeline can be shown on a multi-window time bar. */ private static boolean canShowMultiWindowTimeBar(Timeline timeline, Timeline.Window window) { if (timeline.getWindowCount() > MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR) { return false; } int windowCount = timeline.getWindowCount(); for (int i = 0; i < windowCount; i++) { if (timeline.getWindow(i, window).durationUs == C.TIME_UNSET) { return false; } } return true; }
Example 14
Source File: VideoGesture.java From ExoVideoView with Apache License 2.0 | 5 votes |
private boolean canSeek() { Player player = playerAccessor.attachPlayer(); Timeline timeline = player != null ? player.getCurrentTimeline() : null; boolean haveNonEmptyTimeline = timeline != null && !timeline.isEmpty(); boolean isSeekable = false; if (haveNonEmptyTimeline) { int windowIndex = player.getCurrentWindowIndex(); timeline.getWindow(windowIndex, window); isSeekable = window.isSeekable; } return isSeekable; }
Example 15
Source File: CustomizeControlView.java From bcm-android with GNU General Public License v3.0 | 5 votes |
private void next() { Timeline timeline = player.getCurrentTimeline(); if (timeline.isEmpty()) { return; } int windowIndex = player.getCurrentWindowIndex(); int nextWindowIndex = player.getNextWindowIndex(); if (nextWindowIndex != C.INDEX_UNSET) { seekTo(nextWindowIndex, C.TIME_UNSET); } else if (timeline.getWindow(windowIndex, window, false).isDynamic) { seekTo(windowIndex, C.TIME_UNSET); } }
Example 16
Source File: ClippingMediaSource.java From Telegram with GNU General Public License v2.0 | 5 votes |
private void refreshClippedTimeline(Timeline timeline) { long windowStartUs; long windowEndUs; timeline.getWindow(/* windowIndex= */ 0, window); long windowPositionInPeriodUs = window.getPositionInFirstPeriodUs(); if (clippingTimeline == null || mediaPeriods.isEmpty() || allowDynamicClippingUpdates) { windowStartUs = startUs; windowEndUs = endUs; if (relativeToDefaultPosition) { long windowDefaultPositionUs = window.getDefaultPositionUs(); windowStartUs += windowDefaultPositionUs; windowEndUs += windowDefaultPositionUs; } periodStartUs = windowPositionInPeriodUs + windowStartUs; periodEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : windowPositionInPeriodUs + windowEndUs; int count = mediaPeriods.size(); for (int i = 0; i < count; i++) { mediaPeriods.get(i).updateClipping(periodStartUs, periodEndUs); } } else { // Keep window fixed at previous period position. windowStartUs = periodStartUs - windowPositionInPeriodUs; windowEndUs = endUs == C.TIME_END_OF_SOURCE ? C.TIME_END_OF_SOURCE : periodEndUs - windowPositionInPeriodUs; } try { clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); } catch (IllegalClippingException e) { clippingError = e; return; } refreshSourceInfo(clippingTimeline, manifest); }
Example 17
Source File: PlaybackControlView.java From K-Sonic with MIT License | 5 votes |
private void next() { Timeline currentTimeline = player.getCurrentTimeline(); if (currentTimeline.isEmpty()) { return; } int currentWindowIndex = player.getCurrentWindowIndex(); if (currentWindowIndex < currentTimeline.getWindowCount() - 1) { seekTo(currentWindowIndex + 1, C.TIME_UNSET); } else if (currentTimeline.getWindow(currentWindowIndex, currentWindow, false).isDynamic) { seekTo(currentWindowIndex, C.TIME_UNSET); } }
Example 18
Source File: MaskingMediaSource.java From MediaSDK with Apache License 2.0 | 4 votes |
@Override protected void onChildSourceInfoRefreshed( Void id, MediaSource mediaSource, Timeline newTimeline) { if (isPrepared) { timeline = timeline.cloneWithUpdatedTimeline(newTimeline); } else if (newTimeline.isEmpty()) { timeline = MaskingTimeline.createWithRealTimeline( newTimeline, Window.SINGLE_WINDOW_UID, MaskingTimeline.DUMMY_EXTERNAL_PERIOD_UID); } else { // Determine first period and the start position. // This will be: // 1. The default window start position if no deferred period has been created yet. // 2. The non-zero prepare position of the deferred period under the assumption that this is // a non-zero initial seek position in the window. // 3. The default window start position if the deferred period has a prepare position of zero // under the assumption that the prepare position of zero was used because it's the // default position of the DummyTimeline window. Note that this will override an // intentional seek to zero for a window with a non-zero default position. This is // unlikely to be a problem as a non-zero default position usually only occurs for live // playbacks and seeking to zero in a live window would cause BehindLiveWindowExceptions // anyway. newTimeline.getWindow(/* windowIndex= */ 0, window); long windowStartPositionUs = window.getDefaultPositionUs(); if (unpreparedMaskingMediaPeriod != null) { long periodPreparePositionUs = unpreparedMaskingMediaPeriod.getPreparePositionUs(); if (periodPreparePositionUs != 0) { windowStartPositionUs = periodPreparePositionUs; } } Object windowUid = window.uid; Pair<Object, Long> periodPosition = newTimeline.getPeriodPosition( window, period, /* windowIndex= */ 0, windowStartPositionUs); Object periodUid = periodPosition.first; long periodPositionUs = periodPosition.second; timeline = MaskingTimeline.createWithRealTimeline(newTimeline, windowUid, periodUid); if (unpreparedMaskingMediaPeriod != null) { MaskingMediaPeriod maskingPeriod = unpreparedMaskingMediaPeriod; maskingPeriod.overridePreparePositionUs(periodPositionUs); MediaPeriodId idInSource = maskingPeriod.id.copyWithPeriodUid(getInternalPeriodUid(maskingPeriod.id.periodUid)); maskingPeriod.createPeriod(idInSource); } } isPrepared = true; refreshSourceInfo(this.timeline); }
Example 19
Source File: ConcatenatingMediaSource.java From Telegram-FOSS with GNU General Public License v2.0 | 4 votes |
private void updateMediaSourceInternal(MediaSourceHolder mediaSourceHolder, Timeline timeline) { if (mediaSourceHolder == null) { throw new IllegalArgumentException(); } DeferredTimeline deferredTimeline = mediaSourceHolder.timeline; if (deferredTimeline.getTimeline() == timeline) { return; } int windowOffsetUpdate = timeline.getWindowCount() - deferredTimeline.getWindowCount(); int periodOffsetUpdate = timeline.getPeriodCount() - deferredTimeline.getPeriodCount(); if (windowOffsetUpdate != 0 || periodOffsetUpdate != 0) { correctOffsets( mediaSourceHolder.childIndex + 1, /* childIndexUpdate= */ 0, windowOffsetUpdate, periodOffsetUpdate); } if (mediaSourceHolder.isPrepared) { mediaSourceHolder.timeline = deferredTimeline.cloneWithUpdatedTimeline(timeline); } else if (timeline.isEmpty()) { mediaSourceHolder.timeline = DeferredTimeline.createWithRealTimeline(timeline, DeferredTimeline.DUMMY_ID); } else { // We should have at most one deferred media period for the DummyTimeline because the duration // is unset and we don't load beyond periods with unset duration. We need to figure out how to // handle the prepare positions of multiple deferred media periods, should that ever change. Assertions.checkState(mediaSourceHolder.activeMediaPeriods.size() <= 1); DeferredMediaPeriod deferredMediaPeriod = mediaSourceHolder.activeMediaPeriods.isEmpty() ? null : mediaSourceHolder.activeMediaPeriods.get(0); // Determine first period and the start position. // This will be: // 1. The default window start position if no deferred period has been created yet. // 2. The non-zero prepare position of the deferred period under the assumption that this is // a non-zero initial seek position in the window. // 3. The default window start position if the deferred period has a prepare position of zero // under the assumption that the prepare position of zero was used because it's the // default position of the DummyTimeline window. Note that this will override an // intentional seek to zero for a window with a non-zero default position. This is // unlikely to be a problem as a non-zero default position usually only occurs for live // playbacks and seeking to zero in a live window would cause BehindLiveWindowExceptions // anyway. timeline.getWindow(/* windowIndex= */ 0, window); long windowStartPositionUs = window.getDefaultPositionUs(); if (deferredMediaPeriod != null) { long periodPreparePositionUs = deferredMediaPeriod.getPreparePositionUs(); if (periodPreparePositionUs != 0) { windowStartPositionUs = periodPreparePositionUs; } } Pair<Object, Long> periodPosition = timeline.getPeriodPosition(window, period, /* windowIndex= */ 0, windowStartPositionUs); Object periodUid = periodPosition.first; long periodPositionUs = periodPosition.second; mediaSourceHolder.timeline = DeferredTimeline.createWithRealTimeline(timeline, periodUid); if (deferredMediaPeriod != null) { deferredMediaPeriod.overridePreparePositionUs(periodPositionUs); MediaPeriodId idInSource = deferredMediaPeriod.id.copyWithPeriodUid( getChildPeriodUid(mediaSourceHolder, deferredMediaPeriod.id.periodUid)); deferredMediaPeriod.createPeriod(idInSource); } } mediaSourceHolder.isPrepared = true; scheduleTimelineUpdate(); }
Example 20
Source File: ConcatenatingMediaSource.java From Telegram with GNU General Public License v2.0 | 4 votes |
private void updateMediaSourceInternal(MediaSourceHolder mediaSourceHolder, Timeline timeline) { if (mediaSourceHolder == null) { throw new IllegalArgumentException(); } DeferredTimeline deferredTimeline = mediaSourceHolder.timeline; if (deferredTimeline.getTimeline() == timeline) { return; } int windowOffsetUpdate = timeline.getWindowCount() - deferredTimeline.getWindowCount(); int periodOffsetUpdate = timeline.getPeriodCount() - deferredTimeline.getPeriodCount(); if (windowOffsetUpdate != 0 || periodOffsetUpdate != 0) { correctOffsets( mediaSourceHolder.childIndex + 1, /* childIndexUpdate= */ 0, windowOffsetUpdate, periodOffsetUpdate); } if (mediaSourceHolder.isPrepared) { mediaSourceHolder.timeline = deferredTimeline.cloneWithUpdatedTimeline(timeline); } else if (timeline.isEmpty()) { mediaSourceHolder.timeline = DeferredTimeline.createWithRealTimeline(timeline, DeferredTimeline.DUMMY_ID); } else { // We should have at most one deferred media period for the DummyTimeline because the duration // is unset and we don't load beyond periods with unset duration. We need to figure out how to // handle the prepare positions of multiple deferred media periods, should that ever change. Assertions.checkState(mediaSourceHolder.activeMediaPeriods.size() <= 1); DeferredMediaPeriod deferredMediaPeriod = mediaSourceHolder.activeMediaPeriods.isEmpty() ? null : mediaSourceHolder.activeMediaPeriods.get(0); // Determine first period and the start position. // This will be: // 1. The default window start position if no deferred period has been created yet. // 2. The non-zero prepare position of the deferred period under the assumption that this is // a non-zero initial seek position in the window. // 3. The default window start position if the deferred period has a prepare position of zero // under the assumption that the prepare position of zero was used because it's the // default position of the DummyTimeline window. Note that this will override an // intentional seek to zero for a window with a non-zero default position. This is // unlikely to be a problem as a non-zero default position usually only occurs for live // playbacks and seeking to zero in a live window would cause BehindLiveWindowExceptions // anyway. timeline.getWindow(/* windowIndex= */ 0, window); long windowStartPositionUs = window.getDefaultPositionUs(); if (deferredMediaPeriod != null) { long periodPreparePositionUs = deferredMediaPeriod.getPreparePositionUs(); if (periodPreparePositionUs != 0) { windowStartPositionUs = periodPreparePositionUs; } } Pair<Object, Long> periodPosition = timeline.getPeriodPosition(window, period, /* windowIndex= */ 0, windowStartPositionUs); Object periodUid = periodPosition.first; long periodPositionUs = periodPosition.second; mediaSourceHolder.timeline = DeferredTimeline.createWithRealTimeline(timeline, periodUid); if (deferredMediaPeriod != null) { deferredMediaPeriod.overridePreparePositionUs(periodPositionUs); MediaPeriodId idInSource = deferredMediaPeriod.id.copyWithPeriodUid( getChildPeriodUid(mediaSourceHolder, deferredMediaPeriod.id.periodUid)); deferredMediaPeriod.createPeriod(idInSource); } } mediaSourceHolder.isPrepared = true; scheduleTimelineUpdate(); }