/** * Returns the index of the first window in the playback order depending on whether shuffling is * enabled. * * @param shuffleModeEnabled Whether shuffling is enabled. * @return The index of the first window in the playback order, or {@link C#INDEX_UNSET} if the * timeline is empty. */ public int getFirstWindowIndex(boolean shuffleModeEnabled) { return isEmpty() ? C.INDEX_UNSET : 0; }
private boolean shouldMaskPosition() { return playbackInfo.timeline.isEmpty() || pendingOperationAcks > 0; }
/** * Returns the {@link MediaPeriodInfo} of the media period in the front of the queue. This is * the playing media period unless the player hasn't started playing yet (in which case it is * the loading media period or null). While the player is seeking or preparing, this method will * always return null to reflect the uncertainty about the current playing period. May also be * null, if the timeline is empty or no media period is active yet. */ public @Nullable MediaPeriodInfo getPlayingMediaPeriod() { return mediaPeriodInfoQueue.isEmpty() || timeline.isEmpty() || isSeeking ? null : mediaPeriodInfoQueue.get(0); }
/** * Returns the index of the last window in the playback order depending on whether shuffling is * enabled. * * @param shuffleModeEnabled Whether shuffling is enabled. * @return The index of the last window in the playback order, or {@link C#INDEX_UNSET} if the * timeline is empty. */ public int getLastWindowIndex(boolean shuffleModeEnabled) { return isEmpty() ? C.INDEX_UNSET : getWindowCount() - 1; }
@Override public void onTimelineChanged( Timeline timeline, @Nullable Object manifest, @TimelineChangeReason int reason) { updateCurrentItemIndex(); if (timeline.isEmpty()) { castMediaQueueCreationPending = true; } }
@Override @Nullable public Object getTag() { boolean hasTimeline = timeline != null && !timeline.isEmpty(); return hasTimeline ? timeline.getWindow(0, new Timeline.Window()).tag : null; }
/** Updates the queue with a newly created media period. */ public void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) { boolean isInTimeline = timeline.getIndexOfPeriod(mediaPeriodId.periodUid) != C.INDEX_UNSET; MediaPeriodInfo mediaPeriodInfo = new MediaPeriodInfo(mediaPeriodId, isInTimeline ? timeline : Timeline.EMPTY, windowIndex); mediaPeriodInfoQueue.add(mediaPeriodInfo); mediaPeriodIdToInfo.put(mediaPeriodId, mediaPeriodInfo); if (mediaPeriodInfoQueue.size() == 1 && !timeline.isEmpty()) { updateLastReportedPlayingMediaPeriod(); } }
@Override public long getSupportedPlaybackActions(Player player) { if (player == null || player.getCurrentTimeline().isEmpty()) { return 0; } else if (!player.isCurrentWindowSeekable()) { return BASE_ACTIONS; } long actions = BASE_ACTIONS | PlaybackStateCompat.ACTION_SEEK_TO; if (fastForwardIncrementMs > 0) { actions |= PlaybackStateCompat.ACTION_FAST_FORWARD; } if (rewindIncrementMs > 0) { actions |= PlaybackStateCompat.ACTION_REWIND; } return actions; }
@Override public final boolean isCurrentWindowDynamic() { Timeline timeline = getCurrentTimeline(); return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isDynamic; }
@Override public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) { if (timeline.isEmpty()) { playerReference.get().setPlayWhenReady(/* playWhenReady= */ false); } }
@Override public final boolean isCurrentWindowSeekable() { Timeline timeline = getCurrentTimeline(); return !timeline.isEmpty() && timeline.getWindow(getCurrentWindowIndex(), window).isSeekable; }
@Override public void onSkipToQueueItem(Player player, long id) { Timeline timeline = player.getCurrentTimeline(); if (timeline.isEmpty() || player.isPlayingAd()) { return; } int windowIndex = (int) id; if (0 <= windowIndex && windowIndex < timeline.getWindowCount()) { player.seekTo(windowIndex, C.TIME_UNSET); } }
@Override public final long getContentDuration() { Timeline timeline = getCurrentTimeline(); return timeline.isEmpty() ? C.TIME_UNSET : timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs(); }
@Override @Nullable public Object getTag() { boolean hasTimeline = timeline != null && !timeline.isEmpty(); return hasTimeline ? timeline.getWindow(0, new Timeline.Window()).tag : null; }
@Override public final void onCurrentWindowIndexChanged(Player player) { if (activeQueueItemId == MediaSessionCompat.QueueItem.UNKNOWN_ID || player.getCurrentTimeline().getWindowCount() > maxQueueSize) { publishFloatingQueueWindow(player); } else if (!player.getCurrentTimeline().isEmpty()) { activeQueueItemId = player.getCurrentWindowIndex(); } }
@Override public final int getNextWindowIndex() { Timeline timeline = getCurrentTimeline(); return timeline.isEmpty() ? C.INDEX_UNSET : timeline.getNextWindowIndex( getCurrentWindowIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled()); }
@Override public final int getPreviousWindowIndex() { Timeline timeline = getCurrentTimeline(); return timeline.isEmpty() ? C.INDEX_UNSET : timeline.getPreviousWindowIndex( getCurrentWindowIndex(), getRepeatModeForNavigation(), getShuffleModeEnabled()); }
private void next() { Timeline timeline = player.getCurrentTimeline(); if (timeline.isEmpty() || player.isPlayingAd()) { 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).isDynamic) { seekTo(windowIndex, C.TIME_UNSET); } }
@Override public void onSkipToNext(Player player) { Timeline timeline = player.getCurrentTimeline(); if (timeline.isEmpty() || player.isPlayingAd()) { return; } int windowIndex = player.getCurrentWindowIndex(); int nextWindowIndex = player.getNextWindowIndex(); if (nextWindowIndex != C.INDEX_UNSET) { player.seekTo(nextWindowIndex, C.TIME_UNSET); } else if (timeline.getWindow(windowIndex, window).isDynamic) { player.seekTo(windowIndex, C.TIME_UNSET); } }
@Override public long getDuration() { if (timeline.isEmpty()) { return C.INDEX_UNSET; } if (isPlayingAd()) { long adDurationUs = timeline.getPeriod(0, period).getAdDurationUs(adGroupIndex, adIndexInAdGroup); return C.usToMs(adDurationUs); } else { return timeline.getWindow(getCurrentWindowIndex(), window).getDurationMs(); } }