diff --git a/android-exoplayer/build.gradle b/android-exoplayer/build.gradle
index 502fa599..ac7acd85 100644
--- a/android-exoplayer/build.gradle
+++ b/android-exoplayer/build.gradle
@@ -26,6 +26,7 @@ dependencies {
implementation('com.google.android.exoplayer:exoplayer:2.10.5') {
exclude group: 'com.android.support'
}
+ implementation 'com.google.android.exoplayer:extension-ima:2.10.5'
// All support libs must use the same version
implementation "androidx.annotation:annotation:1.1.0"
diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java
index 9f3d09be..a8d6311a 100644
--- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java
+++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ExoPlayerView.java
@@ -18,16 +18,19 @@ import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
+import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.text.Cue;
import com.google.android.exoplayer2.text.TextRenderer;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.ui.SubtitleView;
+import com.google.android.exoplayer2.util.Assertions;
import java.util.List;
+import java.util.ArrayList;
@TargetApi(16)
-public final class ExoPlayerView extends FrameLayout {
+public final class ExoPlayerView extends FrameLayout implements AdsLoader.AdViewProvider {
private View surfaceView;
private final View shutterView;
@@ -37,6 +40,7 @@ public final class ExoPlayerView extends FrameLayout {
private SimpleExoPlayer player;
private Context context;
private ViewGroup.LayoutParams layoutParams;
+ private final FrameLayout adOverlayFrameLayout;
private boolean useTextureView = true;
private boolean hideShutterView = false;
@@ -81,7 +85,11 @@ public final class ExoPlayerView extends FrameLayout {
layout.addView(shutterView, 1, layoutParams);
layout.addView(subtitleLayout, 2, layoutParams);
+ adOverlayFrameLayout = new FrameLayout(context);
+
addViewInLayout(layout, 0, aspectRatioParams);
+ addViewInLayout(adOverlayFrameLayout, 1, layoutParams);
+
}
private void setVideoView() {
@@ -111,6 +119,31 @@ public final class ExoPlayerView extends FrameLayout {
shutterView.setVisibility(this.hideShutterView ? View.INVISIBLE : View.VISIBLE);
}
+ @Override
+ public void requestLayout() {
+ super.requestLayout();
+ post(measureAndLayout);
+ }
+
+ // AdsLoader.AdViewProvider implementation.
+
+ @Override
+ public ViewGroup getAdViewGroup() {
+ return Assertions.checkNotNull(adOverlayFrameLayout, "exo_ad_overlay must be present for ad playback");
+ }
+
+ @Override
+ public View[] getAdOverlayViews() {
+ ArrayList overlayViews = new ArrayList<>();
+ if (adOverlayFrameLayout != null) {
+ overlayViews.add(adOverlayFrameLayout);
+ }
+ // if (controller != null) {
+ // overlayViews.add(controller);
+ // }
+ return overlayViews.toArray(new View[0]);
+ }
+
/**
* Set the {@link SimpleExoPlayer} to use. The {@link SimpleExoPlayer#setTextOutput} and
* {@link SimpleExoPlayer#setVideoListener} method of the player will be called and previous
diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
index 4802a5a4..0572f66a 100644
--- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
+++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerView.java
@@ -63,9 +63,13 @@ import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.util.Util;
+import com.google.android.exoplayer2.ext.ima.ImaAdsLoader;
+import com.google.android.exoplayer2.source.ads.AdsMediaSource;
+
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
@@ -77,7 +81,8 @@ class ReactExoplayerView extends FrameLayout implements
BandwidthMeter.EventListener,
BecomingNoisyListener,
AudioManager.OnAudioFocusChangeListener,
- MetadataOutput {
+ MetadataOutput,
+ AdsMediaSource.MediaSourceFactory {
private static final String TAG = "ReactExoplayerView";
@@ -97,6 +102,7 @@ class ReactExoplayerView extends FrameLayout implements
private Player.EventListener eventListener;
private ExoPlayerView exoPlayerView;
+ private ImaAdsLoader adsLoader;
private DataSource.Factory mediaDataSourceFactory;
private SimpleExoPlayer player;
@@ -139,6 +145,7 @@ class ReactExoplayerView extends FrameLayout implements
private Map requestHeaders;
private boolean mReportBandwidth = false;
private boolean controls;
+ private Uri adTagUrl;
// \ End props
// React
@@ -155,6 +162,9 @@ class ReactExoplayerView extends FrameLayout implements
&& player.getPlaybackState() == Player.STATE_READY
&& player.getPlayWhenReady()
) {
+ if (isPlayingAd()) {
+ playerControlView.hide();
+ }
long pos = player.getCurrentPosition();
long bufferedDuration = player.getBufferedPercentage() * player.getDuration() / 100;
eventEmitter.progressChanged(pos, bufferedDuration, player.getDuration());
@@ -173,6 +183,8 @@ class ReactExoplayerView extends FrameLayout implements
this.config = config;
this.bandwidthMeter = config.getBandwidthMeter();
+ adsLoader = new ImaAdsLoader(this.themedReactContext, Uri.EMPTY);
+
createViews();
audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -182,6 +194,10 @@ class ReactExoplayerView extends FrameLayout implements
initializePlayer();
}
+ private boolean isPlayingAd() {
+ return player != null && player.isPlayingAd() && player.getPlayWhenReady();
+ }
+
@Override
public void setId(int id) {
@@ -288,7 +304,9 @@ class ReactExoplayerView extends FrameLayout implements
exoPlayerView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- togglePlayerControlVisibility();
+ if (!isPlayingAd()) {
+ togglePlayerControlVisibility();
+ }
}
});
@@ -360,6 +378,7 @@ class ReactExoplayerView extends FrameLayout implements
trackSelector, defaultLoadControl, null, bandwidthMeter);
player.addListener(self);
player.addMetadataOutput(self);
+ adsLoader.setPlayer(player);
exoPlayerView.setPlayer(player);
audioBecomingNoisyReceiver.setListener(self);
bandwidthMeter.addEventListener(new Handler(), self);
@@ -372,11 +391,12 @@ class ReactExoplayerView extends FrameLayout implements
if (playerNeedsSource && srcUri != null) {
ArrayList mediaSourceList = buildTextSources();
MediaSource videoSource = buildMediaSource(srcUri, extension);
+ MediaSource mediaSourceWithAds = new AdsMediaSource(videoSource, mediaDataSourceFactory, adsLoader, exoPlayerView);
MediaSource mediaSource;
if (mediaSourceList.size() == 0) {
- mediaSource = videoSource;
+ mediaSource = mediaSourceWithAds;
} else {
- mediaSourceList.add(0, videoSource);
+ mediaSourceList.add(0, mediaSourceWithAds);
MediaSource[] textSourceArray = mediaSourceList.toArray(
new MediaSource[mediaSourceList.size()]
);
@@ -402,6 +422,19 @@ class ReactExoplayerView extends FrameLayout implements
}, 1);
}
+ // AdsMediaSource.MediaSourceFactory implementation.
+
+ @Override
+ public MediaSource createMediaSource(Uri uri) {
+ return buildMediaSource(uri, extension);
+ }
+
+ @Override
+ public int[] getSupportedTypes() {
+ // IMA does not support Smooth Streaming ads.
+ return new int[] {C.TYPE_DASH, C.TYPE_HLS, C.TYPE_OTHER};
+ }
+
private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension
: uri.getLastPathSegment());
@@ -473,6 +506,7 @@ class ReactExoplayerView extends FrameLayout implements
trackSelector = null;
player = null;
}
+ adsLoader.release();
progressHandler.removeMessages(SHOW_PROGRESS);
themedReactContext.removeLifecycleEventListener(this);
audioBecomingNoisyReceiver.removeListener();
@@ -914,6 +948,11 @@ class ReactExoplayerView extends FrameLayout implements
mReportBandwidth = reportBandwidth;
}
+ public void setAdTagUrl(final Uri uri) {
+ adTagUrl = uri;
+ adsLoader = new ImaAdsLoader(this.themedReactContext, adTagUrl);
+ }
+
public void setRawSrc(final Uri uri, final String extension) {
if (uri != null) {
boolean isOriginalSourceNull = srcUri == null;
diff --git a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java
index c7c96346..b793a882 100644
--- a/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java
+++ b/android-exoplayer/src/main/java/com/brentvatne/exoplayer/ReactExoplayerViewManager.java
@@ -25,6 +25,7 @@ public class ReactExoplayerViewManager extends ViewGroupManager
diff --git a/examples/basic/index.ios.js b/examples/basic/index.ios.js
index 1bc0ac47..ed2675f6 100644
--- a/examples/basic/index.ios.js
+++ b/examples/basic/index.ios.js
@@ -15,6 +15,11 @@ import {
import Video,{FilterType} from 'react-native-video';
+const adTagUrl = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/"
++ "ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp"
++ "&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite"
++ "%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=";
+
const filterTypes = [
FilterType.NONE,
FilterType.INVERT,
@@ -266,6 +271,7 @@ class VideoPlayer extends Component {
controls={this.state.controls}
filter={this.state.filter}
filterEnabled={this.state.filterEnabled}
+ adTagUrl={adTagUrl}
/>
diff --git a/examples/basic/ios/Podfile b/examples/basic/ios/Podfile
new file mode 100644
index 00000000..0b90640f
--- /dev/null
+++ b/examples/basic/ios/Podfile
@@ -0,0 +1,48 @@
+# Uncomment the next line to define a global platform for your project
+platform :ios, '9.0'
+
+target 'VideoPlayer' do
+ # Comment the next line if you don't want to use dynamic frameworks
+ use_frameworks!
+ pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
+ pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
+ pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
+ pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
+ pod 'React', :path => '../node_modules/react-native/'
+ pod 'React-Core', :path => '../node_modules/react-native/'
+ pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
+ pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
+ pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
+ pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
+ pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
+ pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
+ pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
+ pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
+ pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
+ pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
+ pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
+ pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
+
+ pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
+ pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
+ pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
+ pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
+ pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
+ pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
+ pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
+
+ pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
+ pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
+ pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
+
+ # Pods for VideoPlayer
+ pod 'react-native-video', :path => '../node_modules/react-native-video'
+end
+
+target 'VideoPlayer-tvOS' do
+ # Comment the next line if you don't want to use dynamic frameworks
+ use_frameworks!
+
+ # Pods for VideoPlayer-tvOS
+
+end
diff --git a/examples/basic/package.json b/examples/basic/package.json
index 057dcac7..83a991ac 100644
--- a/examples/basic/package.json
+++ b/examples/basic/package.json
@@ -10,7 +10,7 @@
},
"dependencies": {
"react": "16.9.0",
- "react-native": "0.60.5",
+ "react-native": "0.61.5",
"react-native-video": "file:../.."
},
"devDependencies": {
diff --git a/ios/Video/RCTVideo.h b/ios/Video/RCTVideo.h
index 26d436c2..bf9eac1f 100644
--- a/ios/Video/RCTVideo.h
+++ b/ios/Video/RCTVideo.h
@@ -5,6 +5,7 @@
#import "RCTVideoPlayerViewControllerDelegate.h"
#import
#import
+@import GoogleInteractiveMediaAds;
#if __has_include()
#import
@@ -14,11 +15,11 @@
@class RCTEventDispatcher;
#if __has_include()
-@interface RCTVideo : UIView
+@interface RCTVideo : UIView
#elif TARGET_OS_TV
@interface RCTVideo : UIView
#else
-@interface RCTVideo : UIView
+@interface RCTVideo : UIView
#endif
@property (nonatomic, copy) RCTDirectEventBlock onVideoLoadStart;
@@ -42,6 +43,12 @@
@property (nonatomic, copy) RCTDirectEventBlock onVideoExternalPlaybackChange;
@property (nonatomic, copy) RCTDirectEventBlock onPictureInPictureStatusChanged;
@property (nonatomic, copy) RCTDirectEventBlock onRestoreUserInterfaceForPictureInPictureStop;
+/// Playhead used by the SDK to track content video progress and insert mid-rolls.
+@property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead;
+/// Entry point for the SDK. Used to make ad requests.
+@property(nonatomic, strong) IMAAdsLoader *adsLoader;
+/// Main point of interaction with the SDK. Created by the SDK as the result of an ad request.
+@property(nonatomic, strong) IMAAdsManager *adsManager;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
diff --git a/ios/Video/RCTVideo.m b/ios/Video/RCTVideo.m
index 113d9f23..46ab23d0 100644
--- a/ios/Video/RCTVideo.m
+++ b/ios/Video/RCTVideo.m
@@ -39,6 +39,7 @@ static int const RCTVideoUnset = -1;
BOOL _playbackRateObserverRegistered;
BOOL _isExternalPlaybackActiveObserverRegistered;
BOOL _videoLoadStarted;
+ BOOL _isRequestAds;
bool _pendingSeek;
float _pendingSeekTime;
@@ -73,6 +74,7 @@ static int const RCTVideoUnset = -1;
NSString * _fullscreenOrientation;
BOOL _fullscreenPlayerPresented;
NSString *_filterName;
+ NSString * _adTagUrl;
BOOL _filterEnabled;
UIViewController * _presentingViewController;
#if __has_include()
@@ -107,6 +109,7 @@ static int const RCTVideoUnset = -1;
_allowsExternalPlayback = YES;
_playWhenInactive = false;
_pictureInPicture = false;
+ _isRequestAds = false;
_ignoreSilentSwitch = @"inherit"; // inherit, ignore, obey
#if TARGET_OS_IOS
_restoreUserInterfaceForPIPStopCompletionHandler = NULL;
@@ -144,6 +147,8 @@ static int const RCTVideoUnset = -1;
viewController.showsPlaybackControls = YES;
viewController.rctDelegate = self;
viewController.preferredOrientation = _fullscreenOrientation;
+ self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:player];
+ [self setupAdsLoader];
viewController.view.frame = self.bounds;
viewController.player = player;
@@ -267,8 +272,12 @@ static int const RCTVideoUnset = -1;
const Float64 currentTimeSecs = CMTimeGetSeconds(currentTime);
[[NSNotificationCenter defaultCenter] postNotificationName:@"RCTVideo_progress" object:nil userInfo:@{@"progress": [NSNumber numberWithDouble: currentTimeSecs / duration]}];
-
+
if( currentTimeSecs >= 0 && self.onVideoProgress) {
+ if(!_isRequestAds && !_paused) {
+ [self requestAds];
+ _isRequestAds = true;
+ }
self.onVideoProgress(@{
@"currentTime": [NSNumber numberWithFloat:CMTimeGetSeconds(currentTime)],
@"playableDuration": [self calculatePlayableDuration],
@@ -659,7 +668,6 @@ static int const RCTVideoUnset = -1;
@"target": self.reactTag});
}
_videoLoadStarted = NO;
-
[self attachListeners];
[self applyModifiers];
} else if (_playerItem.status == AVPlayerItemStatusFailed && self.onVideoError) {
@@ -719,6 +727,74 @@ static int const RCTVideoUnset = -1;
}
}
+- (void)setupAdsLoader {
+ // Re-use this IMAAdsLoader instance for the entire lifecycle of your app.
+ self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
+ // NOTE: This line will cause a warning until the next step, "Get the Ads Manager".
+ self.adsLoader.delegate = self;
+}
+
+- (void)requestAds {
+ // Create an ad display container for ad rendering.
+ IMAAdDisplayContainer *adDisplayContainer =
+ [[IMAAdDisplayContainer alloc] initWithAdContainer:self companionSlots:nil];
+ // Create an ad request with our ad tag, display container, and optional user context.
+ IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:_adTagUrl
+ adDisplayContainer:adDisplayContainer
+ contentPlayhead:self.contentPlayhead
+ userContext:nil];
+ [self.adsLoader requestAdsWithRequest:request];
+}
+
+#pragma mark AdsLoader Delegates
+
+- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
+ // Grab the instance of the IMAAdsManager and set ourselves as the delegate.
+ self.adsManager = adsLoadedData.adsManager;
+
+ // NOTE: This line will cause a warning until the next step, "Display Ads".
+ self.adsManager.delegate = self;
+
+ // Create ads rendering settings and tell the SDK to use the in-app browser.
+ IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init];
+ adsRenderingSettings.webOpenerPresentingController = _playerViewController;
+
+ // Initialize the ads manager.
+ [self.adsManager initializeWithAdsRenderingSettings:adsRenderingSettings];
+}
+
+- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
+ // Something went wrong loading ads. Log the error and play the content.
+ NSLog(@"Error loading ads: %@", adErrorData.adError.message);
+ [_player play];
+}
+
+#pragma mark AdsManager Delegates
+
+- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
+ if (event.type == kIMAAdEvent_LOADED) {
+ // When the SDK notifies us that ads have been loaded, play them.
+ [adsManager start];
+ }
+}
+
+- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
+ // Something went wrong with the ads manager after ads were loaded. Log the error and play the
+ // content.
+ NSLog(@"AdsManager error: %@", error.message);
+ [_player play];
+}
+
+- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
+ // The SDK is going to play ads, so pause the content.
+ [_player pause];
+}
+
+- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
+ // The SDK is done playing ads (at least for now), so resume the content.
+ [_player play];
+}
+
- (void)attachListeners
{
// listen for end of file
@@ -769,6 +845,9 @@ static int const RCTVideoUnset = -1;
- (void)playerItemDidReachEnd:(NSNotification *)notification
{
+ if (notification.object == _player.currentItem) {
+ [self.adsLoader contentComplete];
+ }
if(self.onVideoEnd) {
self.onVideoEnd(@{@"target": self.reactTag});
}
@@ -868,7 +947,7 @@ static int const RCTVideoUnset = -1;
} else if([_ignoreSilentSwitch isEqualToString:@"obey"]) {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
}
-
+
if (@available(iOS 10.0, *) && !_automaticallyWaitsToMinimizeStalling) {
[_player playImmediatelyAtRate:_rate];
} else {
@@ -1434,6 +1513,10 @@ static int const RCTVideoUnset = -1;
_filterEnabled = filterEnabled;
}
+- (void)setAdTagUrl:(NSString *)adTagUrl {
+ _adTagUrl = adTagUrl;
+}
+
#pragma mark - React View Management
- (void)insertReactSubview:(UIView *)view atIndex:(NSInteger)atIndex
diff --git a/ios/Video/RCTVideoManager.m b/ios/Video/RCTVideoManager.m
index 7233646f..a817ec8d 100644
--- a/ios/Video/RCTVideoManager.m
+++ b/ios/Video/RCTVideoManager.m
@@ -19,6 +19,7 @@ RCT_EXPORT_MODULE();
}
RCT_EXPORT_VIEW_PROPERTY(src, NSDictionary);
+RCT_EXPORT_VIEW_PROPERTY(adTagUrl, NSString);
RCT_EXPORT_VIEW_PROPERTY(maxBitRate, float);
RCT_EXPORT_VIEW_PROPERTY(resizeMode, NSString);
RCT_EXPORT_VIEW_PROPERTY(repeat, BOOL);
diff --git a/react-native-video.podspec b/react-native-video.podspec
index 98ba5537..6a522748 100644
--- a/react-native-video.podspec
+++ b/react-native-video.podspec
@@ -12,10 +12,12 @@ Pod::Spec.new do |s|
s.homepage = 'https://github.com/react-native-community/react-native-video'
s.source = { :git => "https://github.com/react-native-community/react-native-video.git", :tag => "#{s.version}" }
- s.ios.deployment_target = "8.0"
+ s.ios.deployment_target = "9.0"
s.tvos.deployment_target = "9.0"
s.subspec "Video" do |ss|
+ ss.dependency "GoogleAds-IMA-iOS-SDK", "~> 3.9"
+
ss.source_files = "ios/Video/*.{h,m}"
s.static_framework = true
end
@@ -29,7 +31,6 @@ Pod::Spec.new do |s|
s.static_framework = true
end
- s.dependency "React"
-
+ s.dependency 'React'
s.default_subspec = "Video"
end