Skip to content

Commit 0d00af7

Browse files
committed
disable autoplay, rename adStarted to onAdsLoaded, ensure ads are preloading
1 parent 85f88ce commit 0d00af7

9 files changed

+70
-44
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ import { BrightcoveIMAPlayer } from "react-native-brightcove-ima-player";
7373
| adVideoLoadTimeout | number | Set the amount of milliseconds for video to load. Default is `3000` | |
7474
| playbackRate | number | Set playback speed scale. Default is `1` | |
7575
| disableDefaultControl | boolean | Disable default player control. Set `true` when you implement own video controller. | |
76-
| adStarted | Function | Indicates the IMA ad has started | |
76+
| onAdsLoaded | Function | Indicates the IMA ads manager has loaded | |
7777
| onReady | Function | Indicates the video can be played back | |
7878
| onPlay | Function | Indicates the video playback starts | |
7979
| onPause | Function | Indicates the video is paused | |

android/constants.gradle

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
project.ext {
2-
BRIGHTCOVE_VERSION = '6.18.6'
3-
PLAY_SERVICES_VERSION = '20.3.0'
4-
GOOGLE_IMA_SDK_VERSION = '3.21.1'
5-
ANDROIDX_LEGACY_SUPPORT_V4 = '1.0.0'
6-
ANDROIDX_MEDIA = '1.1.0'
2+
BRIGHTCOVE_VERSION = '6.18.6'
3+
PLAY_SERVICES_VERSION = '20.3.0'
4+
GOOGLE_IMA_SDK_VERSION = '3.21.1'
5+
ANDROIDX_LEGACY_SUPPORT_V4 = '1.0.0'
6+
ANDROIDX_MEDIA = '1.1.0'
77
}

android/src/main/java/com/matejdr/brightcoveimaplayer/BrightcoveIMAPlayerView.java

+24-12
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.google.ads.interactivemedia.v3.api.AdsRequest;
3939
import com.google.ads.interactivemedia.v3.api.ImaSdkFactory;
4040
import com.google.ads.interactivemedia.v3.api.ImaSdkSettings;
41+
import com.google.ads.interactivemedia.v3.api.AdsRenderingSettings;
4142
import com.google.android.exoplayer2.ExoPlayer;
4243
import com.google.android.exoplayer2.PlaybackParameters;
4344
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
@@ -60,7 +61,7 @@ public class BrightcoveIMAPlayerView extends RelativeLayout implements Lifecycle
6061
private String policyKey;
6162
private String accountId;
6263
private String videoId;
63-
private boolean autoPlay = true;
64+
private boolean autoPlay = false;
6465
private boolean playing = false;
6566
private boolean adsPlaying = false;
6667
private boolean inViewPort = true;
@@ -107,14 +108,6 @@ private void setup() {
107108
// Use a procedural abstraction to setup the Google IMA SDK via the plugin.
108109
setupGoogleIMA();
109110

110-
eventEmitter.on(EventType.AD_STARTED, new EventListener() {
111-
@Override
112-
public void processEvent(Event e) {
113-
WritableMap event = Arguments.createMap();
114-
ReactContext reactContext = (ReactContext) BrightcoveIMAPlayerView.this.getContext();
115-
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(BrightcoveIMAPlayerView.this.getId(), BrightcoveIMAPlayerViewManager.AD_STARTED, event);
116-
}
117-
});
118111
eventEmitter.on(EventType.VIDEO_SIZE_KNOWN, new EventListener() {
119112
@Override
120113
public void processEvent(Event e) {
@@ -392,9 +385,9 @@ public void onError(@NonNull List<CatalogError> errors) {
392385
private void playVideo(Video video) {
393386
BrightcoveIMAPlayerView.this.brightcoveVideoView.clear();
394387
BrightcoveIMAPlayerView.this.brightcoveVideoView.add(video);
395-
if (BrightcoveIMAPlayerView.this.autoPlay) {
396-
BrightcoveIMAPlayerView.this.brightcoveVideoView.start();
397-
}
388+
// if (BrightcoveIMAPlayerView.this.autoPlay) {
389+
// BrightcoveIMAPlayerView.this.brightcoveVideoView.start();
390+
// }
398391
}
399392

400393
private void fixVideoLayout() {
@@ -427,6 +420,12 @@ private void setupAdMarkers(BaseVideoView videoView) {
427420
int markerTime = cuepoint < 0 ? brightcoveSeekBar.getMax() : (int) (cuepoint * DateUtils.SECOND_IN_MILLIS);
428421
mediaController.getBrightcoveSeekBar().addMarker(markerTime);
429422
}
423+
424+
// fire off ADS_LOADED event
425+
WritableMap adEvent = Arguments.createMap();
426+
ReactContext reactContext = (ReactContext) BrightcoveIMAPlayerView.this.getContext();
427+
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(BrightcoveIMAPlayerView.this.getId(), BrightcoveIMAPlayerViewManager.EVENT_ADS_LOADED, adEvent);
428+
430429
});
431430
videoView.setMediaController(mediaController);
432431
}
@@ -452,6 +451,13 @@ private void setupGoogleIMA() {
452451
eventEmitter.on(EventType.AD_BREAK_COMPLETED, event -> {
453452
adsPlaying = false;
454453
});
454+
// checks ad progress and pauses if out of view
455+
// fixes the elusive play then scroll away before pre-roll starts bug
456+
eventEmitter.on(EventType.AD_PROGRESS, event -> {
457+
if (!inViewPort) {
458+
this.pause();
459+
}
460+
});
455461

456462
// Set up a listener for initializing AdsRequests.
457463
eventEmitter.on(GoogleIMAEventType.ADS_REQUEST_FOR_VIDEO, event -> {
@@ -477,11 +483,17 @@ private void setupGoogleIMA() {
477483
imaSdkSettings.setPpid(settings.getString("publisherProvidedID"));
478484
}
479485

486+
AdsRenderingSettings adsRenderingSettings =
487+
ImaSdkFactory.getInstance().createAdsRenderingSettings();
488+
// preload ads
489+
adsRenderingSettings.setEnablePreloading(true);
490+
480491
// Create the Brightcove IMA Plugin and pass in the event
481492
// emitter so that the plugin can integrate with the SDK.
482493
googleIMAComponent = new GoogleIMAComponent.Builder(this.brightcoveVideoView, eventEmitter)
483494
.setUseAdRules(true)
484495
.setLoadVideoTimeout(adVideoLoadTimeout)
496+
.setAdsRenderingSettings(adsRenderingSettings)
485497
.setImaSdkSettings(imaSdkSettings)
486498
.build();
487499
}

android/src/main/java/com/matejdr/brightcoveimaplayer/BrightcoveIMAPlayerViewManager.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public class BrightcoveIMAPlayerViewManager extends SimpleViewManager<Brightcove
2323
public static final int COMMAND_STOP_PLAYBACK = 4;
2424
public static final int COMMAND_TOGGLE_FULLSCREEN = 5;
2525
public static final int COMMAND_TOGGLE_IN_VIEW_PORT = 6;
26-
public static final String AD_STARTED = "ad_started";
26+
public static final String EVENT_ADS_LOADED = "ads_loaded";
2727
public static final String EVENT_READY = "ready";
2828
public static final String EVENT_PLAY = "play";
2929
public static final String EVENT_PAUSE = "pause";
@@ -167,7 +167,7 @@ public void receiveCommand(BrightcoveIMAPlayerView view, int commandType, @Nulla
167167
public @Nullable
168168
Map<String, Object> getExportedCustomDirectEventTypeConstants() {
169169
Map<String, Object> map = new HashMap<>();
170-
map.put(AD_STARTED, (Object) MapBuilder.of("registrationName", "onAdStarted"));
170+
map.put(EVENT_ADS_LOADED, (Object) MapBuilder.of("registrationName", "onAdsLoaded"));
171171
map.put(EVENT_READY, (Object) MapBuilder.of("registrationName", "onReady"));
172172
map.put(EVENT_PLAY, (Object) MapBuilder.of("registrationName", "onPlay"));
173173
map.put(EVENT_PAUSE, (Object) MapBuilder.of("registrationName", "onPause"));

ios/BrightcoveIMAPlayerView.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
@property (nonatomic, copy) NSString *videoId;
3939
@property (nonatomic, copy) NSString *accountId;
4040
@property (nonatomic, copy) NSString *policyKey;
41-
@property (nonatomic, copy) RCTDirectEventBlock onAdStarted;
41+
@property (nonatomic, copy) RCTDirectEventBlock onAdsLoaded;
4242
@property (nonatomic, copy) RCTDirectEventBlock onReady;
4343
@property (nonatomic, copy) RCTDirectEventBlock onPlay;
4444
@property (nonatomic, copy) RCTDirectEventBlock onPause;

ios/BrightcoveIMAPlayerView.m

+34-20
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,14 @@ - (void)setupWithSettings:(NSDictionary*)settings {
6060
imaSettings.ppid = kViewControllerIMAPublisherID;
6161
}
6262
imaSettings.language = kViewControllerIMALanguage;
63+
imaSettings.autoPlayAdBreaks = NO;
6364

6465
IMAAdsRenderingSettings *renderSettings = [[IMAAdsRenderingSettings alloc] init];
6566
renderSettings.linkOpenerPresentingController = RCTPresentedViewController();
6667
renderSettings.linkOpenerDelegate = self;
68+
renderSettings.enablePreloading = YES; // default is yes anyway
6769

70+
// Timeout (in seconds) when loading a video ad media file. If loading takes longer than this timeout, the ad playback is canceled and the next ad in the pod plays, if available. Use -1 for the default of 8 seconds.
6871
if (_targetAdVideoLoadTimeout == 0) {
6972
renderSettings.loadVideoTimeout = 3.;
7073
} else {
@@ -96,7 +99,7 @@ - (void)setupWithSettings:(NSDictionary*)settings {
9699
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
97100

98101
BOOL autoAdvance = [settings objectForKey:@"autoAdvance"] != nil ? [[settings objectForKey:@"autoAdvance"] boolValue] : NO;
99-
BOOL autoPlay = [settings objectForKey:@"autoPlay"] != nil ? [[settings objectForKey:@"autoPlay"] boolValue] : YES;
102+
BOOL autoPlay = NO; //[settings objectForKey:@"autoPlay"] != nil ? [[settings objectForKey:@"autoPlay"] boolValue] : YES;
100103
BOOL allowsExternalPlayback = [settings objectForKey:@"allowsExternalPlayback"] != nil ? [[settings objectForKey:@"allowsExternalPlayback"] boolValue] : YES;
101104

102105
_playbackController.autoAdvance = autoAdvance;
@@ -238,6 +241,8 @@ -(void) toggleInViewPort:(BOOL)inViewPort {
238241
_inViewPort = YES;
239242
} else {
240243
_inViewPort = NO;
244+
[self.playbackController pauseAd];
245+
[self.playbackController pause];
241246
}
242247
}
243248

@@ -254,8 +259,9 @@ -(void) play {
254259
if (self.playbackController) {
255260
if (_adsPlaying) {
256261
[self.playbackController resumeAd];
257-
[self.playbackController pause];
262+
//[self.playbackController pause];
258263
} else {
264+
// if ad hasnt started, this will kick it off
259265
[self.playbackController play];
260266
}
261267
}
@@ -291,6 +297,8 @@ - (void)handleAppStateDidChange:(NSNotification *)notification
291297
#pragma mark - BCOVPlaybackControllerBasicDelegate methods
292298

293299
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didReceiveLifecycleEvent:(BCOVPlaybackSessionLifecycleEvent *)lifecycleEvent {
300+
301+
// NSLog(@"BC - DEBUG eventType: %@", lifecycleEvent.eventType);
294302

295303
if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventPlaybackBufferEmpty ||
296304
lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventFail ||
@@ -333,20 +341,26 @@ - (void)playbackController:(id<BCOVPlaybackController>)controller playbackSessio
333341
self.onPause(@{});
334342
}
335343
} else if (lifecycleEvent.eventType == kBCOVIMALifecycleEventAdsLoaderLoaded) {
336-
if (self.onAdStarted) {
337-
self.onAdStarted(@{});
344+
if (self.onAdsLoaded) {
345+
self.onAdsLoaded(@{});
338346
}
339347
} else if (lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventAdProgress) {
340348
// catches scroll away before ads start bug
341349
if (!_inViewPort) {
342350
[self.playbackController pauseAd];
351+
[self.playbackController pause];
343352
}
344-
} else if (lifecycleEvent.eventType == kBCOVIMALifecycleEventAdsManagerDidReceiveAdEvent) {
353+
}
354+
355+
if (lifecycleEvent.eventType == kBCOVIMALifecycleEventAdsManagerDidReceiveAdEvent) {
345356
IMAAdEvent *adEvent = lifecycleEvent.properties[@"adEvent"];
357+
358+
// NSLog(@"BC - DEBUG adEvent: %ld %@", adEvent.type, adEvent.typeString);
346359

347360
switch (adEvent.type)
348361
{
349362
case kIMAAdEvent_LOADED:
363+
_adsPlaying = YES;
350364
break;
351365
case kIMAAdEvent_PAUSE:
352366
break;
@@ -417,35 +431,35 @@ -(void)playerView:(BCOVPUIPlayerView *)playerView didTransitionToScreenMode:(BCO
417431
#pragma mark - BCOVPlaybackControllerAdsDelegate methods
418432

419433
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didEnterAdSequence:(BCOVAdSequence *)adSequence {
420-
if (!_inViewPort && _adsPlaying) {
434+
if (!_inViewPort) {
421435
[self.playbackController pauseAd];
422436
}
423-
[self.playbackController pause];
437+
// [self.playbackController pause];
424438
}
425439

426440
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didExitAdSequence:(BCOVAdSequence *)adSequence {
427-
if (_inViewPort) {
428-
[self.playbackController play];
429-
}
441+
// if (_inViewPort) {
442+
// [self.playbackController play];
443+
// }
430444
}
431445

432446
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didEnterAd:(BCOVAd *)ad {
433-
if (!_inViewPort && _adsPlaying) {
434-
[self.playbackController pauseAd];
435-
}
436-
[self.playbackController pause];
447+
// if (!_inViewPort) {
448+
// [self.playbackController pauseAd];
449+
// }
450+
// [self.playbackController pause];
437451
}
438452

439453
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session didExitAd:(BCOVAd *)ad {
440-
if (_inViewPort) {
441-
[self.playbackController play];
442-
}
454+
// if (_inViewPort) {
455+
// [self.playbackController play];
456+
// }
443457
}
444458

445459
- (void)playbackController:(id<BCOVPlaybackController>)controller playbackSession:(id<BCOVPlaybackSession>)session ad:(BCOVAd *)ad didProgressTo:(NSTimeInterval)progress {
446-
if (_playing) {
447-
[self.playbackController pause];
448-
}
460+
// if (_playing) {
461+
// [self.playbackController pause];
462+
// }
449463
}
450464

451465
#pragma mark - IMAPlaybackSessionDelegate Methods

ios/BrightcoveIMAPlayerViewManager.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ - (dispatch_queue_t)methodQueue {
2727
RCT_EXPORT_VIEW_PROPERTY(bitRate, NSNumber);
2828
RCT_EXPORT_VIEW_PROPERTY(adVideoLoadTimeout, NSNumber);
2929
RCT_EXPORT_VIEW_PROPERTY(playbackRate, NSNumber);
30-
RCT_EXPORT_VIEW_PROPERTY(onAdStarted, RCTDirectEventBlock);
30+
RCT_EXPORT_VIEW_PROPERTY(onAdsLoaded, RCTDirectEventBlock);
3131
RCT_EXPORT_VIEW_PROPERTY(onReady, RCTDirectEventBlock);
3232
RCT_EXPORT_VIEW_PROPERTY(onPlay, RCTDirectEventBlock);
3333
RCT_EXPORT_VIEW_PROPERTY(onPause, RCTDirectEventBlock);

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-brightcove-ima-player",
3-
"version": "2.2.8",
3+
"version": "2.2.9",
44
"description": "React Native implementation of Brightcove Player native SDK",
55
"main": "lib/commonjs/index",
66
"module": "lib/module/index",

src/BrightcoveIMAPlayer.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type BrightcoveIMAPlayerProps = ViewProps & {
5454
*/
5555
adVideoLoadTimeout?: number;
5656
playbackRate?: number;
57-
onAdStarted?: (
57+
onAdsLoaded?: (
5858
event: NativeSyntheticEvent<TBrightcoveIMAPlayerEventBase>
5959
) => void;
6060
onReady?: (

0 commit comments

Comments
 (0)