use of androidx.media3.exoplayer.source.MediaPeriod 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.MediaPeriod 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.MediaPeriod in project media by androidx.
the class ServerSideAdInsertionMediaSource method setAdPlaybackStates.
/**
* Sets the map of {@link AdPlaybackState ad playback states} published by this source. The key is
* the period UID of a period in the {@link
* AdPlaybackStateUpdater#onAdPlaybackStateUpdateRequested(Timeline)} content timeline}.
*
* <p>Each period has an {@link AdPlaybackState} that tells where in the period the ad groups
* start and end. Must only contain server-side inserted ad groups. The number of ad groups and
* the number of ads within an ad group may only increase. The durations of ads may change and the
* positions of future ad groups may change. Post-roll ad groups with {@link C#TIME_END_OF_SOURCE}
* must be empty and can be used as a placeholder for a future ad group.
*
* <p>May be called from any thread.
*
* @param adPlaybackStates The map of {@link AdPlaybackState} keyed by their period UID.
*/
public void setAdPlaybackStates(ImmutableMap<Object, AdPlaybackState> adPlaybackStates) {
checkArgument(!adPlaybackStates.isEmpty());
Object adsId = checkNotNull(adPlaybackStates.values().asList().get(0).adsId);
for (Map.Entry<Object, AdPlaybackState> entry : adPlaybackStates.entrySet()) {
Object periodUid = entry.getKey();
AdPlaybackState adPlaybackState = entry.getValue();
checkArgument(Util.areEqual(adsId, adPlaybackState.adsId));
@Nullable AdPlaybackState oldAdPlaybackState = this.adPlaybackStates.get(periodUid);
if (oldAdPlaybackState != null) {
for (int i = adPlaybackState.removedAdGroupCount; i < adPlaybackState.adGroupCount; i++) {
AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(i);
checkArgument(adGroup.isServerSideInserted);
if (i < oldAdPlaybackState.adGroupCount) {
checkArgument(getAdCountInGroup(adPlaybackState, /* adGroupIndex= */
i) >= getAdCountInGroup(oldAdPlaybackState, /* adGroupIndex= */
i));
}
if (adGroup.timeUs == C.TIME_END_OF_SOURCE) {
checkArgument(getAdCountInGroup(adPlaybackState, /* adGroupIndex= */
i) == 0);
}
}
}
}
synchronized (this) {
if (playbackHandler == null) {
this.adPlaybackStates = adPlaybackStates;
} else {
playbackHandler.post(() -> {
for (SharedMediaPeriod mediaPeriod : mediaPeriods.values()) {
@Nullable AdPlaybackState adPlaybackState = adPlaybackStates.get(mediaPeriod.periodUid);
if (adPlaybackState != null) {
mediaPeriod.updateAdPlaybackState(adPlaybackState);
}
}
if (lastUsedMediaPeriod != null) {
@Nullable AdPlaybackState adPlaybackState = adPlaybackStates.get(lastUsedMediaPeriod.periodUid);
if (adPlaybackState != null) {
lastUsedMediaPeriod.updateAdPlaybackState(adPlaybackState);
}
}
this.adPlaybackStates = adPlaybackStates;
if (contentTimeline != null) {
refreshSourceInfo(new ServerSideAdInsertionTimeline(contentTimeline, adPlaybackStates));
}
});
}
}
}
use of androidx.media3.exoplayer.source.MediaPeriod 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);
}
use of androidx.media3.exoplayer.source.MediaPeriod in project media by androidx.
the class ExoPlayerTest method mediaPeriodMaybeThrowPrepareError_isNotThrownUntilPlaybackReachedFailingItem.
@Test
public void mediaPeriodMaybeThrowPrepareError_isNotThrownUntilPlaybackReachedFailingItem() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Timeline timeline = new FakeTimeline();
player.addMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT));
player.addMediaSource(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, /* singleSampleTimeUs= */
0, mediaSourceEventDispatcher, DrmSessionManager.DRM_UNSUPPORTED, drmEventDispatcher, /* deferOnPrepared= */
true) {
@Override
public void maybeThrowPrepareError() throws IOException {
throw new IOException();
}
};
}
});
player.prepare();
player.play();
ExoPlaybackException error = TestPlayerRunHelper.runUntilError(player);
Object period1Uid = player.getCurrentTimeline().getPeriod(/* periodIndex= */
1, new Timeline.Period(), /* setIds= */
true).uid;
assertThat(error.mediaPeriodId.periodUid).isEqualTo(period1Uid);
assertThat(player.getCurrentMediaItemIndex()).isEqualTo(1);
}
Aggregations