Skip played live ad media periods
This change makes sure that live ad periods that are played are skip when attempted to be added to the queue. To make this work the existing filter logic had to be take into account the content resume offset that live periods use. PiperOrigin-RevId: 518068138
This commit is contained in:
parent
fca9197e1c
commit
0a2a20d4fb
@ -441,7 +441,8 @@ public class TimelineTest {
|
|||||||
/* nowUs= */ 60_000_000,
|
/* nowUs= */ 60_000_000,
|
||||||
/* adSequencePattern= */ new boolean[] {false, true, true},
|
/* adSequencePattern= */ new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ false,
|
/* isContentTimeline= */ false,
|
||||||
/* populateAds= */ true);
|
/* populateAds= */ true,
|
||||||
|
/* playedAds= */ false);
|
||||||
|
|
||||||
assertThat(timeline.getPeriodCount()).isEqualTo(4);
|
assertThat(timeline.getPeriodCount()).isEqualTo(4);
|
||||||
assertThat(
|
assertThat(
|
||||||
|
@ -474,13 +474,10 @@ import com.google.common.collect.ImmutableList;
|
|||||||
Timeline.Period period) {
|
Timeline.Period period) {
|
||||||
timeline.getPeriodByUid(periodUid, period);
|
timeline.getPeriodByUid(periodUid, period);
|
||||||
timeline.getWindow(period.windowIndex, window);
|
timeline.getWindow(period.windowIndex, window);
|
||||||
int periodIndex = timeline.getIndexOfPeriod(periodUid);
|
|
||||||
// Skip ignorable server side inserted ad periods.
|
// Skip ignorable server side inserted ad periods.
|
||||||
while ((period.durationUs == 0
|
for (int periodIndex = timeline.getIndexOfPeriod(periodUid);
|
||||||
&& period.getAdGroupCount() > 0
|
isSkippableAdPeriod(period) && periodIndex <= window.lastPeriodIndex;
|
||||||
&& period.isServerSideInsertedAdGroup(period.getRemovedAdGroupCount())
|
periodIndex++) {
|
||||||
&& period.getAdGroupIndexForPositionUs(0) == C.INDEX_UNSET)
|
|
||||||
&& periodIndex++ < window.lastPeriodIndex) {
|
|
||||||
timeline.getPeriod(periodIndex, period, /* setIds= */ true);
|
timeline.getPeriod(periodIndex, period, /* setIds= */ true);
|
||||||
periodUid = checkNotNull(period.uid);
|
periodUid = checkNotNull(period.uid);
|
||||||
}
|
}
|
||||||
@ -495,6 +492,26 @@ import com.google.common.collect.ImmutableList;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isSkippableAdPeriod(Timeline.Period period) {
|
||||||
|
int adGroupCount = period.getAdGroupCount();
|
||||||
|
if (adGroupCount == 0
|
||||||
|
|| (adGroupCount == 1 && period.isLivePostrollPlaceholder(/* adGroupIndex= */ 0))
|
||||||
|
|| !period.isServerSideInsertedAdGroup(period.getRemovedAdGroupCount())
|
||||||
|
|| period.getAdGroupIndexForPositionUs(0L) != C.INDEX_UNSET) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (period.durationUs == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
long contentResumeOffsetUs = 0;
|
||||||
|
int lastIndexInclusive =
|
||||||
|
adGroupCount - (period.isLivePostrollPlaceholder(adGroupCount - 1) ? 2 : 1);
|
||||||
|
for (int i = 0; i <= lastIndexInclusive; i++) {
|
||||||
|
contentResumeOffsetUs += period.getContentResumeOffsetUs(/* adGroupIndex= */ i);
|
||||||
|
}
|
||||||
|
return period.durationUs <= contentResumeOffsetUs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the specified timeline period and position to a {@link MediaPeriodId} that should be
|
* Resolves the specified timeline period and position to a {@link MediaPeriodId} that should be
|
||||||
* played after a period position change, returning an identifier for an ad group if one needs to
|
* played after a period position change, returning an identifier for an ad group if one needs to
|
||||||
|
@ -438,7 +438,8 @@ public final class MediaPeriodQueueTest {
|
|||||||
/* nowUs= */ 110_000_000,
|
/* nowUs= */ 110_000_000,
|
||||||
new boolean[] {false, true, true},
|
new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
setupTimeline(multiPeriodLiveTimeline);
|
setupTimeline(multiPeriodLiveTimeline);
|
||||||
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
||||||
/* periodUid= */ firstPeriodUid,
|
/* periodUid= */ firstPeriodUid,
|
||||||
@ -504,7 +505,8 @@ public final class MediaPeriodQueueTest {
|
|||||||
/* nowUs= */ 110_000_000,
|
/* nowUs= */ 110_000_000,
|
||||||
new boolean[] {false, true, true},
|
new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ false,
|
/* isContentTimeline= */ false,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
setupTimeline(multiPeriodLiveTimeline);
|
setupTimeline(multiPeriodLiveTimeline);
|
||||||
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
||||||
/* periodUid= */ firstPeriodUid,
|
/* periodUid= */ firstPeriodUid,
|
||||||
@ -569,7 +571,8 @@ public final class MediaPeriodQueueTest {
|
|||||||
/* nowUs= */ 110_000_000,
|
/* nowUs= */ 110_000_000,
|
||||||
new boolean[] {false, true, true},
|
new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ false,
|
/* isContentTimeline= */ false,
|
||||||
/* populateAds= */ true);
|
/* populateAds= */ true,
|
||||||
|
/* playedAds= */ false);
|
||||||
setupTimeline(multiPeriodLiveTimeline);
|
setupTimeline(multiPeriodLiveTimeline);
|
||||||
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
||||||
/* periodUid= */ firstPeriodUid,
|
/* periodUid= */ firstPeriodUid,
|
||||||
@ -638,6 +641,47 @@ public final class MediaPeriodQueueTest {
|
|||||||
assertThat(getNextMediaPeriodInfo()).isNull();
|
assertThat(getNextMediaPeriodInfo()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void getNextMediaPeriodInfo_multiPeriodTimelineWithPlayedAdsAndWithPostRollPlaceHolder() {
|
||||||
|
long contentPeriodDurationUs = FakeMultiPeriodLiveTimeline.PERIOD_DURATION_US;
|
||||||
|
FakeMultiPeriodLiveTimeline multiPeriodLiveTimeline =
|
||||||
|
new FakeMultiPeriodLiveTimeline(
|
||||||
|
/* availabilityStartTimeUs= */ 0,
|
||||||
|
/* liveWindowDurationUs= */ 60_000_000,
|
||||||
|
/* nowUs= */ 110_000_000,
|
||||||
|
new boolean[] {false, true, true},
|
||||||
|
/* isContentTimeline= */ false,
|
||||||
|
/* populateAds= */ true,
|
||||||
|
/* playedAds= */ true);
|
||||||
|
setupTimeline(multiPeriodLiveTimeline);
|
||||||
|
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
||||||
|
/* periodUid= */ firstPeriodUid,
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
|
/* requestedContentPositionUs= */ C.TIME_UNSET,
|
||||||
|
/* endPositionUs= */ C.TIME_UNSET,
|
||||||
|
/* durationUs= */ contentPeriodDurationUs,
|
||||||
|
/* isFollowedByTransitionToSameStream= */ false,
|
||||||
|
/* isLastInPeriod= */ false,
|
||||||
|
/* isLastInWindow= */ false,
|
||||||
|
/* isFinal= */ false,
|
||||||
|
/* nextAdGroupIndex= */ 0);
|
||||||
|
advance();
|
||||||
|
assertGetNextMediaPeriodInfoReturnsContentMediaPeriod(
|
||||||
|
new Pair<Object, Object>(((Pair<Object, Object>) firstPeriodUid).first, "uid-6[c]"),
|
||||||
|
/* startPositionUs= */ 0,
|
||||||
|
/* requestedContentPositionUs= */ 0,
|
||||||
|
/* endPositionUs= */ C.TIME_UNSET,
|
||||||
|
/* durationUs= */ C.TIME_UNSET, // Last period in stream.
|
||||||
|
/* isFollowedByTransitionToSameStream= */ false,
|
||||||
|
/* isLastInPeriod= */ false,
|
||||||
|
/* isLastInWindow= */ false,
|
||||||
|
/* isFinal= */ false,
|
||||||
|
/* nextAdGroupIndex= */ 0);
|
||||||
|
advance();
|
||||||
|
assertThat(getNextMediaPeriodInfo()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getNextMediaPeriodInfo_withPostrollLoadError_returnsEmptyFinalMediaPeriodInfo() {
|
public void getNextMediaPeriodInfo_withPostrollLoadError_returnsEmptyFinalMediaPeriodInfo() {
|
||||||
setupAdTimeline(/* adGroupTimesUs...= */ C.TIME_END_OF_SOURCE);
|
setupAdTimeline(/* adGroupTimesUs...= */ C.TIME_END_OF_SOURCE);
|
||||||
|
@ -566,7 +566,8 @@ public class ImaUtilTest {
|
|||||||
/* nowUs= */ 150_000_000,
|
/* nowUs= */ 150_000_000,
|
||||||
/* adSequencePattern= */ new boolean[] {false, true, true},
|
/* adSequencePattern= */ new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
// Ad event received from SDK around 130s.
|
// Ad event received from SDK around 130s.
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
addLiveAdBreak(
|
addLiveAdBreak(
|
||||||
@ -855,7 +856,8 @@ public class ImaUtilTest {
|
|||||||
/* nowUs= */ 59_999_999,
|
/* nowUs= */ 59_999_999,
|
||||||
/* adSequencePattern= */ new boolean[] {false, true, true},
|
/* adSequencePattern= */ new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
// Ad event received from SDK around 30s.
|
// Ad event received from SDK around 30s.
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
addLiveAdBreak(
|
addLiveAdBreak(
|
||||||
@ -1296,7 +1298,8 @@ public class ImaUtilTest {
|
|||||||
/* nowUs= */ 150_000_000,
|
/* nowUs= */ 150_000_000,
|
||||||
/* adSequencePattern= */ new boolean[] {false, true, true},
|
/* adSequencePattern= */ new boolean[] {false, true, true},
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
AdPlaybackState adPlaybackState =
|
AdPlaybackState adPlaybackState =
|
||||||
new AdPlaybackState("adsId").withLivePostrollPlaceholderAppended();
|
new AdPlaybackState("adsId").withLivePostrollPlaceholderAppended();
|
||||||
adPlaybackState =
|
adPlaybackState =
|
||||||
|
@ -57,6 +57,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
private final long liveWindowDurationUs;
|
private final long liveWindowDurationUs;
|
||||||
private final boolean isContentTimeline;
|
private final boolean isContentTimeline;
|
||||||
private final boolean populateAds;
|
private final boolean populateAds;
|
||||||
|
private final boolean playedAds;
|
||||||
|
|
||||||
private long nowUs;
|
private long nowUs;
|
||||||
private ImmutableList<PeriodData> periods;
|
private ImmutableList<PeriodData> periods;
|
||||||
@ -72,7 +73,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
* @param isContentTimeline Whether the timeline is a content timeline without {@link
|
* @param isContentTimeline Whether the timeline is a content timeline without {@link
|
||||||
* AdPlaybackState}s.
|
* AdPlaybackState}s.
|
||||||
* @param populateAds Whether to populate ads like after the ad event has been received. This
|
* @param populateAds Whether to populate ads like after the ad event has been received. This
|
||||||
* parameter is ignored if the timeline is a content timeline.
|
* @param playedAds Whether ads should be marked as played if populated.
|
||||||
*/
|
*/
|
||||||
public FakeMultiPeriodLiveTimeline(
|
public FakeMultiPeriodLiveTimeline(
|
||||||
long availabilityStartTimeUs,
|
long availabilityStartTimeUs,
|
||||||
@ -80,7 +81,8 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
long nowUs,
|
long nowUs,
|
||||||
boolean[] adSequencePattern,
|
boolean[] adSequencePattern,
|
||||||
boolean isContentTimeline,
|
boolean isContentTimeline,
|
||||||
boolean populateAds) {
|
boolean populateAds,
|
||||||
|
boolean playedAds) {
|
||||||
checkArgument(nowUs - liveWindowDurationUs >= availabilityStartTimeUs);
|
checkArgument(nowUs - liveWindowDurationUs >= availabilityStartTimeUs);
|
||||||
this.availabilityStartTimeUs = availabilityStartTimeUs;
|
this.availabilityStartTimeUs = availabilityStartTimeUs;
|
||||||
this.liveWindowDurationUs = liveWindowDurationUs;
|
this.liveWindowDurationUs = liveWindowDurationUs;
|
||||||
@ -88,6 +90,7 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
this.adSequencePattern = Arrays.copyOf(adSequencePattern, adSequencePattern.length);
|
this.adSequencePattern = Arrays.copyOf(adSequencePattern, adSequencePattern.length);
|
||||||
this.isContentTimeline = isContentTimeline;
|
this.isContentTimeline = isContentTimeline;
|
||||||
this.populateAds = populateAds;
|
this.populateAds = populateAds;
|
||||||
|
this.playedAds = playedAds;
|
||||||
mediaItem = new MediaItem.Builder().build();
|
mediaItem = new MediaItem.Builder().build();
|
||||||
periods =
|
periods =
|
||||||
invalidate(
|
invalidate(
|
||||||
@ -96,7 +99,8 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
nowUs,
|
nowUs,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
isContentTimeline,
|
isContentTimeline,
|
||||||
populateAds);
|
populateAds,
|
||||||
|
playedAds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Calculates the total duration of the given ad period sequence. */
|
/** Calculates the total duration of the given ad period sequence. */
|
||||||
@ -118,7 +122,8 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
nowUs,
|
nowUs,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
isContentTimeline,
|
isContentTimeline,
|
||||||
populateAds);
|
populateAds,
|
||||||
|
playedAds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -188,7 +193,8 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
long now,
|
long now,
|
||||||
boolean[] adSequencePattern,
|
boolean[] adSequencePattern,
|
||||||
boolean isContentTimeline,
|
boolean isContentTimeline,
|
||||||
boolean populateAds) {
|
boolean populateAds,
|
||||||
|
boolean playedAds) {
|
||||||
long windowStartTimeUs = now - liveWindowDurationUs;
|
long windowStartTimeUs = now - liveWindowDurationUs;
|
||||||
int sequencePeriodCount = adSequencePattern.length;
|
int sequencePeriodCount = adSequencePattern.length;
|
||||||
long sequenceDurationUs = calculateAdSequencePatternDurationUs(adSequencePattern);
|
long sequenceDurationUs = calculateAdSequencePatternDurationUs(adSequencePattern);
|
||||||
@ -226,6 +232,10 @@ public class FakeMultiPeriodLiveTimeline extends Timeline {
|
|||||||
/* adGroupIndex= */ 0, /* adDurationsUs...= */ periodDurationUs)
|
/* adGroupIndex= */ 0, /* adDurationsUs...= */ periodDurationUs)
|
||||||
.withContentResumeOffsetUs(
|
.withContentResumeOffsetUs(
|
||||||
/* adGroupIndex= */ 0, /* contentResumeOffsetUs= */ periodDurationUs);
|
/* adGroupIndex= */ 0, /* contentResumeOffsetUs= */ periodDurationUs);
|
||||||
|
if (playedAds) {
|
||||||
|
adPlaybackState =
|
||||||
|
adPlaybackState.withPlayedAd(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
liveWindow.add(
|
liveWindow.add(
|
||||||
|
@ -43,7 +43,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
/* nowUs= */ 60_000_000L,
|
/* nowUs= */ 60_000_000L,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
|
|
||||||
@ -79,7 +80,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
/* nowUs= */ 100_000_000L,
|
/* nowUs= */ 100_000_000L,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
/* isContentTimeline= */ false,
|
/* isContentTimeline= */ false,
|
||||||
/* populateAds= */ true);
|
/* populateAds= */ true,
|
||||||
|
/* playedAds= */ false);
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
|
|
||||||
@ -138,7 +140,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
/* nowUs= */ 100_000_000L,
|
/* nowUs= */ 100_000_000L,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
/* isContentTimeline= */ false,
|
/* isContentTimeline= */ false,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
|
|
||||||
@ -189,7 +192,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
/* nowUs= */ 60_000_123L,
|
/* nowUs= */ 60_000_123L,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
|
|
||||||
@ -273,7 +277,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
nowUs,
|
nowUs,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ true);
|
||||||
|
|
||||||
assertThat(timeline.getWindow(0, new Timeline.Window()).windowStartTimeMs)
|
assertThat(timeline.getWindow(0, new Timeline.Window()).windowStartTimeMs)
|
||||||
.isEqualTo(Util.usToMs(nowUs - liveWindowDurationUs));
|
.isEqualTo(Util.usToMs(nowUs - liveWindowDurationUs));
|
||||||
@ -333,7 +338,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
nowUs,
|
nowUs,
|
||||||
adSequencePattern,
|
adSequencePattern,
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
|
|
||||||
assertThat(timeline.getWindow(0, new Timeline.Window()).windowStartTimeMs)
|
assertThat(timeline.getWindow(0, new Timeline.Window()).windowStartTimeMs)
|
||||||
.isEqualTo(Util.usToMs(nowUs - liveWindowDurationUs));
|
.isEqualTo(Util.usToMs(nowUs - liveWindowDurationUs));
|
||||||
@ -353,7 +359,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
/* nowUs= */ 120_000_000L,
|
/* nowUs= */ 120_000_000L,
|
||||||
new boolean[] {false, true, true, true},
|
new boolean[] {false, true, true, true},
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
Timeline.Period period = new Timeline.Period();
|
Timeline.Period period = new Timeline.Period();
|
||||||
Timeline.Window window = new Timeline.Window();
|
Timeline.Window window = new Timeline.Window();
|
||||||
|
|
||||||
@ -390,7 +397,8 @@ public class FakeMultiPeriodLiveTimelineTest {
|
|||||||
/* nowUs= */ 250_000_000L,
|
/* nowUs= */ 250_000_000L,
|
||||||
new boolean[] {false, true, false, true, false},
|
new boolean[] {false, true, false, true, false},
|
||||||
/* isContentTimeline= */ true,
|
/* isContentTimeline= */ true,
|
||||||
/* populateAds= */ false);
|
/* populateAds= */ false,
|
||||||
|
/* playedAds= */ false);
|
||||||
|
|
||||||
assertThat(timeline.getPeriodCount()).isEqualTo(10);
|
assertThat(timeline.getPeriodCount()).isEqualTo(10);
|
||||||
assertThat(timeline.getWindow(0, window).windowStartTimeMs).isEqualTo(30_000L);
|
assertThat(timeline.getWindow(0, window).windowStartTimeMs).isEqualTo(30_000L);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user