ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHolder> { public synchronized void addMediaSource(MediaSource mediaSource) { addMediaSource(mediaSourcesPublic.size(), mediaSource); } ConcatenatingMediaSource(MediaSource... mediaSources);  ConcatenatingMediaSource(boolean isAtomic, MediaSource... mediaSources);  ConcatenatingMediaSource(
      boolean isAtomic, ShuffleOrder shuffleOrder, MediaSource... mediaSources); @SuppressWarnings("initialization")  ConcatenatingMediaSource(
      boolean isAtomic,
      boolean useLazyPreparation,
      ShuffleOrder shuffleOrder,
      MediaSource... mediaSources); synchronized void addMediaSource(MediaSource mediaSource); synchronized void addMediaSource(
      MediaSource mediaSource, Handler handler, Runnable onCompletionAction); synchronized void addMediaSource(int index, MediaSource mediaSource); synchronized void addMediaSource(
      int index, MediaSource mediaSource, Handler handler, Runnable onCompletionAction); synchronized void addMediaSources(Collection<MediaSource> mediaSources); synchronized void addMediaSources(
      Collection<MediaSource> mediaSources, Handler handler, Runnable onCompletionAction); synchronized void addMediaSources(int index, Collection<MediaSource> mediaSources); synchronized void addMediaSources(
      int index,
      Collection<MediaSource> mediaSources,
      Handler handler,
      Runnable onCompletionAction); synchronized MediaSource removeMediaSource(int index); synchronized MediaSource removeMediaSource(
      int index, Handler handler, Runnable onCompletionAction); synchronized void removeMediaSourceRange(int fromIndex, int toIndex); synchronized void removeMediaSourceRange(
      int fromIndex, int toIndex, Handler handler, Runnable onCompletionAction); synchronized void moveMediaSource(int currentIndex, int newIndex); synchronized void moveMediaSource(
      int currentIndex, int newIndex, Handler handler, Runnable onCompletionAction); synchronized void clear(); synchronized void clear(Handler handler, Runnable onCompletionAction); synchronized int getSize(); synchronized MediaSource getMediaSource(int index); synchronized void setShuffleOrder(ShuffleOrder shuffleOrder); synchronized void setShuffleOrder(
      ShuffleOrder shuffleOrder, Handler handler, Runnable onCompletionAction); @Override @Nullable Object getTag(); @Override MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs); @Override void releasePeriod(MediaPeriod mediaPeriod);  }
@Test public void testCustomCallbackBeforePreparationAddSingle() throws Exception { CountDownLatch runnableInvoked = new CountDownLatch(1); DummyMainThread dummyMainThread = new DummyMainThread(); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSource( createFakeMediaSource(), new Handler(), runnableInvoked::countDown)); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS); dummyMainThread.release(); assertThat(runnableInvoked.getCount()).isEqualTo(0); }
@Test public void testCustomCallbackBeforePreparationAddSingleWithIndex() throws Exception { CountDownLatch runnableInvoked = new CountDownLatch(1); DummyMainThread dummyMainThread = new DummyMainThread(); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSource( 0, createFakeMediaSource(), new Handler(), runnableInvoked::countDown)); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS); dummyMainThread.release(); assertThat(runnableInvoked.getCount()).isEqualTo(0); }
@Test public void testCustomCallbackAfterPreparationAddSingle() throws Exception { DummyMainThread dummyMainThread = new DummyMainThread(); try { testRunner.prepareSource(); final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSource(createFakeMediaSource(), new Handler(), timelineGrabber)); Timeline timeline = timelineGrabber.assertTimelineChangeBlocking(); assertThat(timeline.getWindowCount()).isEqualTo(1); } finally { dummyMainThread.release(); } }
@Test public void testCustomCallbackAfterPreparationAddSingleWithIndex() throws Exception { DummyMainThread dummyMainThread = new DummyMainThread(); try { testRunner.prepareSource(); final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSource( 0, createFakeMediaSource(), new Handler(), timelineGrabber)); Timeline timeline = timelineGrabber.assertTimelineChangeBlocking(); assertThat(timeline.getWindowCount()).isEqualTo(1); } finally { dummyMainThread.release(); } }
@Test public void testPeriodCreationWithAds() throws IOException, InterruptedException { Timeline timelineContentOnly = new FakeTimeline( new TimelineWindowDefinition(2, 111, true, false, 10 * C.MICROS_PER_SECOND)); Timeline timelineWithAds = new FakeTimeline( new TimelineWindowDefinition( 2, 222, true, false, 10 * C.MICROS_PER_SECOND, FakeTimeline.createAdPlaybackState( 1, 0))); FakeMediaSource mediaSourceContentOnly = new FakeMediaSource(timelineContentOnly); FakeMediaSource mediaSourceWithAds = new FakeMediaSource(timelineWithAds); mediaSource.addMediaSource(mediaSourceContentOnly); mediaSource.addMediaSource(mediaSourceWithAds); Timeline timeline = testRunner.prepareSource(); TimelineAsserts.assertAdGroupCounts(timeline, 0, 0, 1, 1); testRunner.assertPrepareAndReleaseAllPeriods(); Object timelineContentOnlyPeriodUid0 = timelineContentOnly.getUidOfPeriod( 0); Object timelineContentOnlyPeriodUid1 = timelineContentOnly.getUidOfPeriod( 1); Object timelineWithAdsPeriodUid0 = timelineWithAds.getUidOfPeriod( 0); Object timelineWithAdsPeriodUid1 = timelineWithAds.getUidOfPeriod( 1); mediaSourceContentOnly.assertMediaPeriodCreated( new MediaPeriodId(timelineContentOnlyPeriodUid0, 0)); mediaSourceContentOnly.assertMediaPeriodCreated( new MediaPeriodId(timelineContentOnlyPeriodUid1, 0)); mediaSourceWithAds.assertMediaPeriodCreated( new MediaPeriodId(timelineWithAdsPeriodUid0, 1)); mediaSourceWithAds.assertMediaPeriodCreated( new MediaPeriodId(timelineWithAdsPeriodUid1, 1)); mediaSourceWithAds.assertMediaPeriodCreated( new MediaPeriodId( timelineWithAdsPeriodUid0, 0, 0, 1)); mediaSourceWithAds.assertMediaPeriodCreated( new MediaPeriodId( timelineWithAdsPeriodUid1, 0, 0, 1)); testRunner.assertCompletedManifestLoads(0, 1); assertCompletedAllMediaPeriodLoads(timeline); }
@Test public void testNestedTimeline() throws IOException { ConcatenatingMediaSource nestedSource1 = new ConcatenatingMediaSource( false, new FakeShuffleOrder(0)); ConcatenatingMediaSource nestedSource2 = new ConcatenatingMediaSource( true, new FakeShuffleOrder(0)); mediaSource.addMediaSource(nestedSource1); mediaSource.addMediaSource(nestedSource2); testRunner.prepareSource(); FakeMediaSource[] childSources = createMediaSources(4); nestedSource1.addMediaSource(childSources[0]); testRunner.assertTimelineChangeBlocking(); nestedSource1.addMediaSource(childSources[1]); testRunner.assertTimelineChangeBlocking(); nestedSource2.addMediaSource(childSources[2]); testRunner.assertTimelineChangeBlocking(); nestedSource2.addMediaSource(childSources[3]); Timeline timeline = testRunner.assertTimelineChangeBlocking(); TimelineAsserts.assertWindowTags(timeline, 111, 222, 333, 444); TimelineAsserts.assertPeriodCounts(timeline, 1, 2, 3, 4); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1, 2); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 3, 2); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ALL, false, 3, 0, 1, 2); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_OFF, false, 1, 2, 3, C.INDEX_UNSET); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ONE, false, 0, 1, 3, 2); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 3, 0); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_OFF, true, 1, 3, C.INDEX_UNSET, 2); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 3, 2); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ALL, true, 1, 3, 0, 2); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 3, 1); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ONE, true, 0, 1, 3, 2); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 3, 1); }