Support IMA DAI streams for HLS

PiperOrigin-RevId: 414804513
This commit is contained in:
bachinger 2021-12-07 21:02:24 +00:00 committed by Oliver Woodman
parent eaa4ab59a9
commit a92e48e5f8
3 changed files with 48 additions and 29 deletions

View File

@ -37,6 +37,7 @@ import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer;
import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ui.AdOverlayInfo; import com.google.android.exoplayer2.ui.AdOverlayInfo;
import com.google.android.exoplayer2.ui.AdViewProvider;
import com.google.android.exoplayer2.upstream.DataSchemeDataSource; import com.google.android.exoplayer2.upstream.DataSchemeDataSource;
import com.google.android.exoplayer2.upstream.DataSourceUtil; import com.google.android.exoplayer2.upstream.DataSourceUtil;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
@ -135,31 +136,28 @@ import java.util.Set;
} }
} }
/** Stores configuration for DAI ad playback. */ /** Stores configuration for playing server side ad insertion content. */
static final class DaiConfiguration { public static final class ServerSideAdInsertionConfiguration {
public final AdErrorEvent.AdErrorListener applicationAdErrorListener; public final AdViewProvider adViewProvider;
public final ImaSdkSettings imaSdkSettings;
@Nullable public final AdEvent.AdEventListener applicationAdEventListener;
@Nullable public final AdErrorEvent.AdErrorListener applicationAdErrorListener;
public final ImmutableList<CompanionAdSlot> companionAdSlots;
public final boolean debugModeEnabled; public final boolean debugModeEnabled;
@Nullable public final List<CompanionAdSlot> companionAdSlots; public ServerSideAdInsertionConfiguration(
@Nullable public final AdEvent.AdEventListener applicationAdEventListener; AdViewProvider adViewProvider,
@Nullable public final VideoAdPlayer.VideoAdPlayerCallback applicationVideoAdPlayerCallback; ImaSdkSettings imaSdkSettings,
@Nullable public final ImaSdkSettings imaSdkSettings;
public DaiConfiguration(
AdErrorEvent.AdErrorListener applicationAdErrorListener,
@Nullable List<CompanionAdSlot> companionAdSlots,
@Nullable AdEvent.AdEventListener applicationAdEventListener, @Nullable AdEvent.AdEventListener applicationAdEventListener,
@Nullable VideoAdPlayer.VideoAdPlayerCallback applicationVideoAdPlayerCallback, @Nullable AdErrorEvent.AdErrorListener applicationAdErrorListener,
@Nullable ImaSdkSettings imaSdkSettings, List<CompanionAdSlot> companionAdSlots,
boolean debugModeEnabled) { boolean debugModeEnabled) {
this.applicationAdErrorListener = applicationAdErrorListener;
this.companionAdSlots =
companionAdSlots != null ? ImmutableList.copyOf(companionAdSlots) : null;
this.applicationAdEventListener = applicationAdEventListener;
this.applicationVideoAdPlayerCallback = applicationVideoAdPlayerCallback;
this.imaSdkSettings = imaSdkSettings; this.imaSdkSettings = imaSdkSettings;
this.adViewProvider = adViewProvider;
this.applicationAdEventListener = applicationAdEventListener;
this.applicationAdErrorListener = applicationAdErrorListener;
this.companionAdSlots = ImmutableList.copyOf(companionAdSlots);
this.debugModeEnabled = debugModeEnabled; this.debugModeEnabled = debugModeEnabled;
} }
} }

View File

@ -1141,6 +1141,18 @@ public final class Util {
return (timeMs == C.TIME_UNSET || timeMs == C.TIME_END_OF_SOURCE) ? timeMs : (timeMs * 1000); return (timeMs == C.TIME_UNSET || timeMs == C.TIME_END_OF_SOURCE) ? timeMs : (timeMs * 1000);
} }
/**
* Converts a time in seconds to the corresponding time in microseconds.
*
* @param timeSec The time in seconds.
* @return The corresponding time in microseconds.
*/
public static long secToUs(double timeSec) {
return BigDecimal.valueOf(timeSec)
.multiply(BigDecimal.valueOf(C.MICROS_PER_SECOND))
.longValue();
}
/** /**
* Parses an xs:duration attribute value, returning the parsed duration in milliseconds. * Parses an xs:duration attribute value, returning the parsed duration in milliseconds.
* *

View File

@ -67,16 +67,8 @@ public final class ServerSideAdInsertionUtil {
.withAdCount(insertionIndex, /* adCount= */ 1) .withAdCount(insertionIndex, /* adCount= */ 1)
.withAdDurationsUs(insertionIndex, adDurationUs) .withAdDurationsUs(insertionIndex, adDurationUs)
.withContentResumeOffsetUs(insertionIndex, contentResumeOffsetUs); .withContentResumeOffsetUs(insertionIndex, contentResumeOffsetUs);
long followingAdGroupTimeUsOffset = -adDurationUs + contentResumeOffsetUs; return correctFollowingAdGroupTimes(
for (int i = insertionIndex + 1; i < adPlaybackState.adGroupCount; i++) { adPlaybackState, insertionIndex, adDurationUs, contentResumeOffsetUs);
long adGroupTimeUs = adPlaybackState.getAdGroup(i).timeUs;
if (adGroupTimeUs != C.TIME_END_OF_SOURCE) {
adPlaybackState =
adPlaybackState.withAdGroupTimeUs(
/* adGroupIndex= */ i, adGroupTimeUs + followingAdGroupTimeUsOffset);
}
}
return adPlaybackState;
} }
/** /**
@ -314,4 +306,21 @@ public final class ServerSideAdInsertionUtil {
AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex); AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex);
return adGroup.count == C.LENGTH_UNSET ? 0 : adGroup.count; return adGroup.count == C.LENGTH_UNSET ? 0 : adGroup.count;
} }
private static AdPlaybackState correctFollowingAdGroupTimes(
AdPlaybackState adPlaybackState,
int adGroupInsertionIndex,
long insertedAdDurationUs,
long addedContentResumeOffsetUs) {
long followingAdGroupTimeUsOffset = -insertedAdDurationUs + addedContentResumeOffsetUs;
for (int i = adGroupInsertionIndex + 1; i < adPlaybackState.adGroupCount; i++) {
long adGroupTimeUs = adPlaybackState.getAdGroup(i).timeUs;
if (adGroupTimeUs != C.TIME_END_OF_SOURCE) {
adPlaybackState =
adPlaybackState.withAdGroupTimeUs(
/* adGroupIndex= */ i, adGroupTimeUs + followingAdGroupTimeUsOffset);
}
}
return adPlaybackState;
}
} }