use of com.google.android.exoplayer2.testutil.FakeMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method testPlaySinglePeriodTimeline.
/**
* Tests playback of a source that exposes a single period.
*/
public void testPlaySinglePeriodTimeline() throws Exception {
PlayerWrapper playerWrapper = new PlayerWrapper();
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(false, false, 0));
Object manifest = new Object();
MediaSource mediaSource = new FakeMediaSource(timeline, manifest, TEST_VIDEO_FORMAT);
FakeRenderer renderer = new FakeRenderer(TEST_VIDEO_FORMAT);
playerWrapper.setup(mediaSource, renderer);
playerWrapper.blockUntilEnded(TIMEOUT_MS);
assertEquals(0, playerWrapper.positionDiscontinuityCount);
assertEquals(1, renderer.formatReadCount);
assertEquals(1, renderer.bufferReadCount);
assertTrue(renderer.isEnded);
assertEquals(timeline, playerWrapper.timeline);
assertEquals(manifest, playerWrapper.manifest);
assertEquals(new TrackGroupArray(new TrackGroup(TEST_VIDEO_FORMAT)), playerWrapper.trackGroups);
}
use of com.google.android.exoplayer2.testutil.FakeMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method testReadAheadToEndDoesNotResetRenderer.
/**
* Tests that the player does not unnecessarily reset renderers when playing a multi-period
* source.
*/
public void testReadAheadToEndDoesNotResetRenderer() throws Exception {
final PlayerWrapper playerWrapper = new PlayerWrapper();
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(false, false, 10), new TimelineWindowDefinition(false, false, 10), new TimelineWindowDefinition(false, false, 10));
MediaSource mediaSource = new FakeMediaSource(timeline, null, TEST_VIDEO_FORMAT, TEST_AUDIO_FORMAT);
FakeRenderer videoRenderer = new FakeRenderer(TEST_VIDEO_FORMAT);
FakeMediaClockRenderer audioRenderer = new FakeMediaClockRenderer(TEST_AUDIO_FORMAT) {
@Override
public long getPositionUs() {
// TODO: Avoid hard-coding ExoPlayerImplInternal.RENDERER_TIMESTAMP_OFFSET_US.
return isCurrentStreamFinal() ? 60000030 : 60000000;
}
@Override
public boolean isEnded() {
// Allow playback to end once the final period is playing.
return playerWrapper.positionDiscontinuityCount == 2;
}
};
playerWrapper.setup(mediaSource, videoRenderer, audioRenderer);
playerWrapper.blockUntilEnded(TIMEOUT_MS);
assertEquals(2, playerWrapper.positionDiscontinuityCount);
assertEquals(1, audioRenderer.positionResetCount);
assertTrue(videoRenderer.isEnded);
assertTrue(audioRenderer.isEnded);
assertEquals(timeline, playerWrapper.timeline);
assertNull(playerWrapper.manifest);
}
use of com.google.android.exoplayer2.testutil.FakeMediaSource in project ExoPlayer by google.
the class DefaultAnalyticsCollectorTest method adPlayback.
@Test
public void adPlayback() throws Exception {
long contentDurationsUs = 11 * C.MICROS_PER_SECOND;
long windowOffsetInFirstPeriodUs = TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
AtomicReference<AdPlaybackState> adPlaybackState = new AtomicReference<>(FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */
1, /* adGroupTimesUs...= */
windowOffsetInFirstPeriodUs, windowOffsetInFirstPeriodUs + 5 * C.MICROS_PER_SECOND, C.TIME_END_OF_SOURCE));
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, DrmSessionManager.DRM_UNSUPPORTED, (unusedFormat, mediaPeriodId) -> {
if (mediaPeriodId.isAd()) {
return ImmutableList.of(oneByteSample(/* timeUs= */
0, C.BUFFER_FLAG_KEY_FRAME), END_OF_STREAM_ITEM);
} else {
// postroll.
return ImmutableList.of(oneByteSample(windowOffsetInFirstPeriodUs + C.MICROS_PER_SECOND, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(windowOffsetInFirstPeriodUs + 6 * C.MICROS_PER_SECOND, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(windowOffsetInFirstPeriodUs + contentDurationsUs, C.BUFFER_FLAG_KEY_FRAME), END_OF_STREAM_ITEM);
}
}, ExoPlayerTestRunner.VIDEO_FORMAT);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
player.addListener(new Player.Listener() {
@Override
public void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, @Player.DiscontinuityReason int reason) {
if (!player.isPlayingAd() && reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
// Finished playing ad. Marked as played.
adPlaybackState.set(adPlaybackState.get().withPlayedAd(/* adGroupIndex= */
playedAdCount.getAndIncrement(), /* adIndexInAdGroup= */
0));
fakeMediaSource.setNewSourceInfo(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
false, contentDurationsUs, adPlaybackState.get())), /* sendManifestLoadEvents= */
false);
}
}
});
}
}).pause().waitForIsLoading(true).waitForIsLoading(false).waitForPlaybackState(Player.STATE_READY).playUntilPosition(/* mediaItemIndex= */
0, /* positionMs= */
3_000).waitForPendingPlayerCommands().playUntilPosition(/* mediaItemIndex= */
0, /* positionMs= */
8_000).waitForPendingPlayerCommands().play().waitForPlaybackState(Player.STATE_ENDED).waitForTimelineChanged().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 */
contentAfterPreroll, /* setPlayWhenReady=false */
contentAfterPreroll, /* setPlayWhenReady=true */
contentAfterMidroll, /* setPlayWhenReady=false */
contentAfterMidroll, /* setPlayWhenReady=true */
contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0, /* PLAYLIST_CHANGED */
prerollAd, /* SOURCE_UPDATE (initial) */
contentAfterPreroll, /* SOURCE_UPDATE (played preroll) */
contentAfterMidroll, /* SOURCE_UPDATE (played midroll) */
contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_IS_LOADING_CHANGED)).containsExactly(prerollAd, prerollAd).inOrder();
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_LOAD_STARTED)).containsExactly(WINDOW_0, /* content manifest */
prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)).containsExactly(WINDOW_0, /* content manifest */
prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_DECODER_ENABLED)).containsExactly(prerollAd);
assertThat(listener.getEvents(EVENT_DECODER_INIT)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_ENABLED)).containsExactly(prerollAd);
assertThat(listener.getEvents(EVENT_VIDEO_DECODER_INITIALIZED)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_INPUT_FORMAT_CHANGED)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(contentAfterPreroll, contentAfterMidroll, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(prerollAd, contentAfterPreroll, midrollAd, contentAfterMidroll, postrollAd, contentAfterPostroll).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_FRAME_PROCESSING_OFFSET)).containsExactly(contentAfterPreroll, contentAfterMidroll, contentAfterPostroll).inOrder();
listener.assertNoMoreEvents();
}
use of com.google.android.exoplayer2.testutil.FakeMediaSource in project ExoPlayer by google.
the class DefaultAnalyticsCollectorTest method onPlayerError_thrownDuringRenderAtPeriodTransition_isReportedForNewPeriod.
@Test
public void onPlayerError_thrownDuringRenderAtPeriodTransition_isReportedForNewPeriod() throws Exception {
FakeMediaSource source0 = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT);
FakeMediaSource source1 = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.AUDIO_FORMAT);
RenderersFactory renderersFactory = (eventHandler, videoListener, audioListener, textOutput, metadataOutput) -> new Renderer[] { new FakeRenderer(C.TRACK_TYPE_VIDEO), new FakeRenderer(C.TRACK_TYPE_AUDIO) {
@Override
public void render(long positionUs, long realtimeUs) throws ExoPlaybackException {
// transition.
throw createRendererException(new IllegalStateException(), ExoPlayerTestRunner.AUDIO_FORMAT, PlaybackException.ERROR_CODE_UNSPECIFIED);
}
} };
TestAnalyticsListener listener = runAnalyticsTest(new ConcatenatingMediaSource(source0, source1), /* actionSchedule= */
null, renderersFactory);
populateEventIds(listener.lastReportedTimeline);
assertThat(listener.getEvents(EVENT_PLAYER_ERROR)).containsExactly(period1);
}
use of com.google.android.exoplayer2.testutil.FakeMediaSource in project ExoPlayer by google.
the class DefaultAnalyticsCollectorTest method release_withCallbacksArrivingAfterRelease_onPlayerReleasedForwardedLast.
@Test
public void release_withCallbacksArrivingAfterRelease_onPlayerReleasedForwardedLast() throws Exception {
FakeClock fakeClock = new FakeClock(/* initialTimeMs= */
0, /* isAutoAdvancing= */
true);
ExoPlayer exoPlayer = new TestExoPlayerBuilder(ApplicationProvider.getApplicationContext()).setClock(fakeClock).build();
AnalyticsListener analyticsListener = spy(new AnalyticsListener() {
@Override
public void onVideoDisabled(EventTime eventTime, DecoderCounters decoderCounters) {
// Add delay in callback to test whether event timestamp and release timestamp are
// in the correct order.
fakeClock.advanceTime(1);
}
});
exoPlayer.addAnalyticsListener(analyticsListener);
// Prepare with media to ensure video renderer is enabled.
exoPlayer.setMediaSource(new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT));
exoPlayer.prepare();
TestPlayerRunHelper.runUntilPlaybackState(exoPlayer, Player.STATE_READY);
// Release and add delay on releasing thread to verify timestamps of events.
exoPlayer.release();
long releaseTimeMs = fakeClock.currentTimeMillis();
fakeClock.advanceTime(1);
ShadowLooper.idleMainLooper();
// Verify video disable events and release events arrived in order.
ArgumentCaptor<AnalyticsListener.EventTime> videoDisabledEventTime = ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
ArgumentCaptor<AnalyticsListener.EventTime> releasedEventTime = ArgumentCaptor.forClass(AnalyticsListener.EventTime.class);
InOrder inOrder = inOrder(analyticsListener);
inOrder.verify(analyticsListener).onVideoDisabled(videoDisabledEventTime.capture(), any());
inOrder.verify(analyticsListener).onEvents(same(exoPlayer), argThat(events -> events.contains(EVENT_VIDEO_DISABLED)));
inOrder.verify(analyticsListener).onPlayerReleased(releasedEventTime.capture());
inOrder.verify(analyticsListener).onEvents(same(exoPlayer), argThat(events -> events.contains(EVENT_PLAYER_RELEASED)));
// Verify order of timestamps of these events.
// This verification is needed as a regression test against [internal ref: b/195396384]. The
// root cause of the regression was an onPlayerReleased timestamp that was less than the
// previously reported timestamps for other events triggered as part of the release.
long videoDisableTimeMs = videoDisabledEventTime.getValue().realtimeMs;
assertThat(videoDisableTimeMs).isGreaterThan(releaseTimeMs);
assertThat(releasedEventTime.getValue().realtimeMs).isGreaterThan(videoDisableTimeMs);
}
Aggregations