mirror of
https://github.com/androidx/media.git
synced 2025-05-07 15:40:37 +08:00
Rollback of ff89170b00
*** Original commit *** Fix some logic in AnalyticsCollector. All events issued from ExoPlayerImpl (i.e. Player.EventListener events) currently try to use the media period data from the playing media period as set in the playback thread queue. This is only correct as long as there no pending masking operations in ExoPlayerImpl. That's why we currently disable this whenever the timeline is empty or a seek is pending. Since adding all the playlist API methods to the player, this is no longer the right choice. Moreover,... *** PiperOrigin-RevId: 290312118
This commit is contained in:
parent
4cf614c639
commit
72437e4442
@ -76,7 +76,6 @@ public class AnalyticsCollector
|
|||||||
private final MediaPeriodQueueTracker mediaPeriodQueueTracker;
|
private final MediaPeriodQueueTracker mediaPeriodQueueTracker;
|
||||||
|
|
||||||
private @MonotonicNonNull Player player;
|
private @MonotonicNonNull Player player;
|
||||||
private boolean isSeeking;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an analytics collector.
|
* Creates an analytics collector.
|
||||||
@ -127,9 +126,9 @@ public class AnalyticsCollector
|
|||||||
* adjusts its state and position to the seek.
|
* adjusts its state and position to the seek.
|
||||||
*/
|
*/
|
||||||
public final void notifySeekStarted() {
|
public final void notifySeekStarted() {
|
||||||
if (!isSeeking) {
|
if (!mediaPeriodQueueTracker.isSeeking()) {
|
||||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||||
isSeeking = true;
|
mediaPeriodQueueTracker.onSeekStarted();
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onSeekStarted(eventTime);
|
listener.onSeekStarted(eventTime);
|
||||||
}
|
}
|
||||||
@ -310,8 +309,7 @@ public class AnalyticsCollector
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) {
|
public final void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) {
|
||||||
mediaPeriodQueueTracker.onMediaPeriodCreated(
|
mediaPeriodQueueTracker.onMediaPeriodCreated(windowIndex, mediaPeriodId);
|
||||||
windowIndex, mediaPeriodId, Assertions.checkNotNull(player));
|
|
||||||
EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId);
|
EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId);
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onMediaPeriodCreated(eventTime);
|
listener.onMediaPeriodCreated(eventTime);
|
||||||
@ -321,8 +319,7 @@ public class AnalyticsCollector
|
|||||||
@Override
|
@Override
|
||||||
public final void onMediaPeriodReleased(int windowIndex, MediaPeriodId mediaPeriodId) {
|
public final void onMediaPeriodReleased(int windowIndex, MediaPeriodId mediaPeriodId) {
|
||||||
EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId);
|
EventTime eventTime = generateMediaPeriodEventTime(windowIndex, mediaPeriodId);
|
||||||
if (mediaPeriodQueueTracker.onMediaPeriodReleased(
|
if (mediaPeriodQueueTracker.onMediaPeriodReleased(mediaPeriodId)) {
|
||||||
mediaPeriodId, Assertions.checkNotNull(player))) {
|
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onMediaPeriodReleased(eventTime);
|
listener.onMediaPeriodReleased(eventTime);
|
||||||
}
|
}
|
||||||
@ -414,7 +411,7 @@ public class AnalyticsCollector
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
public final void onTimelineChanged(Timeline timeline, @Player.TimelineChangeReason int reason) {
|
||||||
mediaPeriodQueueTracker.onTimelineChanged(timeline, Assertions.checkNotNull(player));
|
mediaPeriodQueueTracker.onTimelineChanged(timeline);
|
||||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onTimelineChanged(eventTime, reason);
|
listener.onTimelineChanged(eventTime, reason);
|
||||||
@ -481,7 +478,7 @@ public class AnalyticsCollector
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onPlayerError(ExoPlaybackException error) {
|
public final void onPlayerError(ExoPlaybackException error) {
|
||||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
EventTime eventTime = generatePlayingMediaPeriodEventTime();
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onPlayerError(eventTime, error);
|
listener.onPlayerError(eventTime, error);
|
||||||
}
|
}
|
||||||
@ -489,7 +486,6 @@ public class AnalyticsCollector
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) {
|
public final void onPositionDiscontinuity(@Player.DiscontinuityReason int reason) {
|
||||||
mediaPeriodQueueTracker.onPositionDiscontinuity(Assertions.checkNotNull(player));
|
|
||||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onPositionDiscontinuity(eventTime, reason);
|
listener.onPositionDiscontinuity(eventTime, reason);
|
||||||
@ -506,8 +502,8 @@ public class AnalyticsCollector
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void onSeekProcessed() {
|
public final void onSeekProcessed() {
|
||||||
if (isSeeking) {
|
if (mediaPeriodQueueTracker.isSeeking()) {
|
||||||
isSeeking = false;
|
mediaPeriodQueueTracker.onSeekProcessed();
|
||||||
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
EventTime eventTime = generateCurrentPlayerMediaPeriodEventTime();
|
||||||
for (AnalyticsListener listener : listeners) {
|
for (AnalyticsListener listener : listeners) {
|
||||||
listener.onSeekProcessed(eventTime);
|
listener.onSeekProcessed(eventTime);
|
||||||
@ -624,10 +620,13 @@ public class AnalyticsCollector
|
|||||||
Assertions.checkNotNull(player);
|
Assertions.checkNotNull(player);
|
||||||
if (mediaPeriodInfo == null) {
|
if (mediaPeriodInfo == null) {
|
||||||
int windowIndex = player.getCurrentWindowIndex();
|
int windowIndex = player.getCurrentWindowIndex();
|
||||||
Timeline timeline = player.getCurrentTimeline();
|
mediaPeriodInfo = mediaPeriodQueueTracker.tryResolveWindowIndex(windowIndex);
|
||||||
boolean windowIsInTimeline = windowIndex < timeline.getWindowCount();
|
if (mediaPeriodInfo == null) {
|
||||||
return generateEventTime(
|
Timeline timeline = player.getCurrentTimeline();
|
||||||
windowIsInTimeline ? timeline : Timeline.EMPTY, windowIndex, /* mediaPeriodId= */ null);
|
boolean windowIsInTimeline = windowIndex < timeline.getWindowCount();
|
||||||
|
return generateEventTime(
|
||||||
|
windowIsInTimeline ? timeline : Timeline.EMPTY, windowIndex, /* mediaPeriodId= */ null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return generateEventTime(
|
return generateEventTime(
|
||||||
mediaPeriodInfo.timeline, mediaPeriodInfo.windowIndex, mediaPeriodInfo.mediaPeriodId);
|
mediaPeriodInfo.timeline, mediaPeriodInfo.windowIndex, mediaPeriodInfo.mediaPeriodId);
|
||||||
@ -674,10 +673,10 @@ public class AnalyticsCollector
|
|||||||
private final HashMap<MediaPeriodId, MediaPeriodInfo> mediaPeriodIdToInfo;
|
private final HashMap<MediaPeriodId, MediaPeriodInfo> mediaPeriodIdToInfo;
|
||||||
private final Period period;
|
private final Period period;
|
||||||
|
|
||||||
@Nullable private MediaPeriodInfo currentPlayerMediaPeriod;
|
@Nullable private MediaPeriodInfo playingMediaPeriod;
|
||||||
private @MonotonicNonNull MediaPeriodInfo playingMediaPeriod;
|
|
||||||
@Nullable private MediaPeriodInfo readingMediaPeriod;
|
@Nullable private MediaPeriodInfo readingMediaPeriod;
|
||||||
private Timeline timeline;
|
private Timeline timeline;
|
||||||
|
private boolean isSeeking;
|
||||||
|
|
||||||
public MediaPeriodQueueTracker() {
|
public MediaPeriodQueueTracker() {
|
||||||
mediaPeriodInfoQueue = new ArrayList<>();
|
mediaPeriodInfoQueue = new ArrayList<>();
|
||||||
@ -690,11 +689,14 @@ public class AnalyticsCollector
|
|||||||
* Returns the {@link MediaPeriodInfo} of the media period corresponding the current position of
|
* Returns the {@link MediaPeriodInfo} of the media period corresponding the current position of
|
||||||
* the player.
|
* the player.
|
||||||
*
|
*
|
||||||
* <p>May be null if no matching media period has been created yet.
|
* <p>May be null if no matching media period has been created yet or the player is currently
|
||||||
|
* masking its state.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public MediaPeriodInfo getCurrentPlayerMediaPeriod() {
|
public MediaPeriodInfo getCurrentPlayerMediaPeriod() {
|
||||||
return currentPlayerMediaPeriod;
|
return mediaPeriodInfoQueue.isEmpty() || timeline.isEmpty() || isSeeking
|
||||||
|
? null
|
||||||
|
: mediaPeriodInfoQueue.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -737,13 +739,35 @@ public class AnalyticsCollector
|
|||||||
return mediaPeriodIdToInfo.get(mediaPeriodId);
|
return mediaPeriodIdToInfo.get(mediaPeriodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Updates the queue with a reported position discontinuity. */
|
/** Returns whether the player is currently seeking. */
|
||||||
public void onPositionDiscontinuity(Player player) {
|
public boolean isSeeking() {
|
||||||
currentPlayerMediaPeriod = findMatchingMediaPeriodInQueue(player);
|
return isSeeking;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to find an existing media period info from the specified window index. Only returns a
|
||||||
|
* non-null media period info if there is a unique, unambiguous match.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public MediaPeriodInfo tryResolveWindowIndex(int windowIndex) {
|
||||||
|
MediaPeriodInfo match = null;
|
||||||
|
for (int i = 0; i < mediaPeriodInfoQueue.size(); i++) {
|
||||||
|
MediaPeriodInfo info = mediaPeriodInfoQueue.get(i);
|
||||||
|
int periodIndex = timeline.getIndexOfPeriod(info.mediaPeriodId.periodUid);
|
||||||
|
if (periodIndex != C.INDEX_UNSET
|
||||||
|
&& timeline.getPeriod(periodIndex, period).windowIndex == windowIndex) {
|
||||||
|
if (match != null) {
|
||||||
|
// Ambiguous match.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
match = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Updates the queue with a reported timeline change. */
|
/** Updates the queue with a reported timeline change. */
|
||||||
public void onTimelineChanged(Timeline timeline, Player player) {
|
public void onTimelineChanged(Timeline timeline) {
|
||||||
for (int i = 0; i < mediaPeriodInfoQueue.size(); i++) {
|
for (int i = 0; i < mediaPeriodInfoQueue.size(); i++) {
|
||||||
MediaPeriodInfo newMediaPeriodInfo =
|
MediaPeriodInfo newMediaPeriodInfo =
|
||||||
updateMediaPeriodInfoToNewTimeline(mediaPeriodInfoQueue.get(i), timeline);
|
updateMediaPeriodInfoToNewTimeline(mediaPeriodInfoQueue.get(i), timeline);
|
||||||
@ -757,11 +781,20 @@ public class AnalyticsCollector
|
|||||||
playingMediaPeriod = mediaPeriodInfoQueue.get(0);
|
playingMediaPeriod = mediaPeriodInfoQueue.get(0);
|
||||||
}
|
}
|
||||||
this.timeline = timeline;
|
this.timeline = timeline;
|
||||||
currentPlayerMediaPeriod = findMatchingMediaPeriodInQueue(player);
|
}
|
||||||
|
|
||||||
|
/** Updates the queue with a reported start of seek. */
|
||||||
|
public void onSeekStarted() {
|
||||||
|
isSeeking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates the queue with a reported processed seek. */
|
||||||
|
public void onSeekProcessed() {
|
||||||
|
isSeeking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Updates the queue with a newly created media period. */
|
/** Updates the queue with a newly created media period. */
|
||||||
public void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId, Player player) {
|
public void onMediaPeriodCreated(int windowIndex, MediaPeriodId mediaPeriodId) {
|
||||||
int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid);
|
int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid);
|
||||||
boolean isInTimeline = periodIndex != C.INDEX_UNSET;
|
boolean isInTimeline = periodIndex != C.INDEX_UNSET;
|
||||||
MediaPeriodInfo mediaPeriodInfo =
|
MediaPeriodInfo mediaPeriodInfo =
|
||||||
@ -772,17 +805,14 @@ public class AnalyticsCollector
|
|||||||
mediaPeriodInfoQueue.add(mediaPeriodInfo);
|
mediaPeriodInfoQueue.add(mediaPeriodInfo);
|
||||||
mediaPeriodIdToInfo.put(mediaPeriodId, mediaPeriodInfo);
|
mediaPeriodIdToInfo.put(mediaPeriodId, mediaPeriodInfo);
|
||||||
playingMediaPeriod = mediaPeriodInfoQueue.get(0);
|
playingMediaPeriod = mediaPeriodInfoQueue.get(0);
|
||||||
if (currentPlayerMediaPeriod == null && isMatchingPlayingMediaPeriod(player)) {
|
|
||||||
currentPlayerMediaPeriod = playingMediaPeriod;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the queue with a released media period. Returns whether the media period was still in
|
* Updates the queue with a released media period. Returns whether the media period was still in
|
||||||
* the queue.
|
* the queue.
|
||||||
*/
|
*/
|
||||||
public boolean onMediaPeriodReleased(MediaPeriodId mediaPeriodId, Player player) {
|
public boolean onMediaPeriodReleased(MediaPeriodId mediaPeriodId) {
|
||||||
@Nullable MediaPeriodInfo mediaPeriodInfo = mediaPeriodIdToInfo.remove(mediaPeriodId);
|
MediaPeriodInfo mediaPeriodInfo = mediaPeriodIdToInfo.remove(mediaPeriodId);
|
||||||
if (mediaPeriodInfo == null) {
|
if (mediaPeriodInfo == null) {
|
||||||
// The media period has already been removed from the queue in resetForNewPlaylist().
|
// The media period has already been removed from the queue in resetForNewPlaylist().
|
||||||
return false;
|
return false;
|
||||||
@ -794,9 +824,6 @@ public class AnalyticsCollector
|
|||||||
if (!mediaPeriodInfoQueue.isEmpty()) {
|
if (!mediaPeriodInfoQueue.isEmpty()) {
|
||||||
playingMediaPeriod = mediaPeriodInfoQueue.get(0);
|
playingMediaPeriod = mediaPeriodInfoQueue.get(0);
|
||||||
}
|
}
|
||||||
if (currentPlayerMediaPeriod == null && isMatchingPlayingMediaPeriod(player)) {
|
|
||||||
currentPlayerMediaPeriod = playingMediaPeriod;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,99 +832,6 @@ public class AnalyticsCollector
|
|||||||
readingMediaPeriod = mediaPeriodIdToInfo.get(mediaPeriodId);
|
readingMediaPeriod = mediaPeriodIdToInfo.get(mediaPeriodId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private MediaPeriodInfo findMatchingMediaPeriodInQueue(Player player) {
|
|
||||||
Timeline playerTimeline = player.getCurrentTimeline();
|
|
||||||
int playerPeriodIndex = player.getCurrentPeriodIndex();
|
|
||||||
@Nullable
|
|
||||||
Object playerPeriodUid =
|
|
||||||
playerTimeline.isEmpty() ? null : playerTimeline.getUidOfPeriod(playerPeriodIndex);
|
|
||||||
int playerNextAdGroupIndex =
|
|
||||||
player.isPlayingAd() || playerTimeline.isEmpty()
|
|
||||||
? C.INDEX_UNSET
|
|
||||||
: playerTimeline
|
|
||||||
.getPeriod(playerPeriodIndex, period)
|
|
||||||
.getAdGroupIndexAfterPositionUs(C.msToUs(player.getCurrentPosition()));
|
|
||||||
for (int i = 0; i < mediaPeriodInfoQueue.size(); i++) {
|
|
||||||
MediaPeriodInfo mediaPeriodInfo = mediaPeriodInfoQueue.get(i);
|
|
||||||
if (isMatchingMediaPeriod(
|
|
||||||
mediaPeriodInfo,
|
|
||||||
playerTimeline,
|
|
||||||
player.getCurrentWindowIndex(),
|
|
||||||
playerPeriodUid,
|
|
||||||
player.isPlayingAd(),
|
|
||||||
player.getCurrentAdGroupIndex(),
|
|
||||||
player.getCurrentAdIndexInAdGroup(),
|
|
||||||
playerNextAdGroupIndex)) {
|
|
||||||
return mediaPeriodInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mediaPeriodInfoQueue.isEmpty() && playingMediaPeriod != null) {
|
|
||||||
if (isMatchingMediaPeriod(
|
|
||||||
playingMediaPeriod,
|
|
||||||
playerTimeline,
|
|
||||||
player.getCurrentWindowIndex(),
|
|
||||||
playerPeriodUid,
|
|
||||||
player.isPlayingAd(),
|
|
||||||
player.getCurrentAdGroupIndex(),
|
|
||||||
player.getCurrentAdIndexInAdGroup(),
|
|
||||||
playerNextAdGroupIndex)) {
|
|
||||||
return playingMediaPeriod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isMatchingPlayingMediaPeriod(Player player) {
|
|
||||||
if (playingMediaPeriod == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Timeline playerTimeline = player.getCurrentTimeline();
|
|
||||||
int playerPeriodIndex = player.getCurrentPeriodIndex();
|
|
||||||
@Nullable
|
|
||||||
Object playerPeriodUid =
|
|
||||||
playerTimeline.isEmpty() ? null : playerTimeline.getUidOfPeriod(playerPeriodIndex);
|
|
||||||
int playerNextAdGroupIndex =
|
|
||||||
player.isPlayingAd() || playerTimeline.isEmpty()
|
|
||||||
? C.INDEX_UNSET
|
|
||||||
: playerTimeline
|
|
||||||
.getPeriod(playerPeriodIndex, period)
|
|
||||||
.getAdGroupIndexAfterPositionUs(C.msToUs(player.getCurrentPosition()));
|
|
||||||
return isMatchingMediaPeriod(
|
|
||||||
playingMediaPeriod,
|
|
||||||
playerTimeline,
|
|
||||||
player.getCurrentWindowIndex(),
|
|
||||||
playerPeriodUid,
|
|
||||||
player.isPlayingAd(),
|
|
||||||
player.getCurrentAdGroupIndex(),
|
|
||||||
player.getCurrentAdIndexInAdGroup(),
|
|
||||||
playerNextAdGroupIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isMatchingMediaPeriod(
|
|
||||||
MediaPeriodInfo mediaPeriodInfo,
|
|
||||||
Timeline playerTimeline,
|
|
||||||
int playerWindowIndex,
|
|
||||||
@Nullable Object playerPeriodUid,
|
|
||||||
boolean isPlayingAd,
|
|
||||||
int playerAdGroupIndex,
|
|
||||||
int playerAdIndexInAdGroup,
|
|
||||||
int playerNextAdGroupIndex) {
|
|
||||||
if (mediaPeriodInfo.timeline.isEmpty()
|
|
||||||
|| !mediaPeriodInfo.timeline.equals(playerTimeline)
|
|
||||||
|| mediaPeriodInfo.windowIndex != playerWindowIndex
|
|
||||||
|| !mediaPeriodInfo.mediaPeriodId.periodUid.equals(playerPeriodUid)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Timeline period matches. Still need to check ad information.
|
|
||||||
return (isPlayingAd
|
|
||||||
&& mediaPeriodInfo.mediaPeriodId.adGroupIndex == playerAdGroupIndex
|
|
||||||
&& mediaPeriodInfo.mediaPeriodId.adIndexInAdGroup == playerAdIndexInAdGroup)
|
|
||||||
|| (!isPlayingAd
|
|
||||||
&& mediaPeriodInfo.mediaPeriodId.adGroupIndex == C.INDEX_UNSET
|
|
||||||
&& mediaPeriodInfo.mediaPeriodId.nextAdGroupIndex == playerNextAdGroupIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MediaPeriodInfo updateMediaPeriodInfoToNewTimeline(
|
private MediaPeriodInfo updateMediaPeriodInfoToNewTimeline(
|
||||||
MediaPeriodInfo info, Timeline newTimeline) {
|
MediaPeriodInfo info, Timeline newTimeline) {
|
||||||
int newPeriodIndex = newTimeline.getIndexOfPeriod(info.mediaPeriodId.periodUid);
|
int newPeriodIndex = newTimeline.getIndexOfPeriod(info.mediaPeriodId.periodUid);
|
||||||
|
@ -25,6 +25,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -2968,7 +2969,10 @@ public final class ExoPlayerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void contentWithInitialSeekPositionAfterPrerollAdStartsAtSeekPosition() throws Exception {
|
public void contentWithInitialSeekPositionAfterPrerollAdStartsAtSeekPosition() throws Exception {
|
||||||
AdPlaybackState adPlaybackState =
|
AdPlaybackState adPlaybackState =
|
||||||
FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */ 3, /* adGroupTimesUs...= */ 0);
|
FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */ 3, /* adGroupTimesUs= */ 0)
|
||||||
|
.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.parse("https://ad1"))
|
||||||
|
.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 1, Uri.parse("https://ad2"))
|
||||||
|
.withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 2, Uri.parse("https://ad3"));
|
||||||
Timeline fakeTimeline =
|
Timeline fakeTimeline =
|
||||||
new FakeTimeline(
|
new FakeTimeline(
|
||||||
new TimelineWindowDefinition(
|
new TimelineWindowDefinition(
|
||||||
@ -4056,14 +4060,15 @@ public final class ExoPlayerTest {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
ExoPlayerTestRunner testRunner =
|
||||||
.setMediaSources(concatenatingMediaSource)
|
new ExoPlayerTestRunner.Builder()
|
||||||
.initialSeek(seekToWindowIndex, 5000)
|
.setMediaSources(concatenatingMediaSource)
|
||||||
.setActionSchedule(actionSchedule)
|
.initialSeek(seekToWindowIndex, 5000)
|
||||||
.build(context)
|
.setActionSchedule(actionSchedule)
|
||||||
.start()
|
.build(context)
|
||||||
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
.start()
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
||||||
|
.blockUntilEnded(TIMEOUT_MS);
|
||||||
assertArrayEquals(new long[] {5_000}, currentPlaybackPositions);
|
assertArrayEquals(new long[] {5_000}, currentPlaybackPositions);
|
||||||
assertArrayEquals(new int[] {seekToWindowIndex}, currentWindowIndices);
|
assertArrayEquals(new int[] {seekToWindowIndex}, currentWindowIndices);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import android.view.Surface;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.C;
|
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
@ -42,14 +41,12 @@ import com.google.android.exoplayer2.source.MediaLoadData;
|
|||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||||
import com.google.android.exoplayer2.source.ads.AdPlaybackState;
|
|
||||||
import com.google.android.exoplayer2.testutil.ActionSchedule;
|
import com.google.android.exoplayer2.testutil.ActionSchedule;
|
||||||
import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable;
|
import com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable;
|
||||||
import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner;
|
import com.google.android.exoplayer2.testutil.ExoPlayerTestRunner;
|
||||||
import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
import com.google.android.exoplayer2.testutil.FakeMediaSource;
|
||||||
import com.google.android.exoplayer2.testutil.FakeRenderer;
|
import com.google.android.exoplayer2.testutil.FakeRenderer;
|
||||||
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.trackselection.TrackSelectionArray;
|
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
import com.google.android.exoplayer2.video.VideoRendererEventListener;
|
||||||
@ -57,8 +54,6 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.robolectric.annotation.LooperMode;
|
import org.robolectric.annotation.LooperMode;
|
||||||
@ -138,7 +133,7 @@ public final class AnalyticsCollectorTest {
|
|||||||
.containsExactly(
|
.containsExactly(
|
||||||
WINDOW_0 /* setPlayWhenReady */, WINDOW_0 /* BUFFERING */, WINDOW_0 /* ENDED */);
|
WINDOW_0 /* setPlayWhenReady */, WINDOW_0 /* BUFFERING */, WINDOW_0 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, WINDOW_0 /* SOURCE_UPDATE */);
|
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, WINDOW_0 /* DYNAMIC */);
|
||||||
listener.assertNoMoreEvents();
|
listener.assertNoMoreEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +154,7 @@ public final class AnalyticsCollectorTest {
|
|||||||
period0 /* READY */,
|
period0 /* READY */,
|
||||||
period0 /* ENDED */);
|
period0 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, WINDOW_0 /* SOURCE_UPDATE */);
|
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, WINDOW_0 /* DYNAMIC */);
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
||||||
.containsExactly(period0 /* started */, period0 /* stopped */);
|
.containsExactly(period0 /* started */, period0 /* stopped */);
|
||||||
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(period0);
|
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(period0);
|
||||||
@ -206,7 +201,7 @@ public final class AnalyticsCollectorTest {
|
|||||||
period0 /* READY */,
|
period0 /* READY */,
|
||||||
period1 /* ENDED */);
|
period1 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* SOURCE_UPDATE */);
|
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* DYNAMIC */);
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period1);
|
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period1);
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
||||||
.containsExactly(period0, period0, period0, period0);
|
.containsExactly(period0, period0, period0, period0);
|
||||||
@ -262,7 +257,7 @@ public final class AnalyticsCollectorTest {
|
|||||||
period1 /* READY */,
|
period1 /* READY */,
|
||||||
period1 /* ENDED */);
|
period1 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* SOURCE_UPDATE */);
|
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* DYNAMIC */);
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period1);
|
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period1);
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
||||||
.containsExactly(period0, period0, period0, period0);
|
.containsExactly(period0, period0, period0, period0);
|
||||||
@ -325,7 +320,7 @@ public final class AnalyticsCollectorTest {
|
|||||||
period1 /* setPlayWhenReady=true */,
|
period1 /* setPlayWhenReady=true */,
|
||||||
period1 /* ENDED */);
|
period1 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* SOURCE_UPDATE */);
|
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* DYNAMIC */);
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period1);
|
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period1);
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(period0);
|
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(period0);
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(period1);
|
assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(period1);
|
||||||
@ -400,7 +395,7 @@ public final class AnalyticsCollectorTest {
|
|||||||
period1Seq2 /* READY */,
|
period1Seq2 /* READY */,
|
||||||
period1Seq2 /* ENDED */);
|
period1Seq2 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* SOURCE_UPDATE */);
|
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, period0 /* DYNAMIC */);
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY))
|
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY))
|
||||||
.containsExactly(period0, period1Seq2);
|
.containsExactly(period0, period1Seq2);
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(period0);
|
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(period0);
|
||||||
@ -482,9 +477,9 @@ public final class AnalyticsCollectorTest {
|
|||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(
|
.containsExactly(
|
||||||
WINDOW_0 /* PLAYLIST_CHANGE */,
|
WINDOW_0 /* PLAYLIST_CHANGE */,
|
||||||
WINDOW_0 /* SOURCE_UPDATE */,
|
WINDOW_0 /* DYNAMIC */,
|
||||||
WINDOW_0 /* PLAYLIST_CHANGE */,
|
WINDOW_0 /* PLAYLIST_CHANGE */,
|
||||||
WINDOW_0 /* SOURCE_UPDATE */);
|
WINDOW_0 /* DYNAMIC */);
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
||||||
.containsExactly(period0Seq0, period0Seq0, period0Seq1, period0Seq1);
|
.containsExactly(period0Seq0, period0Seq0, period0Seq1, period0Seq1);
|
||||||
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED))
|
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED))
|
||||||
@ -527,13 +522,11 @@ public final class AnalyticsCollectorTest {
|
|||||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT);
|
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT);
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
||||||
.pause()
|
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.throwPlaybackException(ExoPlaybackException.createForSource(new IOException()))
|
.throwPlaybackException(ExoPlaybackException.createForSource(new IOException()))
|
||||||
.waitForPlaybackState(Player.STATE_IDLE)
|
.waitForPlaybackState(Player.STATE_IDLE)
|
||||||
.seek(/* positionMs= */ 0)
|
.seek(/* positionMs= */ 0)
|
||||||
.prepare()
|
.prepare()
|
||||||
.play()
|
|
||||||
.waitForPlaybackState(Player.STATE_ENDED)
|
.waitForPlaybackState(Player.STATE_ENDED)
|
||||||
.build();
|
.build();
|
||||||
TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule);
|
TestAnalyticsListener listener = runAnalyticsTest(mediaSource, actionSchedule);
|
||||||
@ -542,19 +535,17 @@ public final class AnalyticsCollectorTest {
|
|||||||
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED))
|
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED))
|
||||||
.containsExactly(
|
.containsExactly(
|
||||||
WINDOW_0 /* setPlayWhenReady=true */,
|
WINDOW_0 /* setPlayWhenReady=true */,
|
||||||
WINDOW_0 /* setPlayWhenReady=false */,
|
|
||||||
WINDOW_0 /* BUFFERING */,
|
WINDOW_0 /* BUFFERING */,
|
||||||
period0Seq0 /* READY */,
|
period0Seq0 /* READY */,
|
||||||
period0Seq0 /* IDLE */,
|
WINDOW_0 /* IDLE */,
|
||||||
period0Seq0 /* BUFFERING */,
|
WINDOW_0 /* BUFFERING */,
|
||||||
period0Seq0 /* setPlayWhenReady=true */,
|
|
||||||
period0Seq0 /* READY */,
|
period0Seq0 /* READY */,
|
||||||
period0Seq0 /* ENDED */);
|
period0Seq0 /* ENDED */);
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(WINDOW_0 /* prepared */, WINDOW_0 /* prepared */);
|
.containsExactly(WINDOW_0 /* prepared */, WINDOW_0 /* prepared */);
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(period0Seq0);
|
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(WINDOW_0);
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(period0Seq0);
|
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(WINDOW_0);
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(period0Seq0);
|
assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(WINDOW_0);
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
||||||
.containsExactly(period0Seq0, period0Seq0, period0Seq0, period0Seq0);
|
.containsExactly(period0Seq0, period0Seq0, period0Seq0, period0Seq0);
|
||||||
assertThat(listener.getEvents(EVENT_PLAYER_ERROR)).containsExactly(period0Seq0);
|
assertThat(listener.getEvents(EVENT_PLAYER_ERROR)).containsExactly(period0Seq0);
|
||||||
@ -582,7 +573,8 @@ public final class AnalyticsCollectorTest {
|
|||||||
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED))
|
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED))
|
||||||
.containsExactly(period0Seq0, period0Seq0);
|
.containsExactly(period0Seq0, period0Seq0);
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(period0Seq0);
|
assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(period0Seq0);
|
||||||
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(period0Seq0);
|
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES))
|
||||||
|
.containsExactly(period0Seq0, period0Seq0);
|
||||||
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED))
|
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED))
|
||||||
.containsExactly(period0Seq0, period0Seq0);
|
.containsExactly(period0Seq0, period0Seq0);
|
||||||
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME))
|
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME))
|
||||||
@ -628,8 +620,8 @@ public final class AnalyticsCollectorTest {
|
|||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
||||||
.containsExactly(
|
.containsExactly(
|
||||||
WINDOW_0 /* PLAYLIST_CHANGED */,
|
WINDOW_0 /* PLAYLIST_CHANGED */,
|
||||||
window0Period1Seq0 /* SOURCE_UPDATE (concatenated timeline replaces dummy) */,
|
window0Period1Seq0 /* DYNAMIC (concatenated timeline replaces dummy) */,
|
||||||
period1Seq0 /* SOURCE_UPDATE (child sources in concatenating source moved) */);
|
period1Seq0 /* DYNAMIC (child sources in concatenating source moved) */);
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
||||||
.containsExactly(
|
.containsExactly(
|
||||||
window0Period1Seq0, window0Period1Seq0, window0Period1Seq0, window0Period1Seq0);
|
window0Period1Seq0, window0Period1Seq0, window0Period1Seq0, window0Period1Seq0);
|
||||||
@ -664,401 +656,6 @@ public final class AnalyticsCollectorTest {
|
|||||||
listener.assertNoMoreEvents();
|
listener.assertNoMoreEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPlaylistOperations() throws Exception {
|
|
||||||
MediaSource fakeMediaSource =
|
|
||||||
new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.Builder.VIDEO_FORMAT);
|
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
|
||||||
.pause()
|
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
|
||||||
.addMediaSources(fakeMediaSource)
|
|
||||||
// Wait until second period has fully loaded to assert loading events without flakiness.
|
|
||||||
.waitForIsLoading(true)
|
|
||||||
.waitForIsLoading(false)
|
|
||||||
.removeMediaItem(/* index= */ 0)
|
|
||||||
.play()
|
|
||||||
.build();
|
|
||||||
TestAnalyticsListener listener = runAnalyticsTest(fakeMediaSource, actionSchedule);
|
|
||||||
|
|
||||||
// Populate event ids with second to last timeline that still contained both periods.
|
|
||||||
populateEventIds(listener.reportedTimelines.get(listener.reportedTimelines.size() - 2));
|
|
||||||
// Expect the second period with window index 0 and increased window sequence after the removal
|
|
||||||
// moved the period to another window index.
|
|
||||||
period0Seq1 =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
listener.lastReportedTimeline.getUidOfPeriod(/* periodIndex= */ 0),
|
|
||||||
/* windowSequenceNumber= */ 1));
|
|
||||||
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* setPlayWhenReady=true */,
|
|
||||||
WINDOW_0 /* setPlayWhenReady=false */,
|
|
||||||
WINDOW_0 /* BUFFERING */,
|
|
||||||
period0Seq0 /* READY */,
|
|
||||||
period0Seq1 /* BUFFERING */,
|
|
||||||
period0Seq1 /* setPlayWhenReady=true */,
|
|
||||||
period0Seq1 /* READY */,
|
|
||||||
period0Seq1 /* ENDED */);
|
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* PLAYLIST_CHANGED */,
|
|
||||||
WINDOW_0 /* SOURCE_UPDATE (first item) */,
|
|
||||||
period0Seq0 /* PLAYLIST_CHANGED (add) */,
|
|
||||||
period0Seq0 /* SOURCE_UPDATE (second item) */,
|
|
||||||
period0Seq1 /* PLAYLIST_CHANGED (remove) */);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
|
||||||
.containsExactly(period0Seq0, period0Seq0, period0Seq0, period0Seq0);
|
|
||||||
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOAD_STARTED))
|
|
||||||
.containsExactly(WINDOW_0 /* manifest */, period0Seq0 /* media */, period1Seq1 /* media */);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOAD_COMPLETED))
|
|
||||||
.containsExactly(WINDOW_0 /* manifest */, period0Seq0 /* media */, period1Seq1 /* media */);
|
|
||||||
assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED))
|
|
||||||
.containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED))
|
|
||||||
.containsExactly(period0Seq0, period1Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED)).containsExactly(period0Seq0);
|
|
||||||
assertThat(listener.getEvents(EVENT_READING_STARTED)).containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_ENABLED)).containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_INIT)).containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED))
|
|
||||||
.containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(period0Seq0);
|
|
||||||
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED))
|
|
||||||
.containsExactly(period0Seq0, period0Seq1);
|
|
||||||
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME))
|
|
||||||
.containsExactly(period0Seq0, period0Seq1);
|
|
||||||
listener.assertNoMoreEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAdPlayback() throws Exception {
|
|
||||||
long contentDurationsUs = 10 * C.MICROS_PER_SECOND;
|
|
||||||
AtomicReference<AdPlaybackState> adPlaybackState =
|
|
||||||
new AtomicReference<>(
|
|
||||||
FakeTimeline.createAdPlaybackState(
|
|
||||||
/* adsPerAdGroup= */ 1, /* adGroupTimesUs...= */
|
|
||||||
0,
|
|
||||||
5 * C.MICROS_PER_SECOND,
|
|
||||||
C.TIME_END_OF_SOURCE)
|
|
||||||
.withContentDurationUs(contentDurationsUs));
|
|
||||||
AtomicInteger playedAdCount = new AtomicInteger(0);
|
|
||||||
Timeline adTimeline =
|
|
||||||
new FakeTimeline(
|
|
||||||
new TimelineWindowDefinition(
|
|
||||||
/* periodCount= */ 1,
|
|
||||||
/* id= */ 0,
|
|
||||||
/* isSeekable= */ true,
|
|
||||||
/* isDynamic= */ false,
|
|
||||||
contentDurationsUs,
|
|
||||||
adPlaybackState.get()));
|
|
||||||
FakeMediaSource fakeMediaSource =
|
|
||||||
new FakeMediaSource(adTimeline, ExoPlayerTestRunner.Builder.VIDEO_FORMAT);
|
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
|
||||||
.executeRunnable(
|
|
||||||
new PlayerRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run(SimpleExoPlayer player) {
|
|
||||||
player.addListener(
|
|
||||||
new Player.EventListener() {
|
|
||||||
@Override
|
|
||||||
public void onPositionDiscontinuity(
|
|
||||||
@Player.DiscontinuityReason int reason) {
|
|
||||||
if (!player.isPlayingAd()
|
|
||||||
&& reason == Player.DISCONTINUITY_REASON_AD_INSERTION) {
|
|
||||||
// Finished playing ad. Marked as played.
|
|
||||||
adPlaybackState.set(
|
|
||||||
adPlaybackState
|
|
||||||
.get()
|
|
||||||
.withPlayedAd(
|
|
||||||
playedAdCount.getAndIncrement(),
|
|
||||||
/* adIndexInAdGroup= */ 0));
|
|
||||||
fakeMediaSource.setNewSourceInfo(
|
|
||||||
new FakeTimeline(
|
|
||||||
new TimelineWindowDefinition(
|
|
||||||
/* periodCount= */ 1,
|
|
||||||
/* id= */ 0,
|
|
||||||
/* isSeekable= */ true,
|
|
||||||
/* isDynamic= */ false,
|
|
||||||
/* durationUs =*/ 10 * C.MICROS_PER_SECOND,
|
|
||||||
adPlaybackState.get())),
|
|
||||||
/* newManifest= */ null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.pause()
|
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
|
||||||
.play()
|
|
||||||
.waitForPlaybackState(Player.STATE_ENDED)
|
|
||||||
.build();
|
|
||||||
TestAnalyticsListener listener = runAnalyticsTest(fakeMediaSource, actionSchedule);
|
|
||||||
|
|
||||||
Object periodUid = listener.lastReportedTimeline.getUidOfPeriod(/* periodIndex= */ 0);
|
|
||||||
EventWindowAndPeriodId prerollAd =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
periodUid,
|
|
||||||
/* adGroupIndex= */ 0,
|
|
||||||
/* adIndexInAdGroup= */ 0,
|
|
||||||
/* windowSequenceNumber= */ 0));
|
|
||||||
EventWindowAndPeriodId midrollAd =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
periodUid,
|
|
||||||
/* adGroupIndex= */ 1,
|
|
||||||
/* adIndexInAdGroup= */ 0,
|
|
||||||
/* windowSequenceNumber= */ 0));
|
|
||||||
EventWindowAndPeriodId postrollAd =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
periodUid,
|
|
||||||
/* adGroupIndex= */ 2,
|
|
||||||
/* adIndexInAdGroup= */ 0,
|
|
||||||
/* windowSequenceNumber= */ 0));
|
|
||||||
EventWindowAndPeriodId contentAfterPreroll =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(periodUid, /* windowSequenceNumber= */ 0, /* nextAdGroupIndex= */ 1));
|
|
||||||
EventWindowAndPeriodId contentAfterMidroll =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(periodUid, /* windowSequenceNumber= */ 0, /* nextAdGroupIndex= */ 2));
|
|
||||||
EventWindowAndPeriodId contentAfterPostroll =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
periodUid, /* windowSequenceNumber= */ 0, /* nextAdGroupIndex= */ C.INDEX_UNSET));
|
|
||||||
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* setPlayWhenReady=true */,
|
|
||||||
WINDOW_0 /* setPlayWhenReady=false */,
|
|
||||||
WINDOW_0 /* BUFFERING */,
|
|
||||||
prerollAd /* READY */,
|
|
||||||
prerollAd /* setPlayWhenReady=true */,
|
|
||||||
contentAfterPostroll /* ENDED */);
|
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* PLAYLIST_CHANGED */,
|
|
||||||
WINDOW_0 /* SOURCE_UPDATE (initial) */,
|
|
||||||
contentAfterPreroll /* SOURCE_UPDATE (played preroll) */,
|
|
||||||
contentAfterMidroll /* SOURCE_UPDATE (played midroll) */,
|
|
||||||
contentAfterPostroll /* SOURCE_UPDATE (played postroll) */);
|
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY))
|
|
||||||
.containsExactly(
|
|
||||||
contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd, prerollAd, prerollAd, prerollAd, prerollAd, prerollAd, prerollAd, prerollAd,
|
|
||||||
prerollAd, prerollAd, prerollAd, prerollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOAD_STARTED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* content manifest */,
|
|
||||||
WINDOW_0 /* preroll manifest */,
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
WINDOW_0 /* midroll manifest */,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
WINDOW_0 /* postroll manifest */,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOAD_COMPLETED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* content manifest */,
|
|
||||||
WINDOW_0 /* preroll manifest */,
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
WINDOW_0 /* midroll manifest */,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
WINDOW_0 /* postroll manifest */,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_READING_STARTED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_ENABLED)).containsExactly(prerollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_INIT))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
prerollAd,
|
|
||||||
contentAfterPreroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
postrollAd,
|
|
||||||
contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES))
|
|
||||||
.containsExactly(contentAfterPostroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(prerollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(prerollAd);
|
|
||||||
listener.assertNoMoreEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSeekAfterMidroll() throws Exception {
|
|
||||||
Timeline adTimeline =
|
|
||||||
new FakeTimeline(
|
|
||||||
new TimelineWindowDefinition(
|
|
||||||
/* periodCount= */ 1,
|
|
||||||
/* id= */ 0,
|
|
||||||
/* isSeekable= */ true,
|
|
||||||
/* isDynamic= */ false,
|
|
||||||
10 * C.MICROS_PER_SECOND,
|
|
||||||
FakeTimeline.createAdPlaybackState(
|
|
||||||
/* adsPerAdGroup= */ 1, /* adGroupTimesUs...= */ 5 * C.MICROS_PER_SECOND)));
|
|
||||||
FakeMediaSource fakeMediaSource =
|
|
||||||
new FakeMediaSource(adTimeline, ExoPlayerTestRunner.Builder.VIDEO_FORMAT);
|
|
||||||
ActionSchedule actionSchedule =
|
|
||||||
new ActionSchedule.Builder("AnalyticsCollectorTest")
|
|
||||||
.pause()
|
|
||||||
// Ensure everything is preloaded.
|
|
||||||
.waitForIsLoading(true)
|
|
||||||
.waitForIsLoading(false)
|
|
||||||
.waitForIsLoading(true)
|
|
||||||
.waitForIsLoading(false)
|
|
||||||
.waitForIsLoading(true)
|
|
||||||
.waitForIsLoading(false)
|
|
||||||
// Seek behind the midroll.
|
|
||||||
.seek(6 * C.MICROS_PER_SECOND)
|
|
||||||
.play()
|
|
||||||
.waitForPlaybackState(Player.STATE_ENDED)
|
|
||||||
.build();
|
|
||||||
TestAnalyticsListener listener = runAnalyticsTest(fakeMediaSource, actionSchedule);
|
|
||||||
|
|
||||||
Object periodUid = listener.lastReportedTimeline.getUidOfPeriod(/* periodIndex= */ 0);
|
|
||||||
EventWindowAndPeriodId midrollAd =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
periodUid,
|
|
||||||
/* adGroupIndex= */ 0,
|
|
||||||
/* adIndexInAdGroup= */ 0,
|
|
||||||
/* windowSequenceNumber= */ 0));
|
|
||||||
EventWindowAndPeriodId contentBeforeMidroll =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(periodUid, /* windowSequenceNumber= */ 0, /* nextAdGroupIndex= */ 0));
|
|
||||||
EventWindowAndPeriodId contentAfterMidroll =
|
|
||||||
new EventWindowAndPeriodId(
|
|
||||||
/* windowIndex= */ 0,
|
|
||||||
new MediaPeriodId(
|
|
||||||
periodUid, /* windowSequenceNumber= */ 0, /* nextAdGroupIndex= */ C.INDEX_UNSET));
|
|
||||||
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* setPlayWhenReady=true */,
|
|
||||||
WINDOW_0 /* setPlayWhenReady=false */,
|
|
||||||
WINDOW_0 /* BUFFERING */,
|
|
||||||
contentBeforeMidroll /* READY */,
|
|
||||||
contentAfterMidroll /* setPlayWhenReady=true */,
|
|
||||||
midrollAd /* BUFFERING */,
|
|
||||||
midrollAd /* READY */,
|
|
||||||
contentAfterMidroll /* ENDED */);
|
|
||||||
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED))
|
|
||||||
.containsExactly(WINDOW_0 /* PLAYLIST_CHANGED */, WINDOW_0 /* SOURCE_UPDATE */);
|
|
||||||
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY))
|
|
||||||
.containsExactly(
|
|
||||||
contentAfterMidroll /* seek */,
|
|
||||||
midrollAd /* seek adjustment */,
|
|
||||||
contentAfterMidroll /* ad transition */);
|
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_STARTED)).containsExactly(contentBeforeMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_SEEK_PROCESSED)).containsExactly(midrollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOADING_CHANGED))
|
|
||||||
.containsExactly(
|
|
||||||
contentBeforeMidroll,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
midrollAd,
|
|
||||||
midrollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOAD_STARTED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* content manifest */,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_LOAD_COMPLETED))
|
|
||||||
.containsExactly(
|
|
||||||
WINDOW_0 /* content manifest */,
|
|
||||||
contentBeforeMidroll,
|
|
||||||
midrollAd,
|
|
||||||
contentAfterMidroll,
|
|
||||||
contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_CREATED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_MEDIA_PERIOD_RELEASED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_READING_STARTED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_ENABLED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_INIT))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd, contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(contentBeforeMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(contentAfterMidroll);
|
|
||||||
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd);
|
|
||||||
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME))
|
|
||||||
.containsExactly(contentBeforeMidroll, midrollAd);
|
|
||||||
listener.assertNoMoreEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNotifyExternalEvents() throws Exception {
|
public void testNotifyExternalEvents() throws Exception {
|
||||||
MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE);
|
MediaSource mediaSource = new FakeMediaSource(SINGLE_PERIOD_TIMELINE);
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
@ -161,19 +160,11 @@ public final class FakeTimeline extends Timeline {
|
|||||||
AdPlaybackState adPlaybackState = new AdPlaybackState(adGroupTimesUs);
|
AdPlaybackState adPlaybackState = new AdPlaybackState(adGroupTimesUs);
|
||||||
long[][] adDurationsUs = new long[adGroupCount][];
|
long[][] adDurationsUs = new long[adGroupCount][];
|
||||||
for (int i = 0; i < adGroupCount; i++) {
|
for (int i = 0; i < adGroupCount; i++) {
|
||||||
adPlaybackState = adPlaybackState.withAdCount(/* adGroupIndex= */ i, adsPerAdGroup);
|
adPlaybackState = adPlaybackState.withAdCount(i, adsPerAdGroup);
|
||||||
for (int j = 0; j < adsPerAdGroup; j++) {
|
|
||||||
adPlaybackState =
|
|
||||||
adPlaybackState.withAdUri(
|
|
||||||
/* adGroupIndex= */ i,
|
|
||||||
/* adIndexInAdGroup= */ j,
|
|
||||||
Uri.parse("https://ad/" + i + "/" + j));
|
|
||||||
}
|
|
||||||
adDurationsUs[i] = new long[adsPerAdGroup];
|
adDurationsUs[i] = new long[adsPerAdGroup];
|
||||||
Arrays.fill(adDurationsUs[i], AD_DURATION_US);
|
Arrays.fill(adDurationsUs[i], AD_DURATION_US);
|
||||||
}
|
}
|
||||||
adPlaybackState = adPlaybackState.withAdDurationsUs(adDurationsUs);
|
adPlaybackState = adPlaybackState.withAdDurationsUs(adDurationsUs);
|
||||||
|
|
||||||
return adPlaybackState;
|
return adPlaybackState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user