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

View File

@ -67,16 +67,8 @@ public final class ServerSideAdInsertionUtil {
.withAdCount(insertionIndex, /* adCount= */ 1)
.withAdDurationsUs(insertionIndex, adDurationUs)
.withContentResumeOffsetUs(insertionIndex, contentResumeOffsetUs);
long followingAdGroupTimeUsOffset = -adDurationUs + contentResumeOffsetUs;
for (int i = insertionIndex + 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;
return correctFollowingAdGroupTimes(
adPlaybackState, insertionIndex, adDurationUs, contentResumeOffsetUs);
}
/**
@ -314,4 +306,21 @@ public final class ServerSideAdInsertionUtil {
AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex);
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;
}
}