From fe89122524826093689118a4515802d83ca88679 Mon Sep 17 00:00:00 2001 From: Olivier Bouillet <62574056+freeboub@users.noreply.github.com> Date: Fri, 24 Nov 2023 13:17:13 +0100 Subject: [PATCH] fix(android): ads build and enable ads in android sample (#3376) * fix: refactor androidx core version management * chore: fix missing import rework for media3 * fix: enable IMA in sample * chore: rename stub fie * chore: code review, fix variable name * chore: reorder imports * chore: fix linking in sample * chore: fix stub management * chore: few cleans and ensure we don't use ima is disabled --------- Co-authored-by: olivier --- android/build.gradle | 5 +- android/gradle.properties | 3 +- .../media3/exoplayer/ima/ImaAdsLoader.java | 61 +++++++++++++++++ .../exoplayer/ReactExoplayerView.java | 16 +++-- .../exoplayer2/ext/ima/ImaAdsLoader.java | 65 ------------------- examples/basic/android/app/build.gradle | 13 ++++ .../java/com/videoplayer/MainApplication.java | 2 +- examples/basic/android/build.gradle | 4 +- examples/basic/package.json | 1 - examples/basic/src/VideoPlayer.tsx | 2 +- examples/basic/yarn.lock | 3 - 11 files changed, 94 insertions(+), 81 deletions(-) create mode 100644 android/src/main/java/androidx/media3/exoplayer/ima/ImaAdsLoader.java delete mode 100644 android/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java diff --git a/android/build.gradle b/android/build.gradle index 4c8a9cbd..1cdf92d0 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -105,7 +105,7 @@ android { java { if (useExoplayerIMA) { exclude 'com/google/ads/interactivemedia/v3/api' - exclude 'com/google/android/exoplayer2/ext/ima' + exclude 'androidx/media3/exoplayer/ima' } } } @@ -143,6 +143,7 @@ repositories { def media3_version = safeExtGet('media3Version') def kotlin_version = safeExtGet('kotlinVersion') +def androidxCode_version = safeExtGet('androidxCoreVersion') dependencies { // For < 0.71, this will be from the local maven repo @@ -150,7 +151,7 @@ dependencies { //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" - implementation "androidx.core:core:1.9.0" + implementation "androidx.core:core:$androidxCode_version" // For media playback using ExoPlayer implementation "androidx.media3:media3-exoplayer:$media3_version" diff --git a/android/gradle.properties b/android/gradle.properties index 72deab30..3610915c 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -5,4 +5,5 @@ RNVideo_compileSdkVersion=31 RNVideo_ndkversion=21.4.7075529 RNVideo_buildToolsVersion=30.0.2 RNVideo_media3Version=1.1.1 -RNVideo_RNVUseExoplayerIMA=false \ No newline at end of file +RNVideo_RNVUseExoplayerIMA=false +RNVideo_androidxCoreVersion=1.9.0 diff --git a/android/src/main/java/androidx/media3/exoplayer/ima/ImaAdsLoader.java b/android/src/main/java/androidx/media3/exoplayer/ima/ImaAdsLoader.java new file mode 100644 index 00000000..148d5803 --- /dev/null +++ b/android/src/main/java/androidx/media3/exoplayer/ima/ImaAdsLoader.java @@ -0,0 +1,61 @@ +package androidx.media3.exoplayer.ima; + +import android.content.Context; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.media3.common.AdViewProvider; +import androidx.media3.common.Player; +import androidx.media3.datasource.DataSpec; +import androidx.media3.exoplayer.ExoPlayer; +import androidx.media3.exoplayer.source.ads.AdsLoader; +import androidx.media3.exoplayer.source.ads.AdsMediaSource; + +import com.facebook.react.uimanager.ThemedReactContext; + +import java.io.IOException; + +public class ImaAdsLoader implements AdsLoader { + public void setPlayer(ExoPlayer ignoredPlayer) { + } + + @Override + public void setPlayer(@Nullable Player player) { + } + + public void release() { + } + + @Override + public void setSupportedContentTypes(@NonNull int... ints) { + } + + @Override + public void start(@NonNull AdsMediaSource adsMediaSource, @NonNull DataSpec dataSpec, @NonNull Object adsId, @NonNull AdViewProvider adViewProvider, @NonNull EventListener eventListener) { + } + + @Override + public void stop(@NonNull AdsMediaSource adsMediaSource, @NonNull EventListener eventListener) { + } + + @Override + public void handlePrepareComplete(@NonNull AdsMediaSource adsMediaSource, int i, int i1) { + } + + @Override + public void handlePrepareError(@NonNull AdsMediaSource adsMediaSource, int i, int i1, @NonNull IOException e) { + } + + public static class Builder { + public Builder(Context ignoredThemedReactContext) { + } + + public Builder setAdEventListener(Object ignoredReactExoplayerView) { + return this; + } + + public ImaAdsLoader build() { + return null; + } + } +} diff --git a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java index 7cd35d6d..21ef75a0 100644 --- a/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java +++ b/android/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java @@ -61,6 +61,7 @@ import androidx.media3.exoplayer.drm.FrameworkMediaDrm; import androidx.media3.exoplayer.drm.HttpMediaDrmCallback; import androidx.media3.exoplayer.drm.UnsupportedDrmException; import androidx.media3.exoplayer.hls.HlsMediaSource; +import androidx.media3.exoplayer.ima.ImaAdsLoader; import androidx.media3.exoplayer.mediacodec.MediaCodecInfo; import androidx.media3.exoplayer.mediacodec.MediaCodecUtil; import androidx.media3.exoplayer.smoothstreaming.DefaultSsChunkSource; @@ -103,7 +104,6 @@ import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.uimanager.ThemedReactContext; import com.google.ads.interactivemedia.v3.api.AdEvent; -import com.google.android.exoplayer2.ext.ima.ImaAdsLoader; import com.google.common.collect.ImmutableList; import java.net.CookieHandler; @@ -617,10 +617,14 @@ public class ReactExoplayerView extends FrameLayout implements .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF); // Create an AdsLoader. - adsLoader = new ImaAdsLoader.Builder(themedReactContext).setAdEventListener(this).build(); + adsLoader = new ImaAdsLoader.Builder(themedReactContext) + .setAdEventListener(this) + .build(); - MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory) - .setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView); + DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory); + if (adsLoader != null) { + mediaSourceFactory.setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView); + } player = new ExoPlayer.Builder(getContext(), renderersFactory) .setTrackSelector(self.trackSelector) @@ -665,8 +669,8 @@ public class ReactExoplayerView extends FrameLayout implements ArrayList mediaSourceList = buildTextSources(); MediaSource videoSource = buildMediaSource(self.srcUri, self.extension, drmSessionManager, cropStartMs, cropEndMs); MediaSource mediaSourceWithAds = null; - if (adTagUrl != null) { - MediaSource.Factory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory) + if (adTagUrl != null && adsLoader != null) { + DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory) .setLocalAdInsertionComponents(unusedAdTagUri -> adsLoader, exoPlayerView); DataSpec adTagDataSpec = new DataSpec(adTagUrl); mediaSourceWithAds = new AdsMediaSource(videoSource, adTagDataSpec, ImmutableList.of(srcUri, adTagUrl), mediaSourceFactory, adsLoader, exoPlayerView); diff --git a/android/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/android/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java deleted file mode 100644 index cb2b2e42..00000000 --- a/android/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.google.android.exoplayer2.ext.ima; - -import androidx.annotation.Nullable; -import androidx.media3.common.AdViewProvider; -import androidx.media3.common.Player; -import androidx.media3.datasource.DataSpec; -import androidx.media3.exoplayer.ExoPlayer; -import androidx.media3.exoplayer.source.ads.AdsLoader; -import androidx.media3.exoplayer.source.ads.AdsMediaSource; - -import com.facebook.react.uimanager.ThemedReactContext; - -import java.io.IOException; - -public class ImaAdsLoader implements AdsLoader { - public void setPlayer(ExoPlayer player) { - } - - @Override - public void setPlayer(@Nullable Player player) { - - } - - public void release() { - } - - @Override - public void setSupportedContentTypes(int... ints) { - - } - - @Override - public void start(AdsMediaSource adsMediaSource, DataSpec dataSpec, Object adsId, AdViewProvider adViewProvider, EventListener eventListener) { - - } - - @Override - public void stop(AdsMediaSource adsMediaSource, EventListener eventListener) { - - } - - @Override - public void handlePrepareComplete(AdsMediaSource adsMediaSource, int i, int i1) { - - } - - @Override - public void handlePrepareError(AdsMediaSource adsMediaSource, int i, int i1, IOException e) { - - } - - public static class Builder { - public Builder(ThemedReactContext themedReactContext) { - - } - - public Builder setAdEventListener(Object reactExoplayerView) { - return this; - } - - public ImaAdsLoader build() { - return null; - } - } -} diff --git a/examples/basic/android/app/build.gradle b/examples/basic/android/app/build.gradle index 54abe3e3..f173269a 100644 --- a/examples/basic/android/app/build.gradle +++ b/examples/basic/android/app/build.gradle @@ -101,8 +101,12 @@ android { proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } + configurations.all { + resolutionStrategy { force 'androidx.core:core:1.9.0' } + } } + dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") @@ -120,6 +124,15 @@ dependencies { } implementation project(':react-native-video') + + constraints { + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") { + because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib") + } + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") { + because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib") + } + } } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/examples/basic/android/app/src/main/java/com/videoplayer/MainApplication.java b/examples/basic/android/app/src/main/java/com/videoplayer/MainApplication.java index 437d0f64..9cde2307 100644 --- a/examples/basic/android/app/src/main/java/com/videoplayer/MainApplication.java +++ b/examples/basic/android/app/src/main/java/com/videoplayer/MainApplication.java @@ -30,7 +30,7 @@ public class MainApplication extends Application implements ReactApplication { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: - // packages.add(new MyReactNativePackage()); + packages.add(new ReactVideoPackage()); return packages; } diff --git a/examples/basic/android/build.gradle b/examples/basic/android/build.gradle index 7efd41ab..8034dfe8 100644 --- a/examples/basic/android/build.gradle +++ b/examples/basic/android/build.gradle @@ -6,10 +6,12 @@ buildscript { minSdkVersion = 21 compileSdkVersion = 33 targetSdkVersion = 33 - kotlinVersion = "1.6.20" + kotlinVersion = "1.8.0" // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP. ndkVersion = "23.1.7779620" + + RNVUseExoplayerIMA = true } repositories { google() diff --git a/examples/basic/package.json b/examples/basic/package.json index 0ca16261..89d4db36 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -14,7 +14,6 @@ "@react-native-picker/picker": "^1.9.11", "react": "18.2.0", "react-native": "0.72.5", - "react-native-video": "../../", "react-native-windows": "0.63.41" }, "devDependencies": { diff --git a/examples/basic/src/VideoPlayer.tsx b/examples/basic/src/VideoPlayer.tsx index 197483b5..9d9c90d1 100644 --- a/examples/basic/src/VideoPlayer.tsx +++ b/examples/basic/src/VideoPlayer.tsx @@ -715,7 +715,7 @@ class VideoPlayer extends Component { this.video = ref; }} source={this.srcList[this.state.srcListId]} - //adTagUrl={this.srcList[this.state.srcListId]?.adTagUrl} + adTagUrl={this.srcList[this.state.srcListId]?.adTagUrl} style={viewStyle} rate={this.state.rate} paused={this.state.paused} diff --git a/examples/basic/yarn.lock b/examples/basic/yarn.lock index 4661c5f6..a4f8ccfb 100644 --- a/examples/basic/yarn.lock +++ b/examples/basic/yarn.lock @@ -6129,9 +6129,6 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-native-video@../../: - version "6.0.0-beta.0" - react-native-windows@0.63.41: version "0.63.41" resolved "https://registry.yarnpkg.com/react-native-windows/-/react-native-windows-0.63.41.tgz#96f59bc24749b6c167cb4f35fd74b66f78f4a4bb"