feat: add onAdError event listener (#3381)
* feat: add onAdError event listener * feat: remove onAdError event listener and use already existing * feat: add ERROR event to docs
This commit is contained in:
parent
4d9334b477
commit
596c02d2b3
@ -54,6 +54,10 @@ public class ImaAdsLoader implements AdsLoader {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setAdErrorListener(Object ignoredReactExoplayerView) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public ImaAdsLoader build() {
|
public ImaAdsLoader build() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import com.facebook.react.bridge.ReactContext;
|
|||||||
import com.facebook.react.bridge.WritableArray;
|
import com.facebook.react.bridge.WritableArray;
|
||||||
import com.facebook.react.bridge.WritableMap;
|
import com.facebook.react.bridge.WritableMap;
|
||||||
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
import com.facebook.react.uimanager.events.RCTEventEmitter;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdError;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
@ -434,6 +435,19 @@ public class VideoEventEmitter {
|
|||||||
receiveEvent(EVENT_ON_RECEIVE_AD_EVENT, map);
|
receiveEvent(EVENT_ON_RECEIVE_AD_EVENT, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void receiveAdErrorEvent(AdError error) {
|
||||||
|
WritableMap map = Arguments.createMap();
|
||||||
|
map.putString("event", "ERROR");
|
||||||
|
|
||||||
|
WritableMap dataMap = Arguments.createMap();
|
||||||
|
dataMap.putString("message", error.getMessage());
|
||||||
|
dataMap.putString("code", String.valueOf(error.getErrorCode()));
|
||||||
|
dataMap.putString("type", String.valueOf(error.getErrorType()));
|
||||||
|
map.putMap("data", dataMap);
|
||||||
|
|
||||||
|
receiveEvent(EVENT_ON_RECEIVE_AD_EVENT, map);
|
||||||
|
}
|
||||||
|
|
||||||
private void receiveEvent(@VideoEvents String type, WritableMap event) {
|
private void receiveEvent(@VideoEvents String type, WritableMap event) {
|
||||||
eventEmitter.receiveEvent(viewId, type, event);
|
eventEmitter.receiveEvent(viewId, type, event);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,7 @@ import com.facebook.react.bridge.ReadableMap;
|
|||||||
import com.facebook.react.bridge.UiThreadUtil;
|
import com.facebook.react.bridge.UiThreadUtil;
|
||||||
import com.facebook.react.uimanager.ThemedReactContext;
|
import com.facebook.react.uimanager.ThemedReactContext;
|
||||||
import com.google.ads.interactivemedia.v3.api.AdEvent;
|
import com.google.ads.interactivemedia.v3.api.AdEvent;
|
||||||
|
import com.google.ads.interactivemedia.v3.api.AdErrorEvent;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import java.net.CookieHandler;
|
import java.net.CookieHandler;
|
||||||
@ -132,7 +133,8 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
BandwidthMeter.EventListener,
|
BandwidthMeter.EventListener,
|
||||||
BecomingNoisyListener,
|
BecomingNoisyListener,
|
||||||
DrmSessionEventListener,
|
DrmSessionEventListener,
|
||||||
AdEvent.AdEventListener {
|
AdEvent.AdEventListener,
|
||||||
|
AdErrorEvent.AdErrorListener {
|
||||||
|
|
||||||
public static final double DEFAULT_MAX_HEAP_ALLOCATION_PERCENT = 1;
|
public static final double DEFAULT_MAX_HEAP_ALLOCATION_PERCENT = 1;
|
||||||
public static final double DEFAULT_MIN_BACK_BUFFER_MEMORY_RESERVE = 0;
|
public static final double DEFAULT_MIN_BACK_BUFFER_MEMORY_RESERVE = 0;
|
||||||
@ -621,8 +623,10 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
|
.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
|
||||||
|
|
||||||
// Create an AdsLoader.
|
// Create an AdsLoader.
|
||||||
adsLoader = new ImaAdsLoader.Builder(themedReactContext)
|
adsLoader = new ImaAdsLoader
|
||||||
|
.Builder(themedReactContext)
|
||||||
.setAdEventListener(this)
|
.setAdEventListener(this)
|
||||||
|
.setAdErrorListener(this)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory);
|
DefaultMediaSourceFactory mediaSourceFactory = new DefaultMediaSourceFactory(mediaDataSourceFactory);
|
||||||
@ -2103,4 +2107,9 @@ public class ReactExoplayerView extends FrameLayout implements
|
|||||||
eventEmitter.receiveAdEvent(adEvent.getType().name());
|
eventEmitter.receiveAdEvent(adEvent.getType().name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdError(AdErrorEvent adErrorEvent) {
|
||||||
|
eventEmitter.receiveAdErrorEvent(adErrorEvent.getError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.google.ads.interactivemedia.v3.api;
|
||||||
|
|
||||||
|
import androidx.annotation.InspectableProperty;
|
||||||
|
|
||||||
|
public abstract class AdError {
|
||||||
|
public abstract InspectableProperty getErrorCode();
|
||||||
|
public abstract InspectableProperty getErrorCodeNumber();
|
||||||
|
public abstract InspectableProperty getErrorType();
|
||||||
|
public abstract String getMessage();
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.google.ads.interactivemedia.v3.api;
|
||||||
|
|
||||||
|
public abstract class AdErrorEvent {
|
||||||
|
public abstract AdError getError();
|
||||||
|
|
||||||
|
public interface AdErrorListener {
|
||||||
|
public void onAdError(AdErrorEvent adErrorEvent);
|
||||||
|
}
|
||||||
|
}
|
@ -370,6 +370,7 @@ Enum `AdEvent` possible values for [Android](https://developers.google.com/inter
|
|||||||
| `CONTENT_RESUME_REQUESTED` | Android | Fires when content should be resumed. This usually happens when an ad finishes or collapses. |
|
| `CONTENT_RESUME_REQUESTED` | Android | Fires when content should be resumed. This usually happens when an ad finishes or collapses. |
|
||||||
| `CUEPOINTS_CHANGED` | iOS | Cuepoints changed for VOD stream (only used for dynamic ad insertion). |
|
| `CUEPOINTS_CHANGED` | iOS | Cuepoints changed for VOD stream (only used for dynamic ad insertion). |
|
||||||
| `DURATION_CHANGE` | Android | Fires when the ad's duration changes. |
|
| `DURATION_CHANGE` | Android | Fires when the ad's duration changes. |
|
||||||
|
| `ERROR` | Android, iOS | Fires when an error occurred while loading the ad and prevent it from playing. |
|
||||||
| `FIRST_QUARTILE` | Android, iOS | Fires when the ad playhead crosses first quartile. |
|
| `FIRST_QUARTILE` | Android, iOS | Fires when the ad playhead crosses first quartile. |
|
||||||
| `IMPRESSION` | Android | Fires when the impression URL has been pinged. |
|
| `IMPRESSION` | Android | Fires when the impression URL has been pinged. |
|
||||||
| `INTERACTION` | Android | Fires when an ad triggers the interaction callback. Ad interactions contain an interaction ID string in the ad data. |
|
| `INTERACTION` | Android | Fires when an ad triggers the interaction callback. Ad interactions contain an interaction ID string in the ad data. |
|
||||||
|
@ -118,8 +118,22 @@ class RCTIMAAdsManager: NSObject, IMAAdsLoaderDelegate, IMAAdsManagerDelegate, I
|
|||||||
print("AdsManager error: " + error.message!)
|
print("AdsManager error: " + error.message!)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard let _video = _video else {return}
|
||||||
|
|
||||||
|
if _video.onReceiveAdEvent != nil {
|
||||||
|
_video.onReceiveAdEvent?([
|
||||||
|
"event": "ERROR",
|
||||||
|
"data": [
|
||||||
|
"message": error.message ?? "",
|
||||||
|
"code": error.code,
|
||||||
|
"type": error.type,
|
||||||
|
],
|
||||||
|
"target": _video.reactTag!
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
// Fall back to playing content
|
// Fall back to playing content
|
||||||
_video?.setPaused(false)
|
_video.setPaused(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
|
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
|
||||||
|
@ -146,7 +146,7 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
name: UIApplication.willResignActiveNotification,
|
name: UIApplication.willResignActiveNotification,
|
||||||
object: nil
|
object: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
NotificationCenter.default.addObserver(
|
||||||
self,
|
self,
|
||||||
selector: #selector(applicationDidBecomeActive(notification:)),
|
selector: #selector(applicationDidBecomeActive(notification:)),
|
||||||
@ -1346,11 +1346,11 @@ class RCTVideo: UIView, RCTVideoPlayerViewControllerDelegate, RCTPlayerObserverH
|
|||||||
_playerObserver.removePlayerTimeObserver()
|
_playerObserver.removePlayerTimeObserver()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func handleAVPlayerAccess(notification:NSNotification!) {
|
@objc func handleAVPlayerAccess(notification:NSNotification!) {
|
||||||
let accessLog:AVPlayerItemAccessLog! = (notification.object as! AVPlayerItem).accessLog()
|
let accessLog:AVPlayerItemAccessLog! = (notification.object as! AVPlayerItem).accessLog()
|
||||||
let lastEvent:AVPlayerItemAccessLogEvent! = accessLog.events.last
|
let lastEvent:AVPlayerItemAccessLogEvent! = accessLog.events.last
|
||||||
|
|
||||||
onVideoBandwidthUpdate?(["bitrate": lastEvent.observedBitrate, "target": reactTag])
|
onVideoBandwidthUpdate?(["bitrate": lastEvent.observedBitrate, "target": reactTag])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import NativeVideoComponent, {
|
|||||||
} from './VideoNativeComponent';
|
} from './VideoNativeComponent';
|
||||||
|
|
||||||
import type {StyleProp, ImageStyle, NativeSyntheticEvent} from 'react-native';
|
import type {StyleProp, ImageStyle, NativeSyntheticEvent} from 'react-native';
|
||||||
import type {ReactVideoProps} from './types/video';
|
|
||||||
import {getReactTag, resolveAssetSourceForVideo} from './utils';
|
import {getReactTag, resolveAssetSourceForVideo} from './utils';
|
||||||
import {VideoManager} from './VideoNativeComponent';
|
import {VideoManager} from './VideoNativeComponent';
|
||||||
import type {
|
import type {
|
||||||
@ -35,7 +34,8 @@ import type {
|
|||||||
OnVideoAspectRatioData,
|
OnVideoAspectRatioData,
|
||||||
OnVideoErrorData,
|
OnVideoErrorData,
|
||||||
OnVideoTracksData,
|
OnVideoTracksData,
|
||||||
} from './types/events';
|
ReactVideoProps,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
export type VideoSaveData = {
|
export type VideoSaveData = {
|
||||||
uri: string;
|
uri: string;
|
||||||
|
@ -63,6 +63,10 @@ export enum AdEvent {
|
|||||||
* Android only: Fires when the ad's duration changes.
|
* Android only: Fires when the ad's duration changes.
|
||||||
*/
|
*/
|
||||||
DURATION_CHANGE = 'DURATION_CHANGE',
|
DURATION_CHANGE = 'DURATION_CHANGE',
|
||||||
|
/**
|
||||||
|
* Fires when an error is encountered and the ad can't be played.
|
||||||
|
*/
|
||||||
|
ERROR = 'ERROR',
|
||||||
/**
|
/**
|
||||||
* Fires when the ad playhead crosses first quartile.
|
* Fires when the ad playhead crosses first quartile.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user