use of com.google.android.exoplayer2.ExoPlayer in project ExoPlayer by google.
the class ServerSideAdInsertionMediaSourceTest method playbackWithAdditionalAdsInAdGroup_playsSuccessfulWithoutRendererResets.
@Test
public void playbackWithAdditionalAdsInAdGroup_playsSuccessfulWithoutRendererResets() throws Exception {
Context context = ApplicationProvider.getApplicationContext();
AtomicReference<Object> periodUid = new AtomicReference<>();
CapturingRenderersFactory renderersFactory = new CapturingRenderersFactory(context);
ExoPlayer player = new ExoPlayer.Builder(context, renderersFactory).setClock(new FakeClock(/* isAutoAdvancing= */
true)).build();
player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */
1)));
PlaybackOutput playbackOutput = PlaybackOutput.register(player, renderersFactory);
AdPlaybackState firstAdPlaybackState = addAdGroupToAdPlaybackState(new AdPlaybackState(/* adsId= */
new Object()), /* fromPositionUs= */
0, /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
500_000);
AtomicReference<ServerSideAdInsertionMediaSource> mediaSourceRef = new AtomicReference<>();
mediaSourceRef.set(new ServerSideAdInsertionMediaSource(new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)), /* adPlaybackStateUpdater= */
contentTimeline -> {
if (periodUid.get() == null) {
periodUid.set(checkNotNull(contentTimeline.getPeriod(/* periodIndex= */
0, new Timeline.Period(), /* setIds= */
true).uid));
mediaSourceRef.get().setAdPlaybackStates(ImmutableMap.of(periodUid.get(), firstAdPlaybackState));
}
return true;
}));
AnalyticsListener listener = mock(AnalyticsListener.class);
player.addAnalyticsListener(listener);
player.setMediaSource(mediaSourceRef.get());
player.prepare();
// Wait until playback is ready with first ad and then replace by 3 ads.
runUntilPlaybackState(player, Player.STATE_READY);
AdPlaybackState secondAdPlaybackState = firstAdPlaybackState.withAdCount(/* adGroupIndex= */
0, /* adCount= */
3).withAdDurationsUs(/* adGroupIndex= */
0, /* adDurationsUs...= */
50_000, 250_000, 200_000);
mediaSourceRef.get().setAdPlaybackStates(ImmutableMap.of(periodUid.get(), secondAdPlaybackState));
runUntilPendingCommandsAreFullyHandled(player);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
// Assert all samples have been played.
DumpFileAsserts.assertOutput(context, playbackOutput, TEST_ASSET_DUMP);
// Assert playback has been reported with ads: [ad0][ad1][ad2][content]
// 4*2(audio+video) format changes, 3 discontinuities between parts.
verify(listener, times(3)).onPositionDiscontinuity(any(), any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
verify(listener, times(8)).onDownstreamFormatChanged(any(), any());
// Assert renderers played through without reset (=decoders have been enabled only once).
verify(listener).onVideoEnabled(any(), any());
verify(listener).onAudioEnabled(any(), any());
// Assert playback progression was smooth (=no unexpected delays that cause audio to underrun)
verify(listener, never()).onAudioUnderrun(any(), anyInt(), anyLong(), anyLong());
}
use of com.google.android.exoplayer2.ExoPlayer in project ExoPlayer by google.
the class RtspMediaPeriodTest method prepareMediaPeriod_withWwwAuthentication_refreshesSourceInfoAndCallsOnPrepared.
@Test
public void prepareMediaPeriod_withWwwAuthentication_refreshesSourceInfoAndCallsOnPrepared() throws Exception {
RtpPacketStreamDump rtpPacketStreamDump = RtspTestUtils.readRtpPacketStreamDump("media/rtsp/aac-dump.json");
rtspServer = new RtspServer(new RtspServer.ResponseProvider() {
@Override
public RtspResponse getOptionsResponse() {
return new RtspResponse(/* status= */
200, new RtspHeaders.Builder().add(RtspHeaders.PUBLIC, "OPTIONS, DESCRIBE").build());
}
@Override
public RtspResponse getDescribeResponse(Uri requestedUri, RtspHeaders headers) {
String authorizationHeader = headers.get(RtspHeaders.AUTHORIZATION);
if (authorizationHeader == null) {
return new RtspResponse(/* status= */
401, new RtspHeaders.Builder().add(RtspHeaders.CSEQ, headers.get(RtspHeaders.CSEQ)).add(RtspHeaders.WWW_AUTHENTICATE, "Digest realm=\"RTSP server\"," + " nonce=\"0cdfe9719e7373b7d5bb2913e2115f3f\"," + " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"").add(RtspHeaders.WWW_AUTHENTICATE, "BASIC realm=\"WallyWorld\"").build());
}
if (!authorizationHeader.contains("Digest")) {
return new RtspResponse(401, new RtspHeaders.Builder().add(RtspHeaders.CSEQ, headers.get(RtspHeaders.CSEQ)).build());
}
return RtspTestUtils.newDescribeResponseWithSdpMessage("v=0\r\n" + "o=- 1606776316530225 1 IN IP4 127.0.0.1\r\n" + "s=Exoplayer test\r\n" + "t=0 0\r\n" + // The session is 50.46s long.
"a=range:npt=0-50.46\r\n", ImmutableList.of(rtpPacketStreamDump), requestedUri);
}
});
AtomicBoolean prepareCallbackCalled = new AtomicBoolean();
AtomicLong refreshedSourceDurationMs = new AtomicLong();
mediaPeriod = new RtspMediaPeriod(new DefaultAllocator(/* trimOnReset= */
true, C.DEFAULT_BUFFER_SEGMENT_SIZE), new TransferRtpDataChannelFactory(DEFAULT_TIMEOUT_MS), RtspTestUtils.getTestUriWithUserInfo("username", "password", rtspServer.startAndGetPortNumber()), /* listener= */
timing -> refreshedSourceDurationMs.set(timing.getDurationMs()), /* userAgent= */
"ExoPlayer:RtspPeriodTest", /* socketFactory= */
SocketFactory.getDefault(), /* debugLoggingEnabled= */
false);
mediaPeriod.prepare(new MediaPeriod.Callback() {
@Override
public void onPrepared(MediaPeriod mediaPeriod) {
prepareCallbackCalled.set(true);
}
@Override
public void onContinueLoadingRequested(MediaPeriod source) {
source.continueLoading(/* positionUs= */
0);
}
}, /* positionUs= */
0);
RobolectricUtil.runMainLooperUntil(prepareCallbackCalled::get);
mediaPeriod.release();
assertThat(refreshedSourceDurationMs.get()).isEqualTo(50_460);
}
use of com.google.android.exoplayer2.ExoPlayer in project ExoPlayer by google.
the class RtspPlaybackTest method createExoPlayer.
private ExoPlayer createExoPlayer(int serverRtspPortNumber, RtpDataChannel.Factory rtpDataChannelFactory) {
ExoPlayer player = new ExoPlayer.Builder(applicationContext, capturingRenderersFactory).setClock(clock).build();
player.setMediaSource(new RtspMediaSource(MediaItem.fromUri(RtspTestUtils.getTestUri(serverRtspPortNumber)), rtpDataChannelFactory, "ExoPlayer:PlaybackTest", SocketFactory.getDefault(), /* debugLoggingEnabled= */
false), false);
return player;
}
use of com.google.android.exoplayer2.ExoPlayer in project ExoPlayer by google.
the class RtspPlaybackTest method prepare_withSupportedTrack_playsTrackUntilEnded.
@Test
public void prepare_withSupportedTrack_playsTrackUntilEnded() throws Exception {
ResponseProvider responseProvider = new ResponseProvider(clock, ImmutableList.of(aacRtpPacketStreamDump, mp4aLatmRtpPacketStreamDump), fakeRtpDataChannel);
try (RtspServer rtspServer = new RtspServer(responseProvider)) {
ExoPlayer player = createExoPlayer(rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
PlaybackOutput playbackOutput = PlaybackOutput.register(player, capturingRenderersFactory);
player.prepare();
player.play();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
// Only setup the supported track (aac).
assertThat(responseProvider.getDumpsForSetUpTracks()).containsExactly(aacRtpPacketStreamDump);
DumpFileAsserts.assertOutput(applicationContext, playbackOutput, "playbackdumps/rtsp/aac.dump");
}
}
use of com.google.android.exoplayer2.ExoPlayer in project ExoPlayer by google.
the class RtspPlaybackTest method prepare_noSupportedTrack_throwsPreparationError.
@Test
public void prepare_noSupportedTrack_throwsPreparationError() throws Exception {
try (RtspServer rtspServer = new RtspServer(new ResponseProvider(clock, ImmutableList.of(mp4aLatmRtpPacketStreamDump), fakeRtpDataChannel))) {
ExoPlayer player = createExoPlayer(rtspServer.startAndGetPortNumber(), rtpDataChannelFactory);
AtomicReference<Throwable> playbackError = new AtomicReference<>();
player.prepare();
player.addListener(new Listener() {
@Override
public void onPlayerError(PlaybackException error) {
playbackError.set(error);
}
});
RobolectricUtil.runMainLooperUntil(() -> playbackError.get() != null);
player.release();
assertThat(playbackError.get()).hasCauseThat().hasMessageThat().contains("No playable track.");
}
}
Aggregations