ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHolder> { public synchronized void addMediaSources(Collection<MediaSource> mediaSources) { addPublicMediaSources( mediaSourcesPublic.size(), mediaSources, null, null); } 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 testDynamicChangeOfEmptyTimelines() throws IOException { FakeMediaSource[] childSources = new FakeMediaSource[] { new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY), new FakeMediaSource(Timeline.EMPTY), }; Timeline nonEmptyTimeline = new FakeTimeline( 1); mediaSource.addMediaSources(Arrays.asList(childSources)); Timeline timeline = testRunner.prepareSource(); TimelineAsserts.assertEmpty(timeline); childSources[0].setNewSourceInfo(nonEmptyTimeline, null); timeline = testRunner.assertTimelineChangeBlocking(); TimelineAsserts.assertPeriodCounts(timeline, 1); childSources[2].setNewSourceInfo(nonEmptyTimeline, null); timeline = testRunner.assertTimelineChangeBlocking(); TimelineAsserts.assertPeriodCounts(timeline, 1, 1); childSources[1].setNewSourceInfo(nonEmptyTimeline, null); timeline = testRunner.assertTimelineChangeBlocking(); TimelineAsserts.assertPeriodCounts(timeline, 1, 1, 1); }
@Test public void testCustomCallbackBeforePreparationAddMultiple() throws Exception { CountDownLatch runnableInvoked = new CountDownLatch(1); DummyMainThread dummyMainThread = new DummyMainThread(); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSources( Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), new Handler(), runnableInvoked::countDown)); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS); dummyMainThread.release(); assertThat(runnableInvoked.getCount()).isEqualTo(0); }
@Test public void testCustomCallbackBeforePreparationAddMultipleWithIndex() throws Exception { CountDownLatch runnableInvoked = new CountDownLatch(1); DummyMainThread dummyMainThread = new DummyMainThread(); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSources( 0, Arrays.asList(new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), new Handler(), runnableInvoked::countDown)); runnableInvoked.await(MediaSourceTestRunner.TIMEOUT_MS, TimeUnit.MILLISECONDS); dummyMainThread.release(); assertThat(runnableInvoked.getCount()).isEqualTo(0); }
@Test public void testCustomCallbackAfterPreparationAddMultiple() throws Exception { DummyMainThread dummyMainThread = new DummyMainThread(); try { testRunner.prepareSource(); final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSources( Arrays.asList( new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), new Handler(), timelineGrabber)); Timeline timeline = timelineGrabber.assertTimelineChangeBlocking(); assertThat(timeline.getWindowCount()).isEqualTo(2); } finally { dummyMainThread.release(); } }
@Test public void testCustomCallbackAfterPreparationAddMultipleWithIndex() throws Exception { DummyMainThread dummyMainThread = new DummyMainThread(); try { testRunner.prepareSource(); final TimelineGrabber timelineGrabber = new TimelineGrabber(testRunner); dummyMainThread.runOnMainThread( () -> mediaSource.addMediaSources( 0, Arrays.asList( new MediaSource[] {createFakeMediaSource(), createFakeMediaSource()}), new Handler(), timelineGrabber)); Timeline timeline = timelineGrabber.assertTimelineChangeBlocking(); assertThat(timeline.getWindowCount()).isEqualTo(2); } finally { dummyMainThread.release(); } }
@Test public void testAtomicTimelineWindowOrder() throws IOException { testRunner.release(); ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource( true, new FakeShuffleOrder(0)); testRunner = new MediaSourceTestRunner(mediaSource, null); mediaSource.addMediaSources(Arrays.asList(createMediaSources(3))); Timeline timeline = testRunner.prepareSource(); TimelineAsserts.assertWindowTags(timeline, 111, 222, 333); TimelineAsserts.assertPeriodCounts(timeline, 1, 2, 3); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_OFF, false, C.INDEX_UNSET, 0, 1); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_OFF, true, C.INDEX_UNSET, 0, 1); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ONE, false, 2, 0, 1); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ONE, true, 2, 0, 1); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ALL, false, 2, 0, 1); TimelineAsserts.assertPreviousWindowIndices( timeline, Player.REPEAT_MODE_ALL, true, 2, 0, 1); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_OFF, false, 1, 2, C.INDEX_UNSET); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_OFF, true, 1, 2, C.INDEX_UNSET); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ONE, false, 1, 2, 0); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ONE, true, 1, 2, 0); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ALL, false, 1, 2, 0); TimelineAsserts.assertNextWindowIndices( timeline, Player.REPEAT_MODE_ALL, true, 1, 2, 0); assertThat(timeline.getFirstWindowIndex( false)).isEqualTo(0); assertThat(timeline.getFirstWindowIndex( true)).isEqualTo(0); assertThat(timeline.getLastWindowIndex( false)).isEqualTo(2); assertThat(timeline.getLastWindowIndex( true)).isEqualTo(2); }