use of androidx.media3.common.Player.Events in project media by androidx.
the class DashManifestParser method parseEventStream.
/**
* Parses a single EventStream node in the manifest.
*
* @param xpp The current xml parser.
* @return The {@link EventStream} parsed from this EventStream node.
* @throws XmlPullParserException If there is any error parsing this node.
* @throws IOException If there is any error reading from the underlying input stream.
*/
protected EventStream parseEventStream(XmlPullParser xpp) throws XmlPullParserException, IOException {
String schemeIdUri = parseString(xpp, "schemeIdUri", "");
String value = parseString(xpp, "value", "");
long timescale = parseLong(xpp, "timescale", 1);
List<Pair<Long, EventMessage>> eventMessages = new ArrayList<>();
ByteArrayOutputStream scratchOutputStream = new ByteArrayOutputStream(512);
do {
xpp.next();
if (XmlPullParserUtil.isStartTag(xpp, "Event")) {
Pair<Long, EventMessage> event = parseEvent(xpp, schemeIdUri, value, timescale, scratchOutputStream);
eventMessages.add(event);
} else {
maybeSkipTag(xpp);
}
} while (!XmlPullParserUtil.isEndTag(xpp, "EventStream"));
long[] presentationTimesUs = new long[eventMessages.size()];
EventMessage[] events = new EventMessage[eventMessages.size()];
for (int i = 0; i < eventMessages.size(); i++) {
Pair<Long, EventMessage> event = eventMessages.get(i);
presentationTimesUs[i] = event.first;
events[i] = event.second;
}
return buildEventStream(schemeIdUri, value, timescale, presentationTimesUs, events);
}
use of androidx.media3.common.Player.Events in project media by androidx.
the class AdTagLoader method loadAdInternal.
private void loadAdInternal(AdMediaInfo adMediaInfo, AdPodInfo adPodInfo) {
if (adsManager == null) {
// Drop events after release.
if (configuration.debugModeEnabled) {
Log.d(TAG, "loadAd after release " + getAdMediaInfoString(adMediaInfo) + ", ad pod " + adPodInfo);
}
return;
}
int adGroupIndex = getAdGroupIndexForAdPod(adPodInfo);
int adIndexInAdGroup = adPodInfo.getAdPosition() - 1;
AdInfo adInfo = new AdInfo(adGroupIndex, adIndexInAdGroup);
// The ad URI may already be known, so force put to update it if needed.
adInfoByAdMediaInfo.forcePut(adMediaInfo, adInfo);
if (configuration.debugModeEnabled) {
Log.d(TAG, "loadAd " + getAdMediaInfoString(adMediaInfo));
}
if (adPlaybackState.isAdInErrorState(adGroupIndex, adIndexInAdGroup)) {
// timeout after its media load timeout.
return;
}
// The ad count may increase on successive loads of ads in the same ad pod, for example, due to
// separate requests for ad tags with multiple ads within the ad pod completing after an earlier
// ad has loaded. See also https://github.com/google/ExoPlayer/issues/7477.
AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adInfo.adGroupIndex);
adPlaybackState = adPlaybackState.withAdCount(adInfo.adGroupIndex, max(adPodInfo.getTotalAds(), adGroup.states.length));
adGroup = adPlaybackState.getAdGroup(adInfo.adGroupIndex);
for (int i = 0; i < adIndexInAdGroup; i++) {
// Any preceding ads that haven't loaded are not going to load.
if (adGroup.states[i] == AdPlaybackState.AD_STATE_UNAVAILABLE) {
adPlaybackState = adPlaybackState.withAdLoadError(adGroupIndex, /* adIndexInAdGroup= */
i);
}
}
Uri adUri = Uri.parse(adMediaInfo.getUrl());
adPlaybackState = adPlaybackState.withAdUri(adInfo.adGroupIndex, adInfo.adIndexInAdGroup, adUri);
updateAdPlaybackState();
}
use of androidx.media3.common.Player.Events in project media by androidx.
the class AdTagLoader method addListenerWithAdView.
/**
* Starts passing events from this instance (including any pending ad playback state) and
* registers obstructions.
*/
public void addListenerWithAdView(EventListener eventListener, AdViewProvider adViewProvider) {
boolean isStarted = !eventListeners.isEmpty();
eventListeners.add(eventListener);
if (isStarted) {
if (!AdPlaybackState.NONE.equals(adPlaybackState)) {
// Pass the existing ad playback state to the new listener.
eventListener.onAdPlaybackState(adPlaybackState);
}
return;
}
lastVolumePercent = 0;
lastAdProgress = VideoProgressUpdate.VIDEO_TIME_NOT_READY;
lastContentProgress = VideoProgressUpdate.VIDEO_TIME_NOT_READY;
maybeNotifyPendingAdLoadError();
if (!AdPlaybackState.NONE.equals(adPlaybackState)) {
// Pass the ad playback state to the player, and resume ads if necessary.
eventListener.onAdPlaybackState(adPlaybackState);
} else if (adsManager != null) {
adPlaybackState = new AdPlaybackState(adsId, getAdGroupTimesUsForCuePoints(adsManager.getAdCuePoints()));
updateAdPlaybackState();
}
for (AdOverlayInfo overlayInfo : adViewProvider.getAdOverlayInfos()) {
adDisplayContainer.registerFriendlyObstruction(imaFactory.createFriendlyObstruction(overlayInfo.view, ImaUtil.getFriendlyObstructionPurpose(overlayInfo.purpose), overlayInfo.reasonDetail));
}
}
use of androidx.media3.common.Player.Events in project media by androidx.
the class MediaSessionService method onStartCommand.
/**
* Called when a component calls {@link android.content.Context#startService(Intent)}.
*
* <p>The default implementation handles the incoming media button events. In this case, the
* intent will have the action {@link Intent#ACTION_MEDIA_BUTTON}. Override this method if this
* service also needs to handle actions other than {@link Intent#ACTION_MEDIA_BUTTON}.
*/
@CallSuper
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
if (intent == null) {
return START_STICKY;
}
DefaultActionFactory actionFactory;
synchronized (lock) {
actionFactory = checkStateNotNull(this.actionFactory);
}
@Nullable Uri uri = intent.getData();
@Nullable MediaSession session = uri != null ? MediaSession.getSession(uri) : null;
if (actionFactory.isMediaAction(intent)) {
if (session == null) {
ControllerInfo controllerInfo = ControllerInfo.createLegacyControllerInfo();
session = onGetSession(controllerInfo);
if (session == null) {
return START_STICKY;
}
addSession(session);
}
@Nullable KeyEvent keyEvent = actionFactory.getKeyEvent(intent);
if (keyEvent != null) {
session.getSessionCompat().getController().dispatchMediaButtonEvent(keyEvent);
}
} else if (actionFactory.isCustomAction(intent)) {
@Nullable String customAction = actionFactory.getCustomAction(intent);
if (session != null && customAction != null) {
Bundle customExtras = actionFactory.getCustomActionExtras(intent);
getMediaNotificationManager().onCustomAction(session, customAction, customExtras);
}
}
return START_STICKY;
}
use of androidx.media3.common.Player.Events in project media by androidx.
the class MediaControllerListenerTest method onEvents_whenNewCommandIsCalledInsideOnEvents_isCalledFromNewLooperIterationSet.
@Test
public void onEvents_whenNewCommandIsCalledInsideOnEvents_isCalledFromNewLooperIterationSet() throws Exception {
Player.Events firstLooperIterationSetTestEvents = new Player.Events(new FlagSet.Builder().add(EVENT_REPEAT_MODE_CHANGED).build());
Player.Events secondLooperIterationSetTestEvents = new Player.Events(new FlagSet.Builder().add(EVENT_SHUFFLE_MODE_ENABLED_CHANGED).build());
List<Integer> listenerEventCodes = new ArrayList<>();
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
CountDownLatch latch = new CountDownLatch(4);
AtomicReference<Player.Events> firstLooperIterationSetEventsRef = new AtomicReference<>();
AtomicReference<Player.Events> secondLooperIterationSetEventsRef = new AtomicReference<>();
Player.Listener listener = new Player.Listener() {
@Override
public void onRepeatModeChanged(@Player.RepeatMode int repeatMode) {
listenerEventCodes.add(EVENT_REPEAT_MODE_CHANGED);
latch.countDown();
}
@Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
listenerEventCodes.add(EVENT_SHUFFLE_MODE_ENABLED_CHANGED);
latch.countDown();
}
@Override
public void onEvents(Player player, Player.Events events) {
listenerEventCodes.add(EVENT_ON_EVENTS);
if (!controller.getShuffleModeEnabled()) {
controller.setShuffleModeEnabled(true);
firstLooperIterationSetEventsRef.set(events);
} else {
secondLooperIterationSetEventsRef.set(events);
}
latch.countDown();
}
};
controller.addListener(listener);
remoteSession.getMockPlayer().setRepeatMode(REPEAT_MODE_ONE);
remoteSession.getMockPlayer().notifyRepeatModeChanged();
assertThat(latch.await(TIMEOUT_MS, MILLISECONDS)).isTrue();
assertThat(listenerEventCodes).containsExactly(EVENT_REPEAT_MODE_CHANGED, EVENT_ON_EVENTS, EVENT_SHUFFLE_MODE_ENABLED_CHANGED, EVENT_ON_EVENTS);
assertThat(firstLooperIterationSetEventsRef.get()).isEqualTo(firstLooperIterationSetTestEvents);
assertThat(secondLooperIterationSetEventsRef.get()).isEqualTo(secondLooperIterationSetTestEvents);
}
Aggregations