use of androidx.media3.exoplayer.source.MediaSource.MediaPeriodId in project media by androidx.
the class ExoPlaybackException method toBundle.
/**
* {@inheritDoc}
*
* <p>It omits the {@link #mediaPeriodId} field. The {@link #mediaPeriodId} of an instance
* restored by {@link #CREATOR} will always be {@code null}.
*/
@UnstableApi
@Override
public Bundle toBundle() {
Bundle bundle = super.toBundle();
bundle.putInt(keyForField(FIELD_TYPE), type);
bundle.putString(keyForField(FIELD_RENDERER_NAME), rendererName);
bundle.putInt(keyForField(FIELD_RENDERER_INDEX), rendererIndex);
bundle.putBundle(keyForField(FIELD_RENDERER_FORMAT), BundleableUtil.toNullableBundle(rendererFormat));
bundle.putInt(keyForField(FIELD_RENDERER_FORMAT_SUPPORT), rendererFormatSupport);
bundle.putBoolean(keyForField(FIELD_IS_RECOVERABLE), isRecoverable);
return bundle;
}
use of androidx.media3.exoplayer.source.MediaSource.MediaPeriodId in project media by androidx.
the class AdsMediaSource method releasePeriod.
@Override
public void releasePeriod(MediaPeriod mediaPeriod) {
MaskingMediaPeriod maskingMediaPeriod = (MaskingMediaPeriod) mediaPeriod;
MediaPeriodId id = maskingMediaPeriod.id;
if (id.isAd()) {
AdMediaSourceHolder adMediaSourceHolder = checkNotNull(adMediaSourceHolders[id.adGroupIndex][id.adIndexInAdGroup]);
adMediaSourceHolder.releaseMediaPeriod(maskingMediaPeriod);
if (adMediaSourceHolder.isInactive()) {
adMediaSourceHolder.release();
adMediaSourceHolders[id.adGroupIndex][id.adIndexInAdGroup] = null;
}
} else {
maskingMediaPeriod.releasePeriod();
}
}
use of androidx.media3.exoplayer.source.MediaSource.MediaPeriodId in project media by androidx.
the class AdsMediaSource method createPeriod.
@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
AdPlaybackState adPlaybackState = checkNotNull(this.adPlaybackState);
if (adPlaybackState.adGroupCount > 0 && id.isAd()) {
int adGroupIndex = id.adGroupIndex;
int adIndexInAdGroup = id.adIndexInAdGroup;
if (adMediaSourceHolders[adGroupIndex].length <= adIndexInAdGroup) {
int adCount = adIndexInAdGroup + 1;
adMediaSourceHolders[adGroupIndex] = Arrays.copyOf(adMediaSourceHolders[adGroupIndex], adCount);
}
@Nullable AdMediaSourceHolder adMediaSourceHolder = adMediaSourceHolders[adGroupIndex][adIndexInAdGroup];
if (adMediaSourceHolder == null) {
adMediaSourceHolder = new AdMediaSourceHolder(id);
adMediaSourceHolders[adGroupIndex][adIndexInAdGroup] = adMediaSourceHolder;
maybeUpdateAdMediaSources();
}
return adMediaSourceHolder.createMediaPeriod(id, allocator, startPositionUs);
} else {
MaskingMediaPeriod mediaPeriod = new MaskingMediaPeriod(id, allocator, startPositionUs);
mediaPeriod.setMediaSource(contentMediaSource);
mediaPeriod.createPeriod(id);
return mediaPeriod;
}
}
use of androidx.media3.exoplayer.source.MediaSource.MediaPeriodId in project media by androidx.
the class ExoPlayerTest method newServerSideInsertedAdAtPlaybackPosition_keepsRenderersEnabled.
@Test
public void newServerSideInsertedAdAtPlaybackPosition_keepsRenderersEnabled() throws Exception {
// Injecting renderer to count number of renderer resets.
AtomicReference<FakeVideoRenderer> videoRenderer = new AtomicReference<>();
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderersFactory((handler, videoListener, audioListener, textOutput, metadataOutput) -> {
videoRenderer.set(new FakeVideoRenderer(handler, videoListener));
return new Renderer[] { videoRenderer.get() };
}).build();
// Live stream timeline with unassigned next ad group.
AdPlaybackState initialAdPlaybackState = new AdPlaybackState(/* adsId= */
new Object(), /* adGroupTimesUs...= */
C.TIME_END_OF_SOURCE).withIsServerSideInserted(/* adGroupIndex= */
0, /* isServerSideInserted= */
true).withAdCount(/* adGroupIndex= */
0, /* adCount= */
1).withAdDurationsUs(new long[][] { new long[] { 10 * C.MICROS_PER_SECOND } });
// Updated timeline with ad group at 18 seconds.
long firstSampleTimeUs = TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US;
Timeline initialTimeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
true, /* durationUs= */
C.TIME_UNSET, initialAdPlaybackState));
AdPlaybackState updatedAdPlaybackState = initialAdPlaybackState.withAdGroupTimeUs(/* adGroupIndex= */
0, /* adGroupTimeUs= */
firstSampleTimeUs + 18 * C.MICROS_PER_SECOND);
Timeline updatedTimeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
true, /* durationUs= */
C.TIME_UNSET, updatedAdPlaybackState));
// Add samples to allow player to load and start playing (but no EOS as this is a live stream).
FakeMediaSource mediaSource = new FakeMediaSource(initialTimeline, DrmSessionManager.DRM_UNSUPPORTED, (format, mediaPeriodId) -> ImmutableList.of(oneByteSample(firstSampleTimeUs, C.BUFFER_FLAG_KEY_FRAME), oneByteSample(firstSampleTimeUs + 40 * C.MICROS_PER_SECOND)), ExoPlayerTestRunner.VIDEO_FORMAT);
// Set updated ad group once we reach 20 seconds, and then continue playing until 40 seconds.
player.createMessage((message, payload) -> mediaSource.setNewSourceInfo(updatedTimeline)).setPosition(20_000).send();
player.setMediaSource(mediaSource);
player.prepare();
playUntilPosition(player, /* mediaItemIndex= */
0, /* positionMs= */
40_000);
player.release();
// Assert that the renderer hasn't been reset despite the inserted ad group.
assertThat(videoRenderer.get().positionResetCount).isEqualTo(1);
}
use of androidx.media3.exoplayer.source.MediaSource.MediaPeriodId in project media by androidx.
the class ExoPlayerTest method setPlaybackSpeedBeforePreparationCompletesSucceeds.
@Test
public void setPlaybackSpeedBeforePreparationCompletesSucceeds() throws Exception {
// Test that no exception is thrown when playback parameters are updated between creating a
// period and preparation of the period completing.
final CountDownLatch createPeriodCalledCountDownLatch = new CountDownLatch(1);
final FakeMediaPeriod[] fakeMediaPeriodHolder = new FakeMediaPeriod[1];
MediaSource mediaSource = new FakeMediaSource(new FakeTimeline(), 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 playback parameters have been set.
fakeMediaPeriodHolder[0] = new FakeMediaPeriod(trackGroupArray, allocator, TimelineWindowDefinition.DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
true);
createPeriodCalledCountDownLatch.countDown();
return fakeMediaPeriodHolder[0];
}
};
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_BUFFERING).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
try {
player.getClock().onThreadBlocked();
createPeriodCalledCountDownLatch.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}).setPlaybackParameters(new PlaybackParameters(/* speed= */
2f)).executeRunnable(() -> fakeMediaPeriodHolder[0].setPreparationComplete()).build();
new ExoPlayerTestRunner.Builder(context).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
}
Aggregations