Pull IMA cuePoints -> adGroupTimesUs logic into a helper class
We're then able to use this same helper class from tests, to avoid running into spurious failures caused by long microseconds being round-tripped through float seconds. PiperOrigin-RevId: 316435084
This commit is contained in:
parent
1ce040003a
commit
a0e90ce1ff
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.google.android.exoplayer2.ext.ima;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static utility class for constructing {@link AdPlaybackState} instances from IMA-specific data.
|
||||||
|
*/
|
||||||
|
/* package */ final class AdPlaybackStateFactory {
|
||||||
|
private AdPlaybackStateFactory() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an {@link AdPlaybackState} from the provided {@code cuePoints}.
|
||||||
|
*
|
||||||
|
* @param cuePoints The cue points of the ads in seconds.
|
||||||
|
* @return The {@link AdPlaybackState}.
|
||||||
|
*/
|
||||||
|
public static AdPlaybackState fromCuePoints(List<Float> cuePoints) {
|
||||||
|
if (cuePoints.isEmpty()) {
|
||||||
|
// If no cue points are specified, there is a preroll ad.
|
||||||
|
return new AdPlaybackState(/* adGroupTimesUs...= */ 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = cuePoints.size();
|
||||||
|
long[] adGroupTimesUs = new long[count];
|
||||||
|
int adGroupIndex = 0;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
double cuePoint = cuePoints.get(i);
|
||||||
|
if (cuePoint == -1.0) {
|
||||||
|
adGroupTimesUs[count - 1] = C.TIME_END_OF_SOURCE;
|
||||||
|
} else {
|
||||||
|
adGroupTimesUs[adGroupIndex++] = (long) (C.MICROS_PER_SECOND * cuePoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cue points may be out of order, so sort them.
|
||||||
|
Arrays.sort(adGroupTimesUs, 0, adGroupIndex);
|
||||||
|
return new AdPlaybackState(adGroupTimesUs);
|
||||||
|
}
|
||||||
|
}
|
@ -662,7 +662,7 @@ public final class ImaAdsLoader
|
|||||||
adsManager.resume();
|
adsManager.resume();
|
||||||
}
|
}
|
||||||
} else if (adsManager != null) {
|
} else if (adsManager != null) {
|
||||||
adPlaybackState = new AdPlaybackState(getAdGroupTimesUs(adsManager.getAdCuePoints()));
|
adPlaybackState = AdPlaybackStateFactory.fromCuePoints(adsManager.getAdCuePoints());
|
||||||
updateAdPlaybackState();
|
updateAdPlaybackState();
|
||||||
} else {
|
} else {
|
||||||
// Ads haven't loaded yet, so request them.
|
// Ads haven't loaded yet, so request them.
|
||||||
@ -739,7 +739,7 @@ public final class ImaAdsLoader
|
|||||||
if (player != null) {
|
if (player != null) {
|
||||||
// If a player is attached already, start playback immediately.
|
// If a player is attached already, start playback immediately.
|
||||||
try {
|
try {
|
||||||
adPlaybackState = new AdPlaybackState(getAdGroupTimesUs(adsManager.getAdCuePoints()));
|
adPlaybackState = AdPlaybackStateFactory.fromCuePoints(adsManager.getAdCuePoints());
|
||||||
hasAdPlaybackState = true;
|
hasAdPlaybackState = true;
|
||||||
updateAdPlaybackState();
|
updateAdPlaybackState();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
@ -1545,28 +1545,6 @@ public final class ImaAdsLoader
|
|||||||
: timeline.getPeriod(/* periodIndex= */ 0, period).getPositionInWindowMs());
|
: timeline.getPeriod(/* periodIndex= */ 0, period).getPositionInWindowMs());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long[] getAdGroupTimesUs(List<Float> cuePoints) {
|
|
||||||
if (cuePoints.isEmpty()) {
|
|
||||||
// If no cue points are specified, there is a preroll ad.
|
|
||||||
return new long[] {0};
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = cuePoints.size();
|
|
||||||
long[] adGroupTimesUs = new long[count];
|
|
||||||
int adGroupIndex = 0;
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
double cuePoint = cuePoints.get(i);
|
|
||||||
if (cuePoint == -1.0) {
|
|
||||||
adGroupTimesUs[count - 1] = C.TIME_END_OF_SOURCE;
|
|
||||||
} else {
|
|
||||||
adGroupTimesUs[adGroupIndex++] = (long) (C.MICROS_PER_SECOND * cuePoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Cue points may be out of order, so sort them.
|
|
||||||
Arrays.sort(adGroupTimesUs, 0, adGroupIndex);
|
|
||||||
return adGroupTimesUs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isAdGroupLoadError(AdError adError) {
|
private static boolean isAdGroupLoadError(AdError adError) {
|
||||||
// TODO: Find out what other errors need to be handled (if any), and whether each one relates to
|
// TODO: Find out what other errors need to be handled (if any), and whether each one relates to
|
||||||
// a single ad, ad group or the whole timeline.
|
// a single ad, ad group or the whole timeline.
|
||||||
|
@ -58,6 +58,7 @@ import com.google.android.exoplayer2.source.ads.SinglePeriodAdTimeline;
|
|||||||
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
import com.google.android.exoplayer2.testutil.FakeTimeline;
|
||||||
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
import com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -93,7 +94,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
private static final Uri TEST_URI = Uri.EMPTY;
|
private static final Uri TEST_URI = Uri.EMPTY;
|
||||||
private static final AdMediaInfo TEST_AD_MEDIA_INFO = new AdMediaInfo(TEST_URI.toString());
|
private static final AdMediaInfo TEST_AD_MEDIA_INFO = new AdMediaInfo(TEST_URI.toString());
|
||||||
private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND;
|
private static final long TEST_AD_DURATION_US = 5 * C.MICROS_PER_SECOND;
|
||||||
private static final Float[] PREROLL_CUE_POINTS_SECONDS = new Float[] {0f};
|
private static final ImmutableList<Float> PREROLL_CUE_POINTS_SECONDS = ImmutableList.of(0f);
|
||||||
|
|
||||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||||
|
|
||||||
@ -256,7 +257,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void playback_withPostrollFetchError_marksAdAsInErrorState() {
|
public void playback_withPostrollFetchError_marksAdAsInErrorState() {
|
||||||
setupPlayback(CONTENT_TIMELINE, new Float[] {-1f});
|
setupPlayback(CONTENT_TIMELINE, ImmutableList.of(-1f));
|
||||||
|
|
||||||
// Simulate loading an empty postroll ad.
|
// Simulate loading an empty postroll ad.
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -275,9 +276,9 @@ public final class ImaAdsLoaderTest {
|
|||||||
public void playback_withAdNotPreloadingBeforeTimeout_hasNoError() {
|
public void playback_withAdNotPreloadingBeforeTimeout_hasNoError() {
|
||||||
// Simulate an ad at 2 seconds.
|
// Simulate an ad at 2 seconds.
|
||||||
long adGroupPositionInWindowUs = 2 * C.MICROS_PER_SECOND;
|
long adGroupPositionInWindowUs = 2 * C.MICROS_PER_SECOND;
|
||||||
setupPlayback(
|
long adGroupTimeUs = adGroupPositionInWindowUs;
|
||||||
CONTENT_TIMELINE,
|
ImmutableList<Float> cuePoints = ImmutableList.of((float) adGroupTimeUs / C.MICROS_PER_SECOND);
|
||||||
new Float[] {(float) adGroupPositionInWindowUs / C.MICROS_PER_SECOND});
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
|
|
||||||
// Advance playback to just before the midroll and simulate buffering.
|
// Advance playback to just before the midroll and simulate buffering.
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -289,7 +290,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
|
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ adGroupPositionInWindowUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,9 +298,9 @@ public final class ImaAdsLoaderTest {
|
|||||||
public void playback_withAdNotPreloadingAfterTimeout_hasErrorAdGroup() {
|
public void playback_withAdNotPreloadingAfterTimeout_hasErrorAdGroup() {
|
||||||
// Simulate an ad at 2 seconds.
|
// Simulate an ad at 2 seconds.
|
||||||
long adGroupPositionInWindowUs = 2 * C.MICROS_PER_SECOND;
|
long adGroupPositionInWindowUs = 2 * C.MICROS_PER_SECOND;
|
||||||
setupPlayback(
|
long adGroupTimeUs = adGroupPositionInWindowUs;
|
||||||
CONTENT_TIMELINE,
|
ImmutableList<Float> cuePoints = ImmutableList.of((float) adGroupTimeUs / C.MICROS_PER_SECOND);
|
||||||
new Float[] {(float) adGroupPositionInWindowUs / C.MICROS_PER_SECOND});
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
|
|
||||||
// Advance playback to just before the midroll and simulate buffering.
|
// Advance playback to just before the midroll and simulate buffering.
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -311,7 +312,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
|
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ adGroupPositionInWindowUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}})
|
.withAdDurationsUs(new long[][] {{TEST_AD_DURATION_US}})
|
||||||
.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1)
|
.withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1)
|
||||||
@ -321,10 +322,10 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackBeforeMidroll_playsPreroll() {
|
public void resumePlaybackBeforeMidroll_playsPreroll() {
|
||||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long midrollPeriodTimeUs =
|
long midrollPeriodTimeUs = midrollWindowTimeUs;
|
||||||
midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList<Float> cuePoints =
|
||||||
setupPlayback(
|
ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
CONTENT_TIMELINE, new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND});
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
|
|
||||||
fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs) - 1_000);
|
fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs) - 1_000);
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -332,17 +333,17 @@ public final class ImaAdsLoaderTest {
|
|||||||
verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble());
|
verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble());
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resumePlaybackAtMidroll_skipsPreroll() {
|
public void resumePlaybackAtMidroll_skipsPreroll() {
|
||||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long midrollPeriodTimeUs =
|
long midrollPeriodTimeUs = midrollWindowTimeUs;
|
||||||
midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList<Float> cuePoints =
|
||||||
setupPlayback(
|
ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
CONTENT_TIMELINE, new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND});
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
|
|
||||||
fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs));
|
fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs));
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -355,7 +356,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
||||||
}
|
}
|
||||||
@ -363,10 +364,10 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackAfterMidroll_skipsPreroll() {
|
public void resumePlaybackAfterMidroll_skipsPreroll() {
|
||||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long midrollPeriodTimeUs =
|
long midrollPeriodTimeUs = midrollWindowTimeUs;
|
||||||
midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList<Float> cuePoints =
|
||||||
setupPlayback(
|
ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
CONTENT_TIMELINE, new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND});
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
|
|
||||||
fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs) + 1_000);
|
fakeExoPlayer.setPlayingContentPosition(C.usToMs(midrollWindowTimeUs) + 1_000);
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -379,7 +380,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
||||||
}
|
}
|
||||||
@ -387,19 +388,14 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackBeforeSecondMidroll_playsFirstMidroll() {
|
public void resumePlaybackBeforeSecondMidroll_playsFirstMidroll() {
|
||||||
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long firstMidrollPeriodTimeUs =
|
long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs;
|
||||||
firstMidrollWindowTimeUs
|
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
|
||||||
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
||||||
long secondMidrollPeriodTimeUs =
|
long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs;
|
||||||
secondMidrollWindowTimeUs
|
ImmutableList<Float> cuePoints =
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList.of(
|
||||||
setupPlayback(
|
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
||||||
CONTENT_TIMELINE,
|
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
new Float[] {
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
|
||||||
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND
|
|
||||||
});
|
|
||||||
|
|
||||||
fakeExoPlayer.setPlayingContentPosition(C.usToMs(secondMidrollWindowTimeUs) - 1_000);
|
fakeExoPlayer.setPlayingContentPosition(C.usToMs(secondMidrollWindowTimeUs) - 1_000);
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -407,27 +403,21 @@ public final class ImaAdsLoaderTest {
|
|||||||
verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble());
|
verify(mockAdsRenderingSettings, never()).setPlayAdsAfterTime(anyDouble());
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
/* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs)
|
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void resumePlaybackAtSecondMidroll_skipsFirstMidroll() {
|
public void resumePlaybackAtSecondMidroll_skipsFirstMidroll() {
|
||||||
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long firstMidrollPeriodTimeUs =
|
long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs;
|
||||||
firstMidrollWindowTimeUs
|
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
|
||||||
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
||||||
long secondMidrollPeriodTimeUs =
|
long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs;
|
||||||
secondMidrollWindowTimeUs
|
ImmutableList<Float> cuePoints =
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList.of(
|
||||||
setupPlayback(
|
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
||||||
CONTENT_TIMELINE,
|
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
new Float[] {
|
setupPlayback(CONTENT_TIMELINE, cuePoints);
|
||||||
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
|
||||||
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND
|
|
||||||
});
|
|
||||||
|
|
||||||
fakeExoPlayer.setPlayingContentPosition(C.usToMs(secondMidrollWindowTimeUs));
|
fakeExoPlayer.setPlayingContentPosition(C.usToMs(secondMidrollWindowTimeUs));
|
||||||
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
imaAdsLoader.start(adsLoaderListener, adViewProvider);
|
||||||
@ -440,8 +430,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
/* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs)
|
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
||||||
}
|
}
|
||||||
@ -449,11 +438,12 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackBeforeMidroll_withoutPlayAdBeforeStartPosition_skipsPreroll() {
|
public void resumePlaybackBeforeMidroll_withoutPlayAdBeforeStartPosition_skipsPreroll() {
|
||||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long midrollPeriodTimeUs =
|
long midrollPeriodTimeUs = midrollWindowTimeUs;
|
||||||
midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList<Float> cuePoints =
|
||||||
|
ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
setupPlayback(
|
setupPlayback(
|
||||||
CONTENT_TIMELINE,
|
CONTENT_TIMELINE,
|
||||||
new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND},
|
cuePoints,
|
||||||
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
||||||
.setPlayAdBeforeStartPosition(false)
|
.setPlayAdBeforeStartPosition(false)
|
||||||
.setImaFactory(mockImaFactory)
|
.setImaFactory(mockImaFactory)
|
||||||
@ -471,7 +461,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0)
|
.withSkippedAdGroup(/* adGroupIndex= */ 0)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
||||||
}
|
}
|
||||||
@ -479,11 +469,12 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackAtMidroll_withoutPlayAdBeforeStartPosition_skipsPreroll() {
|
public void resumePlaybackAtMidroll_withoutPlayAdBeforeStartPosition_skipsPreroll() {
|
||||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long midrollPeriodTimeUs =
|
long midrollPeriodTimeUs = midrollWindowTimeUs;
|
||||||
midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList<Float> cuePoints =
|
||||||
|
ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
setupPlayback(
|
setupPlayback(
|
||||||
CONTENT_TIMELINE,
|
CONTENT_TIMELINE,
|
||||||
new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND},
|
cuePoints,
|
||||||
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
||||||
.setPlayAdBeforeStartPosition(false)
|
.setPlayAdBeforeStartPosition(false)
|
||||||
.setImaFactory(mockImaFactory)
|
.setImaFactory(mockImaFactory)
|
||||||
@ -501,7 +492,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
||||||
}
|
}
|
||||||
@ -509,11 +500,12 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackAfterMidroll_withoutPlayAdBeforeStartPosition_skipsMidroll() {
|
public void resumePlaybackAfterMidroll_withoutPlayAdBeforeStartPosition_skipsMidroll() {
|
||||||
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long midrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long midrollPeriodTimeUs =
|
long midrollPeriodTimeUs = midrollWindowTimeUs;
|
||||||
midrollWindowTimeUs + TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList<Float> cuePoints =
|
||||||
|
ImmutableList.of(0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
setupPlayback(
|
setupPlayback(
|
||||||
CONTENT_TIMELINE,
|
CONTENT_TIMELINE,
|
||||||
new Float[] {0f, (float) midrollPeriodTimeUs / C.MICROS_PER_SECOND},
|
cuePoints,
|
||||||
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
||||||
.setPlayAdBeforeStartPosition(false)
|
.setPlayAdBeforeStartPosition(false)
|
||||||
.setImaFactory(mockImaFactory)
|
.setImaFactory(mockImaFactory)
|
||||||
@ -526,7 +518,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
verify(mockAdsManager).destroy();
|
verify(mockAdsManager).destroy();
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(/* adGroupTimesUs...= */ 0, midrollPeriodTimeUs)
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0)
|
.withSkippedAdGroup(/* adGroupIndex= */ 0)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 1));
|
.withSkippedAdGroup(/* adGroupIndex= */ 1));
|
||||||
@ -536,19 +528,16 @@ public final class ImaAdsLoaderTest {
|
|||||||
public void
|
public void
|
||||||
resumePlaybackBeforeSecondMidroll_withoutPlayAdBeforeStartPosition_skipsFirstMidroll() {
|
resumePlaybackBeforeSecondMidroll_withoutPlayAdBeforeStartPosition_skipsFirstMidroll() {
|
||||||
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long firstMidrollPeriodTimeUs =
|
long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs;
|
||||||
firstMidrollWindowTimeUs
|
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
|
||||||
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
||||||
long secondMidrollPeriodTimeUs =
|
long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs;
|
||||||
secondMidrollWindowTimeUs
|
ImmutableList<Float> cuePoints =
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList.of(
|
||||||
|
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
||||||
|
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
setupPlayback(
|
setupPlayback(
|
||||||
CONTENT_TIMELINE,
|
CONTENT_TIMELINE,
|
||||||
new Float[] {
|
cuePoints,
|
||||||
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
|
||||||
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND
|
|
||||||
},
|
|
||||||
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
||||||
.setPlayAdBeforeStartPosition(false)
|
.setPlayAdBeforeStartPosition(false)
|
||||||
.setImaFactory(mockImaFactory)
|
.setImaFactory(mockImaFactory)
|
||||||
@ -566,8 +555,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
/* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs)
|
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0)
|
.withSkippedAdGroup(/* adGroupIndex= */ 0)
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US));
|
||||||
}
|
}
|
||||||
@ -575,19 +563,16 @@ public final class ImaAdsLoaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void resumePlaybackAtSecondMidroll_withoutPlayAdBeforeStartPosition_skipsFirstMidroll() {
|
public void resumePlaybackAtSecondMidroll_withoutPlayAdBeforeStartPosition_skipsFirstMidroll() {
|
||||||
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
long firstMidrollWindowTimeUs = 2 * C.MICROS_PER_SECOND;
|
||||||
long firstMidrollPeriodTimeUs =
|
long firstMidrollPeriodTimeUs = firstMidrollWindowTimeUs;
|
||||||
firstMidrollWindowTimeUs
|
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
|
||||||
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
long secondMidrollWindowTimeUs = 4 * C.MICROS_PER_SECOND;
|
||||||
long secondMidrollPeriodTimeUs =
|
long secondMidrollPeriodTimeUs = secondMidrollWindowTimeUs;
|
||||||
secondMidrollWindowTimeUs
|
ImmutableList<Float> cuePoints =
|
||||||
+ TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
|
ImmutableList.of(
|
||||||
|
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
||||||
|
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND);
|
||||||
setupPlayback(
|
setupPlayback(
|
||||||
CONTENT_TIMELINE,
|
CONTENT_TIMELINE,
|
||||||
new Float[] {
|
cuePoints,
|
||||||
(float) firstMidrollPeriodTimeUs / C.MICROS_PER_SECOND,
|
|
||||||
(float) secondMidrollPeriodTimeUs / C.MICROS_PER_SECOND
|
|
||||||
},
|
|
||||||
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
new ImaAdsLoader.Builder(ApplicationProvider.getApplicationContext())
|
||||||
.setPlayAdBeforeStartPosition(false)
|
.setPlayAdBeforeStartPosition(false)
|
||||||
.setImaFactory(mockImaFactory)
|
.setImaFactory(mockImaFactory)
|
||||||
@ -605,8 +590,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
.of(expectedPlayAdsAfterTimeUs / C.MICROS_PER_SECOND);
|
||||||
assertThat(adsLoaderListener.adPlaybackState)
|
assertThat(adsLoaderListener.adPlaybackState)
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
new AdPlaybackState(
|
AdPlaybackStateFactory.fromCuePoints(cuePoints)
|
||||||
/* adGroupTimesUs...= */ firstMidrollPeriodTimeUs, secondMidrollPeriodTimeUs)
|
|
||||||
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
.withContentDurationUs(CONTENT_PERIOD_DURATION_US)
|
||||||
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
.withSkippedAdGroup(/* adGroupIndex= */ 0));
|
||||||
}
|
}
|
||||||
@ -623,7 +607,7 @@ public final class ImaAdsLoaderTest {
|
|||||||
inOrder.verify(mockAdDisplayContainer).unregisterAllVideoControlsOverlays();
|
inOrder.verify(mockAdDisplayContainer).unregisterAllVideoControlsOverlays();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupPlayback(Timeline contentTimeline, Float[] cuePoints) {
|
private void setupPlayback(Timeline contentTimeline, List<Float> cuePoints) {
|
||||||
setupPlayback(
|
setupPlayback(
|
||||||
contentTimeline,
|
contentTimeline,
|
||||||
cuePoints,
|
cuePoints,
|
||||||
@ -634,10 +618,10 @@ public final class ImaAdsLoaderTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setupPlayback(
|
private void setupPlayback(
|
||||||
Timeline contentTimeline, Float[] cuePoints, ImaAdsLoader imaAdsLoader) {
|
Timeline contentTimeline, List<Float> cuePoints, ImaAdsLoader imaAdsLoader) {
|
||||||
fakeExoPlayer = new FakePlayer();
|
fakeExoPlayer = new FakePlayer();
|
||||||
adsLoaderListener = new TestAdsLoaderListener(fakeExoPlayer, contentTimeline);
|
adsLoaderListener = new TestAdsLoaderListener(fakeExoPlayer, contentTimeline);
|
||||||
when(mockAdsManager.getAdCuePoints()).thenReturn(Arrays.asList(cuePoints));
|
when(mockAdsManager.getAdCuePoints()).thenReturn(cuePoints);
|
||||||
this.imaAdsLoader = imaAdsLoader;
|
this.imaAdsLoader = imaAdsLoader;
|
||||||
imaAdsLoader.setPlayer(fakeExoPlayer);
|
imaAdsLoader.setPlayer(fakeExoPlayer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user