Show ad markers for non-multi-window time bars

Ads don't have their own periods any more, so show ad group markers even if the
time bar is not multi-window.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=161524411
This commit is contained in:
andrewlewis 2017-07-11 07:11:49 -07:00 committed by Oliver Woodman
parent 6f2f8e49b8
commit 94683d1e8c
2 changed files with 67 additions and 81 deletions

View File

@ -327,8 +327,6 @@ public class PlayerActivity extends Activity implements OnClickListener, ExoPlay
mediaDataSourceFactory, this, adTagUri, adOverlayViewGroup); mediaDataSourceFactory, this, adTagUri, adOverlayViewGroup);
// The demo app has a non-null overlay frame layout. // The demo app has a non-null overlay frame layout.
simpleExoPlayerView.getOverlayFrameLayout().addView(adOverlayViewGroup); simpleExoPlayerView.getOverlayFrameLayout().addView(adOverlayViewGroup);
// Show a multi-window time bar, which will include ad position markers.
simpleExoPlayerView.setShowMultiWindowTimeBar(true);
} catch (Exception e) { } catch (Exception e) {
// Throw if the media source class was not found, or there was an error instantiating it. // Throw if the media source class was not found, or there was an error instantiating it.
showToast(R.string.ima_not_loaded); showToast(R.string.ima_not_loaded);

View File

@ -695,7 +695,7 @@ public class PlaybackControlView extends FrameLayout {
return; return;
} }
multiWindowTimeBar = showMultiWindowTimeBar multiWindowTimeBar = showMultiWindowTimeBar
&& canShowMultiWindowTimeBar(player.getCurrentTimeline(), period); && canShowMultiWindowTimeBar(player.getCurrentTimeline(), window);
} }
private void updateProgress() { private void updateProgress() {
@ -707,63 +707,61 @@ public class PlaybackControlView extends FrameLayout {
long bufferedPosition = 0; long bufferedPosition = 0;
long duration = 0; long duration = 0;
if (player != null) { if (player != null) {
if (multiWindowTimeBar) { long currentWindowTimeBarOffsetUs = 0;
Timeline timeline = player.getCurrentTimeline(); long durationUs = 0;
int windowCount = timeline.getWindowCount(); int adGroupCount = 0;
int periodIndex = player.getCurrentPeriodIndex(); Timeline timeline = player.getCurrentTimeline();
long positionUs = 0; if (!timeline.isEmpty()) {
long bufferedPositionUs = 0; int currentWindowIndex = player.getCurrentWindowIndex();
long durationUs = 0; int firstWindowIndex = multiWindowTimeBar ? 0 : currentWindowIndex;
int adGroupTimesMsCount = 0; int lastWindowIndex =
for (int i = 0; i < windowCount; i++) { multiWindowTimeBar ? timeline.getWindowCount() - 1 : currentWindowIndex;
for (int i = firstWindowIndex; i <= lastWindowIndex; i++) {
if (i == currentWindowIndex) {
currentWindowTimeBarOffsetUs = durationUs;
}
timeline.getWindow(i, window); timeline.getWindow(i, window);
if (window.durationUs == C.TIME_UNSET) {
Assertions.checkState(!multiWindowTimeBar);
break;
}
for (int j = window.firstPeriodIndex; j <= window.lastPeriodIndex; j++) { for (int j = window.firstPeriodIndex; j <= window.lastPeriodIndex; j++) {
long periodDurationUs = timeline.getPeriod(j, period).getDurationUs(); timeline.getPeriod(j, period);
Assertions.checkState(periodDurationUs != C.TIME_UNSET); int periodAdGroupCount = period.getAdGroupCount();
long periodDurationInWindowUs = periodDurationUs; for (int adGroupIndex = 0; adGroupIndex < periodAdGroupCount; adGroupIndex++) {
if (j == window.firstPeriodIndex) { long adGroupTimeInPeriodUs = period.getAdGroupTimeUs(adGroupIndex);
periodDurationInWindowUs -= window.positionInFirstPeriodUs; if (adGroupTimeInPeriodUs == C.TIME_END_OF_SOURCE) {
} if (period.durationUs == C.TIME_UNSET) {
for (int adGroupIndex = 0; adGroupIndex < period.getAdGroupCount(); adGroupIndex++) { // Don't show ad markers for postrolls in periods with unknown duration.
long adGroupTimeUs = period.getAdGroupTimeUs(adGroupIndex); continue;
if (adGroupTimeUs == C.TIME_END_OF_SOURCE) { }
adGroupTimeUs = periodDurationUs; adGroupTimeInPeriodUs = period.durationUs;
} }
if (j == window.firstPeriodIndex) { long adGroupTimeInWindowUs = adGroupTimeInPeriodUs + period.getPositionInWindowUs();
adGroupTimeUs -= window.positionInFirstPeriodUs; if (adGroupTimeInWindowUs >= 0 && adGroupTimeInWindowUs <= window.durationUs) {
} if (adGroupCount == adGroupTimesMs.length) {
if (adGroupTimeUs >= 0 && adGroupTimeUs <= window.durationUs) {
if (adGroupTimesMsCount == adGroupTimesMs.length) {
int newLength = adGroupTimesMs.length == 0 ? 1 : adGroupTimesMs.length * 2; int newLength = adGroupTimesMs.length == 0 ? 1 : adGroupTimesMs.length * 2;
adGroupTimesMs = Arrays.copyOf(adGroupTimesMs, newLength); adGroupTimesMs = Arrays.copyOf(adGroupTimesMs, newLength);
playedAdGroups = Arrays.copyOf(playedAdGroups, newLength); playedAdGroups = Arrays.copyOf(playedAdGroups, newLength);
} }
adGroupTimesMs[adGroupTimesMsCount] = C.usToMs(durationUs + adGroupTimeUs); adGroupTimesMs[adGroupCount] = C.usToMs(durationUs + adGroupTimeInWindowUs);
playedAdGroups[adGroupTimesMsCount] = period.hasPlayedAdGroup(adGroupIndex); playedAdGroups[adGroupCount] = period.hasPlayedAdGroup(adGroupIndex);
adGroupTimesMsCount++; adGroupCount++;
} }
} }
if (i < periodIndex) {
positionUs += periodDurationInWindowUs;
bufferedPositionUs += periodDurationInWindowUs;
}
durationUs += periodDurationInWindowUs;
} }
durationUs += window.durationUs;
} }
position = C.usToMs(positionUs); }
bufferedPosition = C.usToMs(bufferedPositionUs); duration = C.usToMs(durationUs);
duration = C.usToMs(durationUs); position = C.usToMs(currentWindowTimeBarOffsetUs);
if (!player.isPlayingAd()) { bufferedPosition = C.usToMs(currentWindowTimeBarOffsetUs);
position += player.getCurrentPosition(); if (!player.isPlayingAd()) {
bufferedPosition += player.getBufferedPosition(); position += player.getCurrentPosition();
} bufferedPosition += player.getBufferedPosition();
if (timeBar != null) { }
timeBar.setAdGroupTimesMs(adGroupTimesMs, playedAdGroups, adGroupTimesMsCount); if (timeBar != null) {
} timeBar.setAdGroupTimesMs(adGroupTimesMs, playedAdGroups, adGroupCount);
} else {
position = player.getCurrentPosition();
bufferedPosition = player.getBufferedPosition();
duration = player.getDuration();
} }
} }
if (durationView != null) { if (durationView != null) {
@ -909,38 +907,28 @@ public class PlaybackControlView extends FrameLayout {
} }
} }
private void seekToTimeBarPosition(long timebarPositionMs) { private void seekToTimeBarPosition(long positionMs) {
if (multiWindowTimeBar) { int windowIndex;
Timeline timeline = player.getCurrentTimeline(); Timeline timeline = player.getCurrentTimeline();
if (multiWindowTimeBar && !timeline.isEmpty()) {
int windowCount = timeline.getWindowCount(); int windowCount = timeline.getWindowCount();
long remainingMs = timebarPositionMs; windowIndex = 0;
for (int i = 0; i < windowCount; i++) { while (true) {
timeline.getWindow(i, window); long windowDurationMs = timeline.getWindow(windowIndex, window).getDurationMs();
for (int j = window.firstPeriodIndex; j <= window.lastPeriodIndex; j++) { if (positionMs < windowDurationMs) {
long periodDurationMs = timeline.getPeriod(j, period).getDurationMs(); break;
if (periodDurationMs == C.TIME_UNSET) { } else if (windowIndex == windowCount - 1) {
// Should never happen as canShowMultiWindowTimeBar is true. // Seeking past the end of the last window should seek to the end of the timeline.
throw new IllegalStateException(); positionMs = windowDurationMs;
} break;
if (j == window.firstPeriodIndex) {
periodDurationMs -= window.getPositionInFirstPeriodMs();
}
if (i == windowCount - 1 && j == window.lastPeriodIndex
&& remainingMs >= periodDurationMs) {
// Seeking past the end of the last window should seek to the end of the timeline.
seekTo(i, window.getDurationMs());
return;
}
if (remainingMs < periodDurationMs) {
seekTo(i, period.getPositionInWindowMs() + remainingMs);
return;
}
remainingMs -= periodDurationMs;
} }
positionMs -= windowDurationMs;
windowIndex++;
} }
} else { } else {
seekTo(timebarPositionMs); windowIndex = player.getCurrentWindowIndex();
} }
seekTo(windowIndex, positionMs);
} }
@Override @Override
@ -1028,16 +1016,16 @@ public class PlaybackControlView extends FrameLayout {
* Returns whether the specified {@code timeline} can be shown on a multi-window time bar. * Returns whether the specified {@code timeline} can be shown on a multi-window time bar.
* *
* @param timeline The {@link Timeline} to check. * @param timeline The {@link Timeline} to check.
* @param period A scratch {@link Timeline.Period} instance. * @param window A scratch {@link Timeline.Window} instance.
* @return Whether the specified timeline can be shown on a multi-window time bar. * @return Whether the specified timeline can be shown on a multi-window time bar.
*/ */
private static boolean canShowMultiWindowTimeBar(Timeline timeline, Timeline.Period period) { private static boolean canShowMultiWindowTimeBar(Timeline timeline, Timeline.Window window) {
if (timeline.getWindowCount() > MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR) { if (timeline.getWindowCount() > MAX_WINDOWS_FOR_MULTI_WINDOW_TIME_BAR) {
return false; return false;
} }
int periodCount = timeline.getPeriodCount(); int windowCount = timeline.getWindowCount();
for (int i = 0; i < periodCount; i++) { for (int i = 0; i < windowCount; i++) {
if (timeline.getPeriod(i, period).durationUs == C.TIME_UNSET) { if (timeline.getWindow(i, window).durationUs == C.TIME_UNSET) {
return false; return false;
} }
} }