From 1218f56db64dee47f2ede90ab56877aa45bbe222 Mon Sep 17 00:00:00 2001 From: bachinger Date: Tue, 7 Dec 2021 21:02:24 +0000 Subject: [PATCH] Support IMA DAI streams for HLS PiperOrigin-RevId: 414804513 --- .../androidx/media3/common/util/Util.java | 12 +++++++ .../source/ads/ServerSideAdInsertionUtil.java | 29 +++++++++------ .../media3/exoplayer/ima/ImaUtil.java | 36 +++++++++---------- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/util/Util.java b/libraries/common/src/main/java/androidx/media3/common/util/Util.java index 9246d37c6d..69c78eeb6d 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/Util.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/Util.java @@ -1143,6 +1143,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. * diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java index 796a1cec55..e1e97f7d93 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java @@ -70,16 +70,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); } /** @@ -317,4 +309,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; + } } diff --git a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaUtil.java b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaUtil.java index 2347286705..6703b02709 100644 --- a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaUtil.java +++ b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaUtil.java @@ -21,6 +21,7 @@ import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; import androidx.media3.common.AdOverlayInfo; +import androidx.media3.common.AdViewProvider; import androidx.media3.common.C; import androidx.media3.common.util.Util; import androidx.media3.datasource.DataSchemeDataSource; @@ -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 companionAdSlots; public final boolean debugModeEnabled; - @Nullable public final List 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 companionAdSlots, + public ServerSideAdInsertionConfiguration( + AdViewProvider adViewProvider, + ImaSdkSettings imaSdkSettings, @Nullable AdEvent.AdEventListener applicationAdEventListener, - @Nullable VideoAdPlayer.VideoAdPlayerCallback applicationVideoAdPlayerCallback, - @Nullable ImaSdkSettings imaSdkSettings, + @Nullable AdErrorEvent.AdErrorListener applicationAdErrorListener, + List 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; } }