mirror of
https://github.com/samsonjs/media.git
synced 2026-04-04 11:05:47 +00:00
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
4631105fb3
commit
91e611d5dc
1 changed files with 80 additions and 51 deletions
|
|
@ -526,7 +526,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;
|
||||
|
|
@ -534,6 +533,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);
|
||||
}
|
||||
|
||||
|
|
@ -771,6 +776,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
|
||||
|
|
@ -881,56 +893,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).
|
||||
|
|
@ -1354,4 +1317,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…
Reference in a new issue