use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.
the class ExoPlayerTest method delegatingMediaSourceApproach.
@Test
public void delegatingMediaSourceApproach() throws Exception {
Timeline fakeTimeline = new FakeTimeline(new TimelineWindowDefinition(/* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10_000_000));
final ConcatenatingMediaSource underlyingSource = new ConcatenatingMediaSource();
CompositeMediaSource<Void> delegatingMediaSource = new CompositeMediaSource<Void>() {
@Override
public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);
underlyingSource.addMediaSource(new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT));
underlyingSource.addMediaSource(new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT));
prepareChildSource(null, underlyingSource);
}
@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
return underlyingSource.createPeriod(id, allocator, startPositionUs);
}
@Override
public void releasePeriod(MediaPeriod mediaPeriod) {
underlyingSource.releasePeriod(mediaPeriod);
}
@Override
protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) {
refreshSourceInfo(timeline);
}
@Override
public boolean isSingleWindow() {
return false;
}
@Override
public MediaItem getMediaItem() {
return underlyingSource.getMediaItem();
}
@Override
@Nullable
public Timeline getInitialTimeline() {
return Timeline.EMPTY;
}
};
int[] currentMediaItemIndices = new int[1];
long[] currentPlaybackPositions = new long[1];
long[] windowCounts = new long[1];
int seekToMediaItemIndex = 1;
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).seek(/* mediaItemIndex= */
1, /* positionMs= */
5000).waitForTimelineChanged(/* expectedTimeline= */
null, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
currentMediaItemIndices[0] = player.getCurrentMediaItemIndex();
currentPlaybackPositions[0] = player.getCurrentPosition();
windowCounts[0] = player.getCurrentTimeline().getWindowCount();
}
}).build();
ExoPlayerTestRunner exoPlayerTestRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(delegatingMediaSource).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
assertArrayEquals(new long[] { 2 }, windowCounts);
assertArrayEquals(new int[] { seekToMediaItemIndex }, currentMediaItemIndices);
assertArrayEquals(new long[] { 5_000 }, currentPlaybackPositions);
}
use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.
the class ExoPlayerTest method shortAdFollowedByUnpreparedAd_playbackDoesNotGetStuck.
@Test
public void shortAdFollowedByUnpreparedAd_playbackDoesNotGetStuck() throws Exception {
AdPlaybackState adPlaybackState = FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */
2, /* adGroupTimesUs...= */
0);
long shortAdDurationMs = 1_000;
adPlaybackState = adPlaybackState.withAdDurationsUs(new long[][] { { shortAdDurationMs, shortAdDurationMs } });
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
Util.msToUs(10000), adPlaybackState));
// Simulate the second ad not being prepared.
FakeMediaSource mediaSource = new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT) {
@Override
protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
return new FakeMediaPeriod(trackGroupArray, allocator, FakeMediaPeriod.TrackDataFactory.singleSampleWithTimeUs(0), mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
id.adIndexInAdGroup == 1);
}
};
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.setMediaSource(mediaSource);
player.prepare();
player.play();
// The player is not stuck in the buffering state.
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY);
}
use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.
the class DefaultAnalyticsCollectorTest method prepareNewSource.
@Test
public void prepareNewSource() throws Exception {
MediaSource mediaSource1 = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT);
MediaSource mediaSource2 = new FakeMediaSource(SINGLE_PERIOD_TIMELINE, ExoPlayerTestRunner.VIDEO_FORMAT);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).pause().waitForPlaybackState(Player.STATE_READY).setMediaSources(/* resetPosition= */
false, mediaSource2).waitForTimelineChanged().waitForIsLoading(true).play().build();
TestAnalyticsListener listener = runAnalyticsTest(mediaSource1, actionSchedule);
// Populate all event ids with last timeline (after second prepare).
populateEventIds(listener.lastReportedTimeline);
// Populate event id of period 0, sequence 0 with timeline of initial preparation.
period0Seq0 = new EventWindowAndPeriodId(/* windowIndex= */
0, new MediaPeriodId(listener.reportedTimelines.get(1).getUidOfPeriod(/* periodIndex= */
0), /* windowSequenceNumber= */
0));
assertThat(listener.getEvents(EVENT_PLAYER_STATE_CHANGED)).containsExactly(WINDOW_0, /* setPlayWhenReady=true */
WINDOW_0, /* BUFFERING */
WINDOW_0, /* setPlayWhenReady=false */
period0Seq0, /* READY */
WINDOW_0, /* BUFFERING */
period0Seq1, /* setPlayWhenReady=true */
period0Seq1, /* READY */
period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_TIMELINE_CHANGED)).containsExactly(WINDOW_0, /* PLAYLIST_CHANGE */
period0Seq0, /* SOURCE_UPDATE */
WINDOW_0, /* PLAYLIST_CHANGE */
period0Seq1);
assertThat(listener.getEvents(EVENT_POSITION_DISCONTINUITY)).containsExactly(WINDOW_0);
assertThat(listener.getEvents(EVENT_IS_LOADING_CHANGED)).containsExactly(period0Seq0, period0Seq0, period0Seq1, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_TRACKS_CHANGED)).containsExactly(period0Seq0, /* prepared */
WINDOW_0, /* setMediaSources */
period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_LOAD_STARTED)).containsExactly(WINDOW_0, /* manifest */
period0Seq0, /* media */
WINDOW_0, /* manifest */
period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_LOAD_COMPLETED)).containsExactly(WINDOW_0, /* manifest */
period0Seq0, /* media */
WINDOW_0, /* manifest */
period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_DOWNSTREAM_FORMAT_CHANGED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_DECODER_ENABLED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_DECODER_INIT)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_DECODER_FORMAT_CHANGED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_DECODER_DISABLED)).containsExactly(period0Seq0);
assertThat(listener.getEvents(EVENT_VIDEO_ENABLED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_DECODER_INITIALIZED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_INPUT_FORMAT_CHANGED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_DISABLED)).containsExactly(period0Seq0);
assertThat(listener.getEvents(EVENT_DROPPED_VIDEO_FRAMES)).containsExactly(period0Seq1);
assertThat(listener.getEvents(EVENT_VIDEO_SIZE_CHANGED)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_RENDERED_FIRST_FRAME)).containsExactly(period0Seq0, period0Seq1).inOrder();
assertThat(listener.getEvents(EVENT_VIDEO_FRAME_PROCESSING_OFFSET)).containsExactly(period0Seq1);
listener.assertNoMoreEvents();
}
use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.
the class MediaSourceTestRunner method assertPrepareAndReleaseAllPeriods.
/**
* Creates and releases all periods (including ad periods) defined in the last timeline to be
* returned from {@link #prepareSource()}, {@link #assertTimelineChange()} or {@link
* #assertTimelineChangeBlocking()}. The {@link MediaPeriodId#windowSequenceNumber} is set to the
* index of the window.
*/
public void assertPrepareAndReleaseAllPeriods() throws InterruptedException {
Timeline.Period period = new Timeline.Period();
for (int i = 0; i < timeline.getPeriodCount(); i++) {
timeline.getPeriod(i, period, /* setIds= */
true);
assertPrepareAndReleasePeriod(new MediaPeriodId(period.uid, period.windowIndex));
for (int adGroupIndex = 0; adGroupIndex < period.getAdGroupCount(); adGroupIndex++) {
for (int adIndex = 0; adIndex < period.getAdCountInAdGroup(adGroupIndex); adIndex++) {
assertPrepareAndReleasePeriod(new MediaPeriodId(period.uid, adGroupIndex, adIndex, period.windowIndex));
}
}
}
}
use of com.google.android.exoplayer2.source.MediaSource.MediaPeriodId in project ExoPlayer by google.
the class MediaSourceTestRunner method assertCompletedMediaPeriodLoads.
/**
* Asserts that the media source reported completed loads via {@link
* MediaSourceEventListener#onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)} for
* each specified media period id, and asserts that the associated window index matches the one in
* the last known timeline returned from {@link #prepareSource()}, {@link #assertTimelineChange()}
* or {@link #assertTimelineChangeBlocking()}.
*/
public void assertCompletedMediaPeriodLoads(MediaPeriodId... mediaPeriodIds) {
Timeline.Period period = new Timeline.Period();
HashSet<MediaPeriodId> expectedLoads = new HashSet<>(Arrays.asList(mediaPeriodIds));
for (Pair<Integer, MediaPeriodId> windowIndexAndMediaPeriodId : completedLoads) {
int windowIndex = windowIndexAndMediaPeriodId.first;
MediaPeriodId mediaPeriodId = windowIndexAndMediaPeriodId.second;
if (expectedLoads.remove(mediaPeriodId)) {
int periodIndex = timeline.getIndexOfPeriod(mediaPeriodId.periodUid);
assertThat(windowIndex).isEqualTo(timeline.getPeriod(periodIndex, period).windowIndex);
}
}
assertWithMessage("Not all expected media source loads have been completed.").that(expectedLoads).isEmpty();
}
Aggregations