Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ads localize #4113

Merged
merged 4 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@
import androidx.media3.exoplayer.source.ads.AdsLoader;
import androidx.media3.exoplayer.source.ads.AdsMediaSource;

import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;

import java.io.IOException;

public class ImaAdsLoader implements AdsLoader {
private final ImaSdkSettings imaSdkSettings;

public ImaAdsLoader(ImaSdkSettings imaSdkSettings) {
this.imaSdkSettings = imaSdkSettings;
}

public void setPlayer(ExoPlayer ignoredPlayer) {
}

Expand Down Expand Up @@ -45,6 +53,7 @@ public void handlePrepareError(@NonNull AdsMediaSource adsMediaSource, int i, in
}

public static class Builder {
private ImaSdkSettings imaSdkSettings;
public Builder(Context ignoredThemedReactContext) {
}

Expand All @@ -56,6 +65,11 @@ public Builder setAdErrorListener(Object ignoredReactExoplayerView) {
return this;
}

public Builder setImaSdkSettings(ImaSdkSettings imaSdkSettings) {
this.imaSdkSettings = imaSdkSettings;
return this;
}

public ImaAdsLoader build() {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@
import com.google.ads.interactivemedia.v3.api.AdError;
import com.google.ads.interactivemedia.v3.api.AdEvent;
import com.google.ads.interactivemedia.v3.api.AdErrorEvent;
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
import com.google.ads.interactivemedia.v3.api.ImaSdkFactory;
import com.google.common.collect.ImmutableList;

import java.net.CookieHandler;
Expand Down Expand Up @@ -251,6 +253,7 @@ public class ReactExoplayerView extends FrameLayout implements
private boolean mReportBandwidth = false;
private boolean controls;
private Uri adTagUrl;
private String adLanguage;

private boolean showNotificationControls = false;
// \ End props
Expand Down Expand Up @@ -754,9 +757,13 @@ private void initializePlayerCore(ReactExoplayerView self) {
.setEnableDecoderFallback(true)
.forceEnableMediaCodecAsynchronousQueueing();

ImaSdkSettings imaSdkSettings = ImaSdkFactory.getInstance().createImaSdkSettings();
imaSdkSettings.setLanguage(adLanguage);

// Create an AdsLoader.
adsLoader = new ImaAdsLoader
.Builder(themedReactContext)
.setImaSdkSettings(imaSdkSettings)
.setAdEventListener(this)
.setAdErrorListener(this)
.build();
Expand Down Expand Up @@ -1851,6 +1858,10 @@ public void setAdTagUrl(final Uri uri) {
adTagUrl = uri;
}

public void setAdLanguage(final String language) {
adLanguage = language;
}

public void setTextTracks(SideLoadedTextTrackList textTracks) {
this.textTracks = textTracks;
reloadSource(); // FIXME Shall be moved inside source
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View
private const val REACT_CLASS = "RCTVideo"
private const val PROP_SRC = "src"
private const val PROP_AD_TAG_URL = "adTagUrl"
private const val PROP_AD_LANGUAGE = "adLanguage"
private const val PROP_RESIZE_MODE = "resizeMode"
private const val PROP_REPEAT = "repeat"
private const val PROP_SELECTED_AUDIO_TRACK = "selectedAudioTrack"
Expand Down Expand Up @@ -110,6 +111,16 @@ class ReactExoplayerViewManager(private val config: ReactExoplayerConfig) : View
videoView.setAdTagUrl(adTagUrl)
}

@ReactProp(name = PROP_AD_LANGUAGE)
fun setAdLanguage(videoView: ReactExoplayerView, languageString: String?) {
if (TextUtils.isEmpty(languageString)) {
videoView.setAdLanguage(null) // Maybe "en" default?
moskalakamil marked this conversation as resolved.
Show resolved Hide resolved
return
}

videoView.setAdLanguage(languageString)
}

@ReactProp(name = PROP_RESIZE_MODE)
fun setResizeMode(videoView: ReactExoplayerView, resizeMode: String) {
when (resizeMode) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.google.ads.interactivemedia.v3.api;

public abstract class ImaSdkFactory {
private static ImaSdkFactory instance;

public abstract ImaSdkSettings createImaSdkSettings();

public static ImaSdkFactory getInstance() {
if (instance == null) {
instance = new ConcreteImaSdkFactory();
}
return instance;
}
}

class ConcreteImaSdkFactory extends ImaSdkFactory {

@Override
public ImaSdkSettings createImaSdkSettings() {
return new ConcreteImaSdkSettings();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.google.ads.interactivemedia.v3.api;

import androidx.annotation.InspectableProperty;

public abstract class ImaSdkSettings {
public abstract String getLanguage();
public abstract void setLanguage(String language);
}

// Concrete Implementation
class ConcreteImaSdkSettings extends ImaSdkSettings {

private String language;

@Override
public String getLanguage() {
return language;
}

@Override
public void setLanguage(String language) {
this.language = language;
}
}
13 changes: 13 additions & 0 deletions docs/pages/component/ads.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,16 @@ Example:
onReceiveAdEvent={event => console.log(event)}
...
```

### Localization
To change the language of the IMA SDK, you need to pass `adLanguage` prop to `Video` component. List of supported languages, you can find [here](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/localization#locale-codes)

by default ios will be system language and android will be `en`
guyhguy25 marked this conversation as resolved.
Show resolved Hide resolved

Example:

```jsx
...
adLanguage="fr"
...
```
7 changes: 6 additions & 1 deletion ios/Video/Features/RCTIMAAdsManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
}

func setUpAdsLoader() {
adsLoader = IMAAdsLoader(settings: nil)
guard let _video else { return }
let settings = IMASettings()
if let adLanguage = _video.getAdLanguage() {
settings.language = adLanguage
}
adsLoader = IMAAdsLoader(settings: settings)
adsLoader.delegate = self
}

Expand Down
5 changes: 5 additions & 0 deletions ios/Video/RCTVideo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH

/* IMA Ads */
private var _adTagUrl: String?
private var _adLanguage: String?
#if USE_GOOGLE_IMA
private var _imaAdsManager: RCTIMAAdsManager!
/* Playhead used by the SDK to track content video progress and insert mid-rolls. */
Expand Down Expand Up @@ -1213,6 +1214,10 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH

// MARK: - RCTIMAAdsManager

func getAdLanguage() -> String? {
return _adLanguage
}

func getAdTagUrl() -> String? {
return _adTagUrl
}
Expand Down
1 change: 1 addition & 0 deletions ios/Video/RCTVideoManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ @interface RCT_EXTERN_MODULE (RCTVideoManager, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(drm, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(adTagUrl, NSString);
RCT_EXPORT_VIEW_PROPERTY(adLanguage, NSString);
RCT_EXPORT_VIEW_PROPERTY(maxBitRate, float);
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString);
RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL);
Expand Down
1 change: 1 addition & 0 deletions src/specs/VideoNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ export type OnControlsVisibilityChange = Readonly<{
export interface VideoNativeProps extends ViewProps {
src?: VideoSrc;
adTagUrl?: string;
adLanguage?: string;
allowsExternalPlayback?: boolean; // ios, true
disableFocus?: boolean; // android
maxBitRate?: Float;
Expand Down
1 change: 1 addition & 0 deletions src/types/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ export interface ReactVideoProps extends ReactVideoEvents, ViewProps {
drm?: Drm;
style?: StyleProp<ViewStyle>;
adTagUrl?: string;
adLanguage?: ISO639_1;
audioOutput?: AudioOutput; // Mobile
automaticallyWaitsToMinimizeStalling?: boolean; // iOS
bufferConfig?: BufferConfig; // Android
Expand Down
Loading