Create an AdEventListener for each supported stream type
This is a refactoring to separate and simplify the logic of VOD and live streams when handling IMA ad events. An additional listener will be required for DASH live stream in a follow-up CL. PiperOrigin-RevId: 507435741
This commit is contained in:
parent
0eb11e269c
commit
afa3c628c1
@ -528,7 +528,6 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
this.contentMediaSourceFactory = contentMediaSourceFactory;
|
||||
this.applicationAdEventListener = applicationAdEventListener;
|
||||
this.applicationAdErrorListener = applicationAdErrorListener;
|
||||
componentListener = new ComponentListener();
|
||||
Assertions.checkArgument(player.getApplicationLooper() == Looper.getMainLooper());
|
||||
mainHandler = new Handler(Looper.getMainLooper());
|
||||
Uri streamRequestUri = checkNotNull(mediaItem.localConfiguration).uri;
|
||||
@ -536,6 +535,12 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
adsId = ImaServerSideAdInsertionUriBuilder.getAdsId(streamRequestUri);
|
||||
loadVideoTimeoutMs = ImaServerSideAdInsertionUriBuilder.getLoadVideoTimeoutMs(streamRequestUri);
|
||||
streamRequest = ImaServerSideAdInsertionUriBuilder.createStreamRequest(streamRequestUri);
|
||||
boolean isDashStream = streamRequest.getFormat().equals(StreamRequest.StreamFormat.DASH);
|
||||
componentListener =
|
||||
new ComponentListener(
|
||||
isLiveStream
|
||||
? (isDashStream ? new NoopAdEventListener() : new SinglePeriodLiveAdEventListener())
|
||||
: new VodAdEventListener());
|
||||
adPlaybackState = adsLoader.getAdPlaybackState(adsId);
|
||||
}
|
||||
|
||||
@ -773,6 +778,13 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
private final class ComponentListener
|
||||
implements AdEvent.AdEventListener, Player.Listener, AdPlaybackStateUpdater {
|
||||
|
||||
private final AdEventListener adEventListener;
|
||||
|
||||
/** Creates an new instance. */
|
||||
public ComponentListener(AdEventListener adEventListener) {
|
||||
this.adEventListener = adEventListener;
|
||||
}
|
||||
|
||||
// Implement Player.Listener.
|
||||
|
||||
@Override
|
||||
@ -883,56 +895,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
@MainThread
|
||||
@Override
|
||||
public void onAdEvent(AdEvent event) {
|
||||
AdPlaybackState newAdPlaybackState = adPlaybackState;
|
||||
switch (event.getType()) {
|
||||
case CUEPOINTS_CHANGED:
|
||||
// CUEPOINTS_CHANGED event is firing multiple times with the same queue points.
|
||||
if (!isLiveStream && newAdPlaybackState.equals(AdPlaybackState.NONE)) {
|
||||
newAdPlaybackState =
|
||||
setVodAdGroupPlaceholders(
|
||||
checkNotNull(streamManager).getCuePoints(), new AdPlaybackState(adsId));
|
||||
}
|
||||
break;
|
||||
case LOADED:
|
||||
if (isLiveStream) {
|
||||
Timeline timeline = player.getCurrentTimeline();
|
||||
Timeline.Window window =
|
||||
timeline.getWindow(player.getCurrentMediaItemIndex(), new Timeline.Window());
|
||||
if (window.lastPeriodIndex > window.firstPeriodIndex) {
|
||||
// multi-period live not integrated
|
||||
return;
|
||||
}
|
||||
long positionInWindowUs =
|
||||
timeline.getPeriod(player.getCurrentPeriodIndex(), new Timeline.Period())
|
||||
.positionInWindowUs;
|
||||
long currentContentPeriodPositionUs =
|
||||
msToUs(player.getContentPosition()) - positionInWindowUs;
|
||||
Ad ad = event.getAd();
|
||||
AdPodInfo adPodInfo = ad.getAdPodInfo();
|
||||
newAdPlaybackState =
|
||||
addLiveAdBreak(
|
||||
currentContentPeriodPositionUs,
|
||||
/* adDurationUs= */ secToUsRounded(ad.getDuration()),
|
||||
/* adPositionInAdPod= */ adPodInfo.getAdPosition(),
|
||||
/* totalAdDurationUs= */ secToUsRounded(adPodInfo.getMaxDuration()),
|
||||
/* totalAdsInAdPod= */ adPodInfo.getTotalAds(),
|
||||
/* adPlaybackState= */ newAdPlaybackState.equals(AdPlaybackState.NONE)
|
||||
? new AdPlaybackState(adsId)
|
||||
: newAdPlaybackState);
|
||||
} else {
|
||||
newAdPlaybackState = setVodAdInPlaceholder(event.getAd(), newAdPlaybackState);
|
||||
}
|
||||
break;
|
||||
case SKIPPED:
|
||||
if (!isLiveStream) {
|
||||
newAdPlaybackState = skipAd(event.getAd(), newAdPlaybackState);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
setAdPlaybackState(newAdPlaybackState);
|
||||
adEventListener.onAdEvent(event);
|
||||
}
|
||||
|
||||
// Implement AdPlaybackStateUpdater (called on the playback thread).
|
||||
@ -1356,4 +1319,70 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class VodAdEventListener implements AdEventListener {
|
||||
@Override
|
||||
public void onAdEvent(AdEvent event) {
|
||||
AdPlaybackState newAdPlaybackState = adPlaybackState;
|
||||
switch (event.getType()) {
|
||||
case CUEPOINTS_CHANGED:
|
||||
if (newAdPlaybackState.equals(AdPlaybackState.NONE)) {
|
||||
newAdPlaybackState =
|
||||
setVodAdGroupPlaceholders(
|
||||
checkNotNull(streamManager).getCuePoints(), new AdPlaybackState(adsId));
|
||||
}
|
||||
break;
|
||||
case LOADED:
|
||||
newAdPlaybackState = setVodAdInPlaceholder(event.getAd(), newAdPlaybackState);
|
||||
break;
|
||||
case SKIPPED:
|
||||
newAdPlaybackState = skipAd(event.getAd(), newAdPlaybackState);
|
||||
break;
|
||||
default:
|
||||
// Do nothing.
|
||||
break;
|
||||
}
|
||||
setAdPlaybackState(newAdPlaybackState);
|
||||
}
|
||||
}
|
||||
|
||||
private class SinglePeriodLiveAdEventListener implements AdEventListener {
|
||||
@Override
|
||||
public void onAdEvent(AdEvent event) {
|
||||
if (event.getType() != AdEvent.AdEventType.LOADED) {
|
||||
return;
|
||||
}
|
||||
AdPlaybackState newAdPlaybackState = adPlaybackState;
|
||||
Timeline timeline = player.getCurrentTimeline();
|
||||
long positionInWindowUs =
|
||||
timeline.getPeriod(player.getCurrentPeriodIndex(), new Timeline.Period())
|
||||
.positionInWindowUs;
|
||||
long currentContentPeriodPositionUs =
|
||||
msToUs(player.getContentPosition()) - positionInWindowUs;
|
||||
Ad ad = event.getAd();
|
||||
AdPodInfo adPodInfo = ad.getAdPodInfo();
|
||||
newAdPlaybackState =
|
||||
addLiveAdBreak(
|
||||
currentContentPeriodPositionUs,
|
||||
/* adDurationUs= */ secToUsRounded(ad.getDuration()),
|
||||
/* adPositionInAdPod= */ adPodInfo.getAdPosition(),
|
||||
/* totalAdDurationUs= */ secToUsRounded(adPodInfo.getMaxDuration()),
|
||||
/* totalAdsInAdPod= */ adPodInfo.getTotalAds(),
|
||||
/* adPlaybackState= */ newAdPlaybackState.equals(AdPlaybackState.NONE)
|
||||
? new AdPlaybackState(adsId)
|
||||
: newAdPlaybackState);
|
||||
setAdPlaybackState(newAdPlaybackState);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NoopAdEventListener implements AdEventListener {
|
||||
@Override
|
||||
public void onAdEvent(AdEvent event) {
|
||||
Log.w(
|
||||
"ImaSSAIMediaSource",
|
||||
String.format(
|
||||
"Ignoring IMA ad event %s because the current stream type is not supported.",
|
||||
event.getType().name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user