From 7501880062a4c381838949084f0017a2aecc58d7 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> Date: Thu, 17 Oct 2024 21:56:06 +0200 Subject: [PATCH] fix: remove warning and refactor & fix ad workflow (#4235) --- .../com/brentvatne/common/api/AdsProps.kt | 3 - .../com/brentvatne/common/api/CMCDProps.kt | 4 +- .../com/brentvatne/exoplayer/ExoPlayerView.kt | 28 +++-- .../exoplayer/ReactExoplayerView.java | 100 +++++++++--------- 4 files changed, 62 insertions(+), 73 deletions(-) diff --git a/android/src/main/java/com/brentvatne/common/api/AdsProps.kt b/android/src/main/java/com/brentvatne/common/api/AdsProps.kt index 9443d537..2f5a057c 100644 --- a/android/src/main/java/com/brentvatne/common/api/AdsProps.kt +++ b/android/src/main/java/com/brentvatne/common/api/AdsProps.kt @@ -2,7 +2,6 @@ package com.brentvatne.common.api import android.net.Uri import android.text.TextUtils -import com.brentvatne.common.toolbox.DebugLog import com.brentvatne.common.toolbox.ReactBridgeUtils import com.facebook.react.bridge.ReadableMap @@ -26,8 +25,6 @@ class AdsProps { @JvmStatic fun parse(src: ReadableMap?): AdsProps { val adsProps = AdsProps() - DebugLog.w("olivier", "uri: parse AdsProps") - if (src != null) { val uriString = ReactBridgeUtils.safeGetString(src, PROP_AD_TAG_URL) if (TextUtils.isEmpty(uriString)) { diff --git a/android/src/main/java/com/brentvatne/common/api/CMCDProps.kt b/android/src/main/java/com/brentvatne/common/api/CMCDProps.kt index 76bcefa1..dfff54b5 100644 --- a/android/src/main/java/com/brentvatne/common/api/CMCDProps.kt +++ b/android/src/main/java/com/brentvatne/common/api/CMCDProps.kt @@ -37,8 +37,8 @@ data class CMCDProps( return (0 until array.size()).mapNotNull { i -> val item = array.getMap(i) - val key = item?.getString("key") - val value = when (item?.getType("value")) { + val key = item.getString("key") + val value = when (item.getType("value")) { ReadableType.Number -> item.getDouble("value") ReadableType.String -> item.getString("value") else -> null diff --git a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.kt b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.kt index 98f2d0a5..462354c2 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.kt +++ b/android/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.kt @@ -40,7 +40,7 @@ class ExoPlayerView(private val context: Context) : ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) - private var adOverlayFrameLayout: FrameLayout + private var adOverlayFrameLayout: FrameLayout? = null val isPlaying: Boolean get() = player != null && player?.isPlaying == true @@ -72,12 +72,9 @@ class ExoPlayerView(private val context: Context) : updateSurfaceView(viewType) - adOverlayFrameLayout = FrameLayout(context) - layout.addView(shutterView, 1, layoutParams) if (localStyle.subtitlesFollowVideo) { layout.addView(subtitleLayout, layoutParams) - layout.addView(adOverlayFrameLayout, layoutParams) } addViewInLayout(layout, 0, aspectRatioParams) @@ -194,22 +191,21 @@ class ExoPlayerView(private val context: Context) : } } - private fun hideShutterView() { - shutterView.setVisibility(INVISIBLE) - surfaceView?.setAlpha(1f) - } - - private fun showShutterView() { - shutterView.setVisibility(VISIBLE) - surfaceView?.setAlpha(0f) - } - + var adsShown = false fun showAds() { - adOverlayFrameLayout.setVisibility(View.VISIBLE) + if (!adsShown) { + adOverlayFrameLayout = FrameLayout(context) + layout.addView(adOverlayFrameLayout, layoutParams) + adsShown = true + } } fun hideAds() { - adOverlayFrameLayout.setVisibility(View.GONE) + if (adsShown) { + layout.removeView(adOverlayFrameLayout) + adOverlayFrameLayout = null + adsShown = false + } } fun updateShutterViewVisibility() { diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index a672997a..1246d9fd 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -83,7 +83,6 @@ import androidx.media3.exoplayer.source.DefaultMediaSourceFactory; import androidx.media3.exoplayer.source.MediaSource; import androidx.media3.exoplayer.source.MergingMediaSource; import androidx.media3.exoplayer.source.ProgressiveMediaSource; -import androidx.media3.exoplayer.source.SingleSampleMediaSource; import androidx.media3.exoplayer.source.TrackGroupArray; import androidx.media3.exoplayer.source.ads.AdsMediaSource; import androidx.media3.exoplayer.trackselection.AdaptiveTrackSelection; @@ -827,23 +826,6 @@ public class ReactExoplayerView extends FrameLayout implements mediaSourceFactory.setDataSourceFactory(RNVSimpleCache.INSTANCE.getCacheFactory(buildHttpDataSourceFactory(true))); } - if (BuildConfig.USE_EXOPLAYER_IMA) { - AdsProps adProps = source.getAdsProps(); - - // Create an AdsLoader. - ImaAdsLoader.Builder imaLoaderBuilder = new ImaAdsLoader - .Builder(themedReactContext) - .setAdEventListener(this) - .setAdErrorListener(this); - - if (adProps != null && adProps.getAdLanguage() != null) { - ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings(); - imaSdkSettings.setLanguage(adProps.getAdLanguage()); - imaLoaderBuilder.setImaSdkSettings(imaSdkSettings); - } - adsLoader = imaLoaderBuilder.build(); - } - mediaSourceFactory.setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView); player = new ExoPlayer.Builder(getContext(), renderersFactory) @@ -858,9 +840,6 @@ public class ReactExoplayerView extends FrameLayout implements player.setVolume(muted ? 0.f : audioVolume * 1); exoPlayerView.setPlayer(player); - if (adsLoader != null) { - adsLoader.setPlayer(player); - } audioBecomingNoisyReceiver.setListener(self); bandwidthMeter.addEventListener(new Handler(), self); setPlayWhenReady(!isPaused); @@ -875,6 +854,41 @@ public class ReactExoplayerView extends FrameLayout implements } } + private AdsMediaSource initializeAds(MediaSource videoSource, Source runningSource) { + AdsProps adProps = runningSource.getAdsProps(); + Uri uri = runningSource.getUri(); + if (adProps != null && uri != null) { + Uri adTagUrl = adProps.getAdTagUrl(); + if (adTagUrl != null) { + exoPlayerView.showAds(); + // Create an AdsLoader. + ImaAdsLoader.Builder imaLoaderBuilder = new ImaAdsLoader + .Builder(themedReactContext) + .setAdEventListener(this) + .setAdErrorListener(this); + + if (adProps.getAdLanguage() != null) { + ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings(); + imaSdkSettings.setLanguage(adProps.getAdLanguage()); + imaLoaderBuilder.setImaSdkSettings(imaSdkSettings); + } + adsLoader = imaLoaderBuilder.build(); + adsLoader.setPlayer(player); + if (adsLoader != null) { + DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory) + .setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView); + DataSpec adTagDataSpec = new DataSpec(adTagUrl); + return new AdsMediaSource(videoSource, + adTagDataSpec, + ImmutableList.of(uri, adTagUrl), + mediaSourceFactory, adsLoader, exoPlayerView); + } + } + } + exoPlayerView.hideAds(); + return null; + } + private DrmSessionManager initializePlayerDrm() { DrmSessionManager drmSessionManager = null; DRMProps drmProps = source.getDrmProps(); @@ -908,32 +922,17 @@ public class ReactExoplayerView extends FrameLayout implements return; } // init source to manage ads and external text tracks - MediaSource subtitlesSource = buildTextSource(); - MediaSource videoSource = buildMediaSource(runningSource.getUri(), runningSource.getExtension(), drmSessionManager, runningSource.getCropStartMs(), runningSource.getCropEndMs()); - MediaSource mediaSourceWithAds = null; - Uri adTagUrl = null; - if (source.getAdsProps() != null) { - adTagUrl = source.getAdsProps().getAdTagUrl(); - } - if (adTagUrl != null && adsLoader != null) { - DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory) - .setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView); - DataSpec adTagDataSpec = new DataSpec(adTagUrl); - DebugLog.w(TAG, "ads " + adTagUrl); - mediaSourceWithAds = new AdsMediaSource(videoSource, adTagDataSpec, ImmutableList.of(runningSource.getUri(), adTagUrl), mediaSourceFactory, adsLoader, exoPlayerView); - exoPlayerView.showAds(); - } - MediaSource mediaSource; - if (subtitlesSource == null) { - mediaSource = Objects.requireNonNullElse(mediaSourceWithAds, videoSource); - } else { - ArrayList mediaSourceList = new ArrayList<>(); - mediaSourceList.add(subtitlesSource); - mediaSourceList.add(0, Objects.requireNonNullElse(mediaSourceWithAds, videoSource)); - MediaSource[] mediaSourceArray = mediaSourceList.toArray( - new MediaSource[mediaSourceList.size()] - ); + MediaSource videoSource = buildMediaSource(runningSource.getUri(), + runningSource.getExtension(), + drmSessionManager, + runningSource.getCropStartMs(), + runningSource.getCropEndMs()); + MediaSource mediaSourceWithAds = initializeAds(videoSource, runningSource); + MediaSource mediaSource = Objects.requireNonNullElse(mediaSourceWithAds, videoSource); + MediaSource subtitlesSource = buildTextSource(); + if (subtitlesSource != null) { + MediaSource[] mediaSourceArray = {mediaSource, subtitlesSource}; mediaSource = new MergingMediaSource(mediaSourceArray); } @@ -1132,6 +1131,7 @@ public class ReactExoplayerView extends FrameLayout implements drmProvider = new DefaultDrmSessionManagerProvider(); } + switch (type) { case CONTENT_TYPE_SS: if(!BuildConfig.USE_EXOPLAYER_SMOOTH_STREAMING) { @@ -1905,7 +1905,8 @@ public class ReactExoplayerView extends FrameLayout implements } if (!isSourceEqual) { - reloadSource(); + playerNeedsSource = true; + initializePlayer(); } } else { clearSrc(); @@ -1932,11 +1933,6 @@ public class ReactExoplayerView extends FrameLayout implements mReportBandwidth = reportBandwidth; } - private void reloadSource() { - playerNeedsSource = true; - initializePlayer(); - } - public void setResizeModeModifier(@ResizeMode.Mode int resizeMode) { if (exoPlayerView != null) { exoPlayerView.setResizeMode(resizeMode);