Search in sources :

Example 6 with MediaPeriod

use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.

the class ConcatenatingMediaSourceTest method playlistWithLazyMediaSource.

@Test
public void playlistWithLazyMediaSource() throws IOException, InterruptedException {
    // Create some normal (immediately preparing) sources and some lazy sources whose timeline
    // updates need to be triggered.
    FakeMediaSource[] fastSources = createMediaSources(2);
    final FakeMediaSource[] lazySources = new FakeMediaSource[4];
    for (int i = 0; i < 4; i++) {
        lazySources[i] = new FakeMediaSource(null);
    }
    // Add lazy sources and normal sources before preparation. Also remove one lazy source again
    // before preparation to check it doesn't throw or change the result.
    mediaSource.addMediaSource(lazySources[0]);
    mediaSource.addMediaSource(0, fastSources[0]);
    mediaSource.removeMediaSource(1);
    mediaSource.addMediaSource(1, lazySources[1]);
    testRunner.assertNoTimelineChange();
    // Prepare and assert that the timeline contains all information for normal sources while having
    // placeholder information for lazy sources.
    Timeline timeline = testRunner.prepareSource();
    TimelineAsserts.assertPeriodCounts(timeline, 1, 1);
    TimelineAsserts.assertWindowTags(timeline, 111, null);
    TimelineAsserts.assertWindowIsDynamic(timeline, false, true);
    // Trigger source info refresh for lazy source and check that the timeline now contains all
    // information for all windows.
    testRunner.runOnPlaybackThread(() -> lazySources[1].setNewSourceInfo(createFakeTimeline(8)));
    timeline = testRunner.assertTimelineChangeBlocking();
    TimelineAsserts.assertPeriodCounts(timeline, 1, 9);
    TimelineAsserts.assertWindowTags(timeline, 111, 999);
    TimelineAsserts.assertWindowIsDynamic(timeline, false, false);
    testRunner.assertPrepareAndReleaseAllPeriods();
    testRunner.assertCompletedManifestLoads(0, 1);
    assertCompletedAllMediaPeriodLoads(timeline);
    // Add further lazy and normal sources after preparation. Also remove one lazy source again to
    // check it doesn't throw or change the result.
    mediaSource.addMediaSource(1, lazySources[2]);
    testRunner.assertTimelineChangeBlocking();
    mediaSource.addMediaSource(2, fastSources[1]);
    testRunner.assertTimelineChangeBlocking();
    mediaSource.addMediaSource(0, lazySources[3]);
    testRunner.assertTimelineChangeBlocking();
    mediaSource.removeMediaSource(2);
    timeline = testRunner.assertTimelineChangeBlocking();
    TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 2, 9);
    TimelineAsserts.assertWindowTags(timeline, null, 111, 222, 999);
    TimelineAsserts.assertWindowIsDynamic(timeline, true, false, false, false);
    // Create a period from an unprepared lazy media source and assert Callback.onPrepared is not
    // called yet.
    MediaPeriod lazyPeriod = testRunner.createPeriod(new MediaPeriodId(timeline.getUidOfPeriod(/* periodIndex= */
    0), /* windowSequenceNumber= */
    0));
    CountDownLatch preparedCondition = testRunner.preparePeriod(lazyPeriod, 0);
    assertThat(preparedCondition.getCount()).isEqualTo(1);
    // Trigger source info refresh for lazy media source. Assert that now all information is
    // available again and the previously created period now also finished preparing.
    testRunner.runOnPlaybackThread(() -> lazySources[3].setNewSourceInfo(createFakeTimeline(7)));
    timeline = testRunner.assertTimelineChangeBlocking();
    TimelineAsserts.assertPeriodCounts(timeline, 8, 1, 2, 9);
    TimelineAsserts.assertWindowTags(timeline, 888, 111, 222, 999);
    TimelineAsserts.assertWindowIsDynamic(timeline, false, false, false, false);
    assertThat(preparedCondition.getCount()).isEqualTo(0);
    // Release the period and source.
    testRunner.releasePeriod(lazyPeriod);
    testRunner.releaseSource();
    // Assert all sources were fully released.
    for (FakeMediaSource fastSource : fastSources) {
        fastSource.assertReleased();
    }
    for (FakeMediaSource lazySource : lazySources) {
        lazySource.assertReleased();
    }
}
Also used : Timeline(com.google.android.exoplayer2.Timeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.Test)

Example 7 with MediaPeriod

use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.

the class ClippingMediaSourceTest method getClippedTimelines.

private static Timeline[] getClippedTimelines(FakeMediaSource fakeMediaSource, ClippingMediaSource clippingMediaSource, Timeline... additionalTimelines) throws IOException {
    MediaSourceTestRunner testRunner = new MediaSourceTestRunner(clippingMediaSource, /* allocator= */
    null);
    Timeline[] clippedTimelines = new Timeline[additionalTimelines.length + 1];
    try {
        clippedTimelines[0] = testRunner.prepareSource();
        MediaPeriod mediaPeriod = testRunner.createPeriod(new MediaPeriodId(clippedTimelines[0].getUidOfPeriod(/* periodIndex= */
        0), /* windowSequenceNumber= */
        0));
        for (int i = 0; i < additionalTimelines.length; i++) {
            fakeMediaSource.setNewSourceInfo(additionalTimelines[i]);
            clippedTimelines[i + 1] = testRunner.assertTimelineChangeBlocking();
        }
        testRunner.releasePeriod(mediaPeriod);
        testRunner.releaseSource();
        fakeMediaSource.assertReleased();
        return clippedTimelines;
    } finally {
        testRunner.release();
    }
}
Also used : PlaceholderTimeline(com.google.android.exoplayer2.source.MaskingMediaSource.PlaceholderTimeline) Timeline(com.google.android.exoplayer2.Timeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) MediaSourceTestRunner(com.google.android.exoplayer2.testutil.MediaSourceTestRunner) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)

Example 8 with MediaPeriod

use of com.google.android.exoplayer2.source.MediaPeriod 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);
}
Also used : Util(com.google.android.exoplayer2.util.Util) Uri(android.net.Uri) RunWith(org.junit.runner.RunWith) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.junit.Test) Truth.assertThat(com.google.common.truth.Truth.assertThat) AndroidJUnit4(androidx.test.ext.junit.runners.AndroidJUnit4) SocketFactory(javax.net.SocketFactory) AtomicLong(java.util.concurrent.atomic.AtomicLong) RobolectricUtil(com.google.android.exoplayer2.robolectric.RobolectricUtil) ImmutableList(com.google.common.collect.ImmutableList) MediaPeriod(com.google.android.exoplayer2.source.MediaPeriod) After(org.junit.After) DefaultAllocator(com.google.android.exoplayer2.upstream.DefaultAllocator) C(com.google.android.exoplayer2.C) Uri(android.net.Uri) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) DefaultAllocator(com.google.android.exoplayer2.upstream.DefaultAllocator) MediaPeriod(com.google.android.exoplayer2.source.MediaPeriod) Test(org.junit.Test)

Example 9 with MediaPeriod

use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.

the class ExoPlayerTest method seekBeforePreparationCompletes_seeksToCorrectPosition.

@Test
public void seekBeforePreparationCompletes_seeksToCorrectPosition() throws Exception {
    CountDownLatch createPeriodCalledCountDownLatch = new CountDownLatch(1);
    FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1];
    FakeMediaSource mediaSource = new FakeMediaSource(/* timeline= */
    null, ExoPlayerTestRunner.VIDEO_FORMAT) {

        @Override
        protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
            // Defer completing preparation of the period until seek has been sent.
            fakeMediaPeriodHolder[0] = new FakeMediaPeriod(trackGroupArray, allocator, TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
            true);
            createPeriodCalledCountDownLatch.countDown();
            return fakeMediaPeriodHolder[0];
        }
    };
    AtomicLong positionWhenReady = new AtomicLong();
    ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).pause().waitForPlaybackState(Player.STATE_BUFFERING).delay(1).executeRunnable(() -> mediaSource.setNewSourceInfo(new FakeTimeline())).waitForTimelineChanged().executeRunnable(() -> {
        try {
            createPeriodCalledCountDownLatch.await();
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }).seek(5000).executeRunnable(() -> fakeMediaPeriodHolder[0].setPreparationComplete()).waitForPlaybackState(Player.STATE_READY).executeRunnable(new PlayerRunnable() {

        @Override
        public void run(ExoPlayer player) {
            positionWhenReady.set(player.getCurrentPosition());
        }
    }).play().build();
    new ExoPlayerTestRunner.Builder(context).initialSeek(/* mediaItemIndex= */
    0, /* positionMs= */
    2000).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
    assertThat(positionWhenReady.get()).isAtLeast(5000);
}
Also used : TransferListener(com.google.android.exoplayer2.upstream.TransferListener) Allocator(com.google.android.exoplayer2.upstream.Allocator) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) ActionSchedule(com.google.android.exoplayer2.testutil.ActionSchedule) PlayerRunnable(com.google.android.exoplayer2.testutil.ActionSchedule.PlayerRunnable) DrmSessionManager(com.google.android.exoplayer2.drm.DrmSessionManager) TestExoPlayerBuilder(com.google.android.exoplayer2.testutil.TestExoPlayerBuilder) TrackGroupArray(com.google.android.exoplayer2.source.TrackGroupArray) CountDownLatch(java.util.concurrent.CountDownLatch) FakeMediaPeriod(com.google.android.exoplayer2.testutil.FakeMediaPeriod) AtomicLong(java.util.concurrent.atomic.AtomicLong) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) Nullable(androidx.annotation.Nullable) Test(org.junit.Test)

Example 10 with MediaPeriod

use of com.google.android.exoplayer2.source.MediaPeriod in project ExoPlayer by google.

the class ExoPlayerTest method seekPastBufferingMidroll_playsAdAndThenContentFromSeekPosition.

@Test
public void seekPastBufferingMidroll_playsAdAndThenContentFromSeekPosition() throws Exception {
    long adGroupWindowTimeMs = 1_000;
    long seekPositionMs = 95_000;
    long contentDurationMs = 100_000;
    AdPlaybackState adPlaybackState = FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */
    1, /* adGroupTimesUs...= */
    TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US + Util.msToUs(adGroupWindowTimeMs));
    Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
    1, /* id= */
    0, /* isSeekable= */
    true, /* isDynamic= */
    false, /* durationUs= */
    Util.msToUs(contentDurationMs), adPlaybackState));
    AtomicBoolean hasCreatedAdMediaPeriod = new AtomicBoolean();
    FakeMediaSource mediaSource = new FakeMediaSource(timeline) {

        @Override
        public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
            if (id.adGroupIndex == 0) {
                hasCreatedAdMediaPeriod.set(true);
            }
            return super.createPeriod(id, allocator, startPositionUs);
        }
    };
    ExoPlayer player = new TestExoPlayerBuilder(context).build();
    player.setMediaSource(mediaSource);
    // Throw on the playback thread if the player position reaches a value that is just less than
    // seek position. This ensures that playback stops and the assertion on the player position
    // below fails, even if a long time passes between detecting the discontinuity and asserting.
    player.createMessage((messageType, payload) -> {
        throw new IllegalStateException();
    }).setPosition(seekPositionMs - 1).send();
    player.pause();
    player.prepare();
    // Block until the midroll has started buffering, then seek after the midroll before playing.
    runMainLooperUntil(hasCreatedAdMediaPeriod::get);
    player.seekTo(seekPositionMs);
    player.play();
    // When the ad finishes, the player position should be at or after the requested seek position.
    runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
    assertThat(player.getCurrentPosition()).isAtLeast(seekPositionMs);
}
Also used : Allocator(com.google.android.exoplayer2.upstream.Allocator) FakeMediaSource(com.google.android.exoplayer2.testutil.FakeMediaSource) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) NoUidTimeline(com.google.android.exoplayer2.testutil.NoUidTimeline) SinglePeriodTimeline(com.google.android.exoplayer2.source.SinglePeriodTimeline) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) AdPlaybackState(com.google.android.exoplayer2.source.ads.AdPlaybackState) ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState(com.google.android.exoplayer2.source.ads.ServerSideAdInsertionUtil.addAdGroupToAdPlaybackState) FakeTimeline(com.google.android.exoplayer2.testutil.FakeTimeline) TimelineWindowDefinition(com.google.android.exoplayer2.testutil.FakeTimeline.TimelineWindowDefinition) MediaPeriodId(com.google.android.exoplayer2.source.MediaSource.MediaPeriodId) TestExoPlayerBuilder(com.google.android.exoplayer2.testutil.TestExoPlayerBuilder) Test(org.junit.Test)

Aggregations

MediaPeriodId (com.google.android.exoplayer2.source.MediaSource.MediaPeriodId)23 Test (org.junit.Test)21 FakeTimeline (com.google.android.exoplayer2.testutil.FakeTimeline)18 FakeMediaSource (com.google.android.exoplayer2.testutil.FakeMediaSource)17 Nullable (androidx.annotation.Nullable)15 TrackGroupArray (com.google.android.exoplayer2.source.TrackGroupArray)15 Allocator (com.google.android.exoplayer2.upstream.Allocator)15 DrmSessionManager (com.google.android.exoplayer2.drm.DrmSessionManager)14 MediaPeriod (com.google.android.exoplayer2.source.MediaPeriod)14 FakeMediaPeriod (com.google.android.exoplayer2.testutil.FakeMediaPeriod)14 TransferListener (com.google.android.exoplayer2.upstream.TransferListener)13 TestExoPlayerBuilder (com.google.android.exoplayer2.testutil.TestExoPlayerBuilder)11 DrmSessionEventListener (com.google.android.exoplayer2.drm.DrmSessionEventListener)9 CountDownLatch (java.util.concurrent.CountDownLatch)9 ExoPlayerTestRunner (com.google.android.exoplayer2.testutil.ExoPlayerTestRunner)8 AndroidJUnit4 (androidx.test.ext.junit.runners.AndroidJUnit4)7 MaskingMediaSource (com.google.android.exoplayer2.source.MaskingMediaSource)7 MediaSource (com.google.android.exoplayer2.source.MediaSource)7 SinglePeriodTimeline (com.google.android.exoplayer2.source.SinglePeriodTimeline)7 ActionSchedule (com.google.android.exoplayer2.testutil.ActionSchedule)7