react-native-theoplayer 3.2.1 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +3 -1
  3. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +2 -1
  4. package/android/src/main/java/com/theoplayer/ads/AdAdapter.kt +295 -4
  5. package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.kt +63 -15
  6. package/android/src/main/java/com/theoplayer/broadcast/DefaultEventDispatcher.kt +27 -0
  7. package/android/src/main/java/com/theoplayer/broadcast/EventAdapter.kt +23 -0
  8. package/android/src/main/java/com/theoplayer/broadcast/EventBroadcastAdapter.kt +15 -0
  9. package/android/src/main/java/com/theoplayer/broadcast/EventBroadcastModule.kt +36 -0
  10. package/ios/THEOplayerRCTBridge.m +10 -0
  11. package/ios/THEOplayerRCTTypeUtils.swift +17 -0
  12. package/ios/THEOplayerRCTView.swift +2 -0
  13. package/ios/ads/{THEOplayerRCTAdAggregator.swift → THEOplayerRCTAdAdapter.swift} +92 -20
  14. package/ios/ads/THEOplayerRCTAdEventAdapter.swift +27 -0
  15. package/ios/ads/THEOplayerRCTAdsAPI.swift +3 -3
  16. package/ios/ads/THEOplayerRCTAdsEventHandler.swift +9 -9
  17. package/ios/ads/THEOplayerRCTAdsNative.swift +159 -0
  18. package/ios/eventBroadcasting/THEOplayerRCTBroadcastEventHandler.swift +99 -0
  19. package/ios/eventBroadcasting/THEOplayerRCTEventBroadcastAPI.swift +33 -0
  20. package/lib/commonjs/api/barrel.js +42 -20
  21. package/lib/commonjs/api/barrel.js.map +1 -1
  22. package/lib/commonjs/api/broadcast/EventBroadcastAPI.js +6 -0
  23. package/lib/commonjs/api/broadcast/EventBroadcastAPI.js.map +1 -0
  24. package/lib/commonjs/api/broadcast/barrel.js +17 -0
  25. package/lib/commonjs/api/broadcast/barrel.js.map +1 -0
  26. package/lib/commonjs/api/player/THEOplayer.js.map +1 -1
  27. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js +9 -0
  28. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
  29. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js +5 -0
  30. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  31. package/lib/commonjs/internal/adapter/broadcast/EventBroadcastAdapter.js +24 -0
  32. package/lib/commonjs/internal/adapter/broadcast/EventBroadcastAdapter.js.map +1 -0
  33. package/lib/commonjs/internal/adapter/broadcast/EventBroadcastAdapter.web.js +44 -0
  34. package/lib/commonjs/internal/adapter/broadcast/EventBroadcastAdapter.web.js.map +1 -0
  35. package/lib/commonjs/internal/adapter/broadcast/web/DefaultWebEventDispatcher.js +72 -0
  36. package/lib/commonjs/internal/adapter/broadcast/web/DefaultWebEventDispatcher.js.map +1 -0
  37. package/lib/module/api/barrel.js +2 -0
  38. package/lib/module/api/barrel.js.map +1 -1
  39. package/lib/module/api/broadcast/EventBroadcastAPI.js +2 -0
  40. package/lib/module/api/broadcast/EventBroadcastAPI.js.map +1 -0
  41. package/lib/module/api/broadcast/barrel.js +2 -0
  42. package/lib/module/api/broadcast/barrel.js.map +1 -0
  43. package/lib/module/api/player/THEOplayer.js.map +1 -1
  44. package/lib/module/internal/adapter/THEOplayerAdapter.js +9 -0
  45. package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
  46. package/lib/module/internal/adapter/THEOplayerWebAdapter.js +5 -0
  47. package/lib/module/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  48. package/lib/module/internal/adapter/broadcast/EventBroadcastAdapter.js +17 -0
  49. package/lib/module/internal/adapter/broadcast/EventBroadcastAdapter.js.map +1 -0
  50. package/lib/module/internal/adapter/broadcast/EventBroadcastAdapter.web.js +37 -0
  51. package/lib/module/internal/adapter/broadcast/EventBroadcastAdapter.web.js.map +1 -0
  52. package/lib/module/internal/adapter/broadcast/web/DefaultWebEventDispatcher.js +63 -0
  53. package/lib/module/internal/adapter/broadcast/web/DefaultWebEventDispatcher.js.map +1 -0
  54. package/lib/typescript/api/barrel.d.ts +2 -0
  55. package/lib/typescript/api/broadcast/EventBroadcastAPI.d.ts +12 -0
  56. package/lib/typescript/api/broadcast/barrel.d.ts +1 -0
  57. package/lib/typescript/api/player/THEOplayer.d.ts +5 -0
  58. package/lib/typescript/internal/adapter/THEOplayerAdapter.d.ts +4 -3
  59. package/lib/typescript/internal/adapter/THEOplayerWebAdapter.d.ts +4 -2
  60. package/lib/typescript/internal/adapter/broadcast/EventBroadcastAdapter.d.ts +7 -0
  61. package/lib/typescript/internal/adapter/broadcast/EventBroadcastAdapter.web.d.ts +11 -0
  62. package/lib/typescript/internal/adapter/broadcast/web/DefaultWebEventDispatcher.d.ts +12 -0
  63. package/package.json +2 -2
  64. package/react-native-theoplayer.podspec +1 -1
  65. package/src/api/barrel.ts +2 -0
  66. package/src/api/broadcast/EventBroadcastAPI.ts +13 -0
  67. package/src/api/broadcast/barrel.ts +1 -0
  68. package/src/api/player/THEOplayer.ts +6 -0
  69. package/src/internal/adapter/THEOplayerAdapter.ts +10 -2
  70. package/src/internal/adapter/THEOplayerWebAdapter.ts +11 -5
  71. package/src/internal/adapter/broadcast/EventBroadcastAdapter.ts +20 -0
  72. package/src/internal/adapter/broadcast/EventBroadcastAdapter.web.ts +44 -0
  73. package/src/internal/adapter/broadcast/web/DefaultWebEventDispatcher.ts +66 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.1.0/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [3.3.0] - 23-12-11
9
+
10
+ ### Changed
11
+
12
+ - Extended event dispatching mechanism with broadcast functionality.
13
+
8
14
  ## [3.2.1] - 23-12-07
9
15
 
10
16
  ### Fixed
@@ -8,6 +8,7 @@ import com.theoplayer.ads.AdsModule
8
8
  import com.theoplayer.cache.CacheModule
9
9
  import com.theoplayer.drm.ContentProtectionModule
10
10
  import com.theoplayer.cast.CastModule
11
+ import com.theoplayer.broadcast.EventBroadcastModule
11
12
  import com.theoplayer.player.PlayerModule
12
13
 
13
14
  class ReactTHEOplayerPackage : ReactPackage {
@@ -17,7 +18,8 @@ class ReactTHEOplayerPackage : ReactPackage {
17
18
  AdsModule(reactContext),
18
19
  ContentProtectionModule(reactContext),
19
20
  CastModule(reactContext),
20
- CacheModule(reactContext)
21
+ CacheModule(reactContext),
22
+ EventBroadcastModule(reactContext)
21
23
  )
22
24
  }
23
25
 
@@ -11,6 +11,7 @@ import com.theoplayer.android.api.ads.wrapper.AdsApiWrapper
11
11
  import com.theoplayer.android.api.cast.Cast
12
12
  import com.theoplayer.android.api.error.THEOplayerException
13
13
  import com.theoplayer.android.api.player.Player
14
+ import com.theoplayer.broadcast.EventBroadcastAdapter
14
15
  import com.theoplayer.presentation.PresentationManager
15
16
  import com.theoplayer.source.SourceAdapter
16
17
 
@@ -22,7 +23,7 @@ class ReactTHEOplayerView(private val reactContext: ThemedReactContext) :
22
23
 
23
24
  private val eventEmitter: PlayerEventEmitter =
24
25
  PlayerEventEmitter(reactContext.reactApplicationContext, this)
25
-
26
+ val broadcast = EventBroadcastAdapter(this)
26
27
  var presentationManager: PresentationManager? = null
27
28
  var playerContext: ReactTHEOplayerContext? = null
28
29
  private var isInitialized: Boolean = false
@@ -1,12 +1,17 @@
1
1
  package com.theoplayer.ads
2
2
 
3
3
  import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.ReadableMap
4
5
  import com.facebook.react.bridge.WritableMap
5
6
  import com.facebook.react.bridge.WritableArray
7
+ import com.google.ads.interactivemedia.v3.api.AdPodInfo
8
+ import com.google.ads.interactivemedia.v3.api.UiElement
6
9
  import com.theoplayer.android.api.ads.Ad
7
10
  import com.theoplayer.android.api.ads.AdBreak
8
11
  import com.theoplayer.android.api.ads.CompanionAd
9
12
  import com.theoplayer.android.api.ads.GoogleImaAd
13
+ import com.theoplayer.android.api.ads.UniversalAdId
14
+ import com.theoplayer.android.api.event.ads.AdIntegrationKind
10
15
  import java.lang.Exception
11
16
 
12
17
  private const val PROP_AD_SYSTEM = "adSystem"
@@ -42,11 +47,13 @@ private const val PROP_COMPANION_RESOURCEURI = "resourceURI"
42
47
  private const val PROP_UNIVERSAL_AD_ID_REGISTRY = "adIdRegistry"
43
48
  private const val PROP_UNIVERSAL_AD_ID_VALUE = "adIdValue"
44
49
 
45
- object AdAdapter {
46
- fun fromAd(ad: Ad): WritableMap {
47
- return fromAd(ad, true)
48
- }
50
+ private const val INVALID_DOUBLE = -1.0
51
+ private const val INVALID_INT = -1
49
52
 
53
+ object AdAdapter {
54
+ /**
55
+ * Convert a list of native Ads to a ReactNative Ads.
56
+ */
50
57
  fun fromAds(ads: List<Ad>): WritableArray {
51
58
  val payload = Arguments.createArray()
52
59
  for (ad in ads) {
@@ -55,6 +62,16 @@ object AdAdapter {
55
62
  return payload
56
63
  }
57
64
 
65
+ /**
66
+ * Convert a native Ad to a ReactNative Ad.
67
+ */
68
+ fun fromAd(ad: Ad): WritableMap {
69
+ return fromAd(ad, true)
70
+ }
71
+
72
+ /**
73
+ * Convert a native Ad to a ReactNative Ad, optionally include its AdBreak.
74
+ */
58
75
  private fun fromAd(ad: Ad, includeAdBreak: Boolean): WritableMap {
59
76
  val adPayload = Arguments.createMap()
60
77
  adPayload.putString(
@@ -113,6 +130,9 @@ object AdAdapter {
113
130
  return adPayload
114
131
  }
115
132
 
133
+ /**
134
+ * Convert a native AdBreak to a ReactNative AdBreak.
135
+ */
116
136
  fun fromAdBreak(adbreak: AdBreak?): WritableMap {
117
137
  val adbreakPayload = Arguments.createMap()
118
138
  if (adbreak == null) {
@@ -158,4 +178,275 @@ object AdAdapter {
158
178
  }
159
179
  return companionsPayload
160
180
  }
181
+
182
+ /**
183
+ * Convert a ReactNative Ad to a native Ad.
184
+ */
185
+ fun parseAd(ad: ReadableMap?): GoogleImaAd? {
186
+ if (ad == null) {
187
+ return null
188
+ }
189
+ return object: GoogleImaAd {
190
+ override fun getId(): String {
191
+ return ad.getString(PROP_AD_ID) ?: ""
192
+ }
193
+
194
+ override fun getCompanions(): List<CompanionAd> {
195
+ return emptyList()
196
+ }
197
+
198
+ override fun getType(): String? {
199
+ return ad.getString(PROP_AD_TYPE)
200
+ }
201
+
202
+ override fun getAdBreak(): AdBreak? {
203
+ return parseAdBreak(ad.getMap(PROP_AD_BREAK))
204
+ }
205
+
206
+ override fun getSkipOffset(): Int {
207
+ return if (ad.hasKey(PROP_AD_SKIPOFFSET)) ad.getInt(PROP_AD_SKIPOFFSET) else 0
208
+ }
209
+
210
+ override fun getIntegration(): AdIntegrationKind {
211
+ return AdIntegrationKind.from(ad.getString(PROP_AD_INTEGRATION))
212
+ }
213
+
214
+ override fun getImaAd(): com.google.ads.interactivemedia.v3.api.Ad {
215
+ return parseImaAd(ad)
216
+ }
217
+
218
+ override fun getAdSystem(): String {
219
+ return ad.getString(PROP_AD_SYSTEM) ?: ""
220
+ }
221
+
222
+ override fun getCreativeId(): String? {
223
+ return ad.getString(PROP_AD_CREATIVE_ID)
224
+ }
225
+
226
+ override fun getWrapperAdIds(): List<String> {
227
+ return emptyList()
228
+ }
229
+
230
+ override fun getWrapperAdSystems(): List<String> {
231
+ return emptyList()
232
+ }
233
+
234
+ override fun getWrapperCreativeIds(): List<String> {
235
+ return emptyList()
236
+ }
237
+
238
+ override fun getVastMediaBitrate(): Int {
239
+ return if (ad.hasKey(PROP_AD_BITRATE)) ad.getInt(PROP_AD_BITRATE) else 0
240
+ }
241
+
242
+ override fun getUniversalAdIds(): List<UniversalAdId> {
243
+ return emptyList()
244
+ }
245
+
246
+ override fun getTraffickingParameters(): String {
247
+ return ad.getString(PROP_AD_TRAFFICKING_PARAMETERS) ?: ""
248
+ }
249
+ }
250
+ }
251
+
252
+ fun parseAdBreak(adBreak: ReadableMap?): AdBreak? {
253
+ if (adBreak == null) {
254
+ return null
255
+ }
256
+ return object: AdBreak {
257
+ override fun getAds(): List<Ad> {
258
+ return emptyList()
259
+ }
260
+
261
+ override fun getMaxDuration(): Int {
262
+ return if (adBreak.hasKey(PROP_ADBREAK_MAXDURATION))
263
+ (1e-3 * adBreak.getInt(PROP_ADBREAK_MAXDURATION)).toInt()
264
+ else
265
+ INVALID_INT
266
+ }
267
+
268
+ override fun getMaxRemainingDuration(): Double {
269
+ return if (adBreak.hasKey(PROP_ADBREAK_MAXREMAININGDURATION))
270
+ 1e-3 * adBreak.getDouble(PROP_ADBREAK_MAXREMAININGDURATION)
271
+ else
272
+ INVALID_DOUBLE
273
+ }
274
+
275
+ override fun getTimeOffset(): Int {
276
+ return if (adBreak.hasKey(PROP_ADBREAK_TIMEOFFSET))
277
+ (1e-3 * adBreak.getInt(PROP_ADBREAK_TIMEOFFSET)).toInt()
278
+ else
279
+ 0
280
+ }
281
+
282
+ override fun getIntegration(): AdIntegrationKind {
283
+ return AdIntegrationKind.from(adBreak.getString(PROP_ADBREAK_INTEGRATION))
284
+ }
285
+ }
286
+ }
287
+
288
+ fun parseImaAd(ad: ReadableMap?): com.google.ads.interactivemedia.v3.api.Ad {
289
+ return object: com.google.ads.interactivemedia.v3.api.Ad {
290
+ override fun getDuration(): Double {
291
+ return ad?.run {
292
+ if (hasKey(PROP_AD_DURATION)) 1e-3 * getDouble(PROP_AD_DURATION) else INVALID_DOUBLE
293
+ } ?: INVALID_DOUBLE
294
+ }
295
+
296
+ override fun getSkipTimeOffset(): Double {
297
+ return ad?.run {
298
+ if (hasKey(PROP_AD_SKIPOFFSET)) 1e-3 * getDouble(PROP_AD_SKIPOFFSET) else INVALID_DOUBLE
299
+ } ?: INVALID_DOUBLE
300
+ }
301
+
302
+ override fun getHeight(): Int {
303
+ return ad?.run {
304
+ if (hasKey(PROP_AD_HEIGHT)) getInt(PROP_AD_HEIGHT) else INVALID_INT
305
+ } ?: INVALID_INT
306
+ }
307
+
308
+ override fun getVastMediaBitrate(): Int {
309
+ return ad?.run {
310
+ if (hasKey(PROP_AD_BITRATE)) getInt(PROP_AD_BITRATE) else INVALID_INT
311
+ } ?: INVALID_INT
312
+ }
313
+
314
+ override fun getVastMediaHeight(): Int {
315
+ return ad?.run {
316
+ if (hasKey(PROP_AD_HEIGHT)) getInt(PROP_AD_HEIGHT) else INVALID_INT
317
+ } ?: INVALID_INT
318
+ }
319
+
320
+ override fun getVastMediaWidth(): Int {
321
+ return ad?.run {
322
+ if (hasKey(PROP_AD_WIDTH)) getInt(PROP_AD_WIDTH) else INVALID_INT
323
+ } ?: INVALID_INT
324
+ }
325
+
326
+ override fun getWidth(): Int {
327
+ return ad?.run {
328
+ if (hasKey(PROP_AD_WIDTH)) getInt(PROP_AD_WIDTH) else INVALID_INT
329
+ } ?: INVALID_INT
330
+ }
331
+
332
+ override fun getAdPodInfo(): AdPodInfo {
333
+ return object: AdPodInfo {
334
+ override fun getMaxDuration(): Double {
335
+ return INVALID_DOUBLE
336
+ }
337
+
338
+ override fun getTimeOffset(): Double {
339
+ return INVALID_DOUBLE
340
+ }
341
+
342
+ override fun getAdPosition(): Int {
343
+ return INVALID_INT
344
+ }
345
+
346
+ override fun getPodIndex(): Int {
347
+ return INVALID_INT
348
+ }
349
+
350
+ override fun getTotalAds(): Int {
351
+ return INVALID_INT
352
+ }
353
+
354
+ override fun isBumper(): Boolean {
355
+ return false
356
+ }
357
+ }
358
+ }
359
+
360
+ override fun getAdId(): String {
361
+ return ad?.getString(PROP_AD_ID) ?: ""
362
+ }
363
+
364
+ override fun getAdSystem(): String {
365
+ return ad?.getString(PROP_AD_SYSTEM) ?: ""
366
+ }
367
+
368
+ override fun getAdvertiserName(): String {
369
+ return ""
370
+ }
371
+
372
+ override fun getContentType(): String {
373
+ return ad?.getString(PROP_AD_CONTENT_TYPE) ?: ""
374
+ }
375
+
376
+ override fun getCreativeAdId(): String {
377
+ return ""
378
+ }
379
+
380
+ override fun getCreativeId(): String {
381
+ return ad?.getString(PROP_AD_CREATIVE_ID) ?: ""
382
+ }
383
+
384
+ override fun getDealId(): String {
385
+ return ""
386
+ }
387
+
388
+ override fun getDescription(): String {
389
+ return ""
390
+ }
391
+
392
+ override fun getSurveyUrl(): String {
393
+ return ""
394
+ }
395
+
396
+ override fun getTitle(): String {
397
+ return ad?.getString(PROP_AD_TITLE) ?: ""
398
+ }
399
+
400
+ override fun getTraffickingParameters(): String {
401
+ return ad?.getString(PROP_AD_TRAFFICKING_PARAMETERS) ?: ""
402
+ }
403
+
404
+ @Deprecated("Deprecated in Java")
405
+ override fun getUniversalAdIdRegistry(): String {
406
+ return ""
407
+ }
408
+
409
+ @Deprecated("Deprecated in Java")
410
+ override fun getUniversalAdIdValue(): String {
411
+ return ad?.getString(PROP_UNIVERSAL_AD_ID_VALUE) ?: ""
412
+ }
413
+
414
+ override fun getCompanionAds(): List<com.google.ads.interactivemedia.v3.api.CompanionAd> {
415
+ return emptyList()
416
+ }
417
+
418
+ override fun getUiElements(): Set<UiElement> {
419
+ return emptySet()
420
+ }
421
+
422
+ override fun isLinear(): Boolean {
423
+ // Only linear ads are supported currently
424
+ return true
425
+ }
426
+
427
+ override fun isSkippable(): Boolean {
428
+ return false
429
+ }
430
+
431
+ override fun isUiDisabled(): Boolean {
432
+ return false
433
+ }
434
+
435
+ override fun getUniversalAdIds(): Array<com.google.ads.interactivemedia.v3.api.UniversalAdId> {
436
+ return emptyArray()
437
+ }
438
+
439
+ override fun getAdWrapperCreativeIds(): Array<String> {
440
+ return emptyArray()
441
+ }
442
+
443
+ override fun getAdWrapperIds(): Array<String> {
444
+ return emptyArray()
445
+ }
446
+
447
+ override fun getAdWrapperSystems(): Array<String> {
448
+ return emptyArray()
449
+ }
450
+ }
451
+ }
161
452
  }
@@ -1,10 +1,13 @@
1
1
  package com.theoplayer.ads
2
2
 
3
3
  import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.ReadableMap
4
5
  import com.theoplayer.android.api.ads.wrapper.AdsApiWrapper
5
6
  import com.facebook.react.bridge.WritableMap
6
7
  import com.theoplayer.android.api.ads.Ad
7
8
  import com.theoplayer.android.api.ads.AdBreak
9
+ import com.theoplayer.android.api.ads.GoogleImaAd
10
+ import com.theoplayer.android.api.ads.ima.GoogleImaAdEvent
8
11
  import com.theoplayer.android.api.ads.ima.GoogleImaAdEventType
9
12
  import com.theoplayer.android.api.ads.wrapper.AdEventListener
10
13
  import com.theoplayer.android.api.event.EventType
@@ -13,6 +16,8 @@ import java.util.*
13
16
 
14
17
  private const val EVENT_PROP_AD = "ad"
15
18
  private const val EVENT_PROP_TYPE = "type"
19
+ private const val EVENT_PROP_SUBTYPE = "subType"
20
+
16
21
  private val ALL_AD_EVENTS = arrayOf(
17
22
  GoogleImaAdEventType.LOADED,
18
23
  GoogleImaAdEventType.AD_BREAK_STARTED,
@@ -64,21 +69,64 @@ class AdEventAdapter(private val adsApi: AdsApiWrapper, eventEmitter: AdEventEmi
64
69
  }
65
70
  }
66
71
 
67
- private fun mapAdType(eventType: EventType<*>): String {
68
- return when (eventType as GoogleImaAdEventType) {
69
- GoogleImaAdEventType.LOADED -> "adloaded"
70
- GoogleImaAdEventType.STARTED -> "adbegin"
71
- GoogleImaAdEventType.FIRST_QUARTILE -> "adfirstquartile"
72
- GoogleImaAdEventType.MIDPOINT -> "admidpoint"
73
- GoogleImaAdEventType.THIRD_QUARTILE -> "adthirdquartile"
74
- GoogleImaAdEventType.COMPLETED -> "adend"
75
- GoogleImaAdEventType.SKIPPED -> "adskip"
76
- GoogleImaAdEventType.AD_ERROR -> "aderror"
77
- GoogleImaAdEventType.AD_BUFFERING -> "adbuffering"
78
- GoogleImaAdEventType.AD_BREAK_STARTED -> "adbreakbegin"
79
- GoogleImaAdEventType.AD_BREAK_ENDED -> "adbreakend"
80
- GoogleImaAdEventType.AD_BREAK_FETCH_ERROR -> "aderror"
81
- else -> eventType.getName().lowercase(Locale.getDefault())
72
+ companion object {
73
+
74
+ /**
75
+ * Create a native GoogleImaAdEvent from a ReactNative AdEvent.
76
+ */
77
+ fun parseEvent(event: ReadableMap?): GoogleImaAdEvent? {
78
+ val eventType = mapAdType(event?.getString(EVENT_PROP_SUBTYPE))
79
+ return if (event != null && eventType != null) {
80
+ object : GoogleImaAdEvent {
81
+ override val ad: GoogleImaAd?
82
+ get() = AdAdapter.parseAd(event.getMap(EVENT_PROP_AD))
83
+ override val adData: Map<String, String>
84
+ get() = mapOf()
85
+ override fun getDate(): Date {
86
+ return Date()
87
+ }
88
+ override fun getType(): EventType<GoogleImaAdEvent> {
89
+ return eventType
90
+ }
91
+ }
92
+ } else {
93
+ null
94
+ }
95
+ }
96
+
97
+ private fun mapAdType(eventType: String?): EventType<GoogleImaAdEvent>? {
98
+ return when (eventType) {
99
+ "adloaded" -> GoogleImaAdEventType.LOADED
100
+ "adbegin" -> GoogleImaAdEventType.STARTED
101
+ "adfirstquartile" -> GoogleImaAdEventType.FIRST_QUARTILE
102
+ "admidpoint" -> GoogleImaAdEventType.MIDPOINT
103
+ "adthirdquartile" -> GoogleImaAdEventType.THIRD_QUARTILE
104
+ "adend" -> GoogleImaAdEventType.COMPLETED
105
+ "adskip" -> GoogleImaAdEventType.SKIPPED
106
+ "aderror" -> GoogleImaAdEventType.AD_ERROR
107
+ "adbuffering" -> GoogleImaAdEventType.AD_BUFFERING
108
+ "adbreakbegin" -> GoogleImaAdEventType.AD_BREAK_STARTED
109
+ "adbreakend" -> GoogleImaAdEventType.AD_BREAK_ENDED
110
+ else -> null /*unknown*/
111
+ }
112
+ }
113
+
114
+ private fun mapAdType(eventType: EventType<*>): String {
115
+ return when (eventType as GoogleImaAdEventType) {
116
+ GoogleImaAdEventType.LOADED -> "adloaded"
117
+ GoogleImaAdEventType.STARTED -> "adbegin"
118
+ GoogleImaAdEventType.FIRST_QUARTILE -> "adfirstquartile"
119
+ GoogleImaAdEventType.MIDPOINT -> "admidpoint"
120
+ GoogleImaAdEventType.THIRD_QUARTILE -> "adthirdquartile"
121
+ GoogleImaAdEventType.COMPLETED -> "adend"
122
+ GoogleImaAdEventType.SKIPPED -> "adskip"
123
+ GoogleImaAdEventType.AD_ERROR -> "aderror"
124
+ GoogleImaAdEventType.AD_BUFFERING -> "adbuffering"
125
+ GoogleImaAdEventType.AD_BREAK_STARTED -> "adbreakbegin"
126
+ GoogleImaAdEventType.AD_BREAK_ENDED -> "adbreakend"
127
+ GoogleImaAdEventType.AD_BREAK_FETCH_ERROR -> "aderror"
128
+ else -> eventType.getName().lowercase(Locale.getDefault())
129
+ }
82
130
  }
83
131
  }
84
132
 
@@ -0,0 +1,27 @@
1
+ package com.theoplayer.broadcast
2
+
3
+ import com.theoplayer.android.api.event.EventDispatcher
4
+ import com.theoplayer.android.api.event.EventListener
5
+ import com.theoplayer.android.api.event.EventType
6
+ import com.theoplayer.android.api.event.Event
7
+
8
+ open class DefaultEventDispatcher: EventDispatcher<Event<*>> {
9
+ private val _listeners = mutableMapOf<EventType<*>, MutableList<EventListener<*>>>()
10
+
11
+ override fun <T : Event<*>> addEventListener(eventType: EventType<T>, listener: EventListener<in T>) {
12
+ if (!_listeners.contains(eventType)) {
13
+ _listeners[eventType] = mutableListOf()
14
+ }
15
+ _listeners[eventType]?.add(listener)
16
+ }
17
+
18
+ override fun <T : Event<*>> removeEventListener(eventType: EventType<T>, listener: EventListener<in T>) {
19
+ _listeners[eventType]?.remove(listener)
20
+ }
21
+
22
+ fun dispatchEvent(event: Event<*>) {
23
+ _listeners[event.type]?.forEach { listener ->
24
+ (listener as EventListener<Event<*>>).handleEvent(event)
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,23 @@
1
+ package com.theoplayer.broadcast
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.ReadableMap
5
+ import com.theoplayer.ads.AdEventAdapter
6
+ import com.theoplayer.android.api.event.Event
7
+
8
+ private const val EVENT_PROP_TYPE = "type"
9
+ private const val PROP_AD_EVENT = "adevent"
10
+
11
+ private const val TAG = "EventAdapter"
12
+
13
+ object EventAdapter {
14
+ fun parseEvent(event: ReadableMap?): Event<*>? {
15
+ return when (val eventType = event?.getString(EVENT_PROP_TYPE)) {
16
+ PROP_AD_EVENT -> AdEventAdapter.parseEvent(event)
17
+ else -> {
18
+ Log.w(TAG, "Forwarding events of type $eventType not supported yet.")
19
+ null
20
+ } /*not supported yet*/
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,15 @@
1
+ package com.theoplayer.broadcast
2
+
3
+ import com.facebook.react.bridge.ReadableMap
4
+ import com.theoplayer.ReactTHEOplayerView
5
+
6
+ class EventBroadcastAdapter(private val view: ReactTHEOplayerView): DefaultEventDispatcher() {
7
+ /**
8
+ * Convert a react-native event to a native event and broadcast it.
9
+ */
10
+ fun broadcastEvent(event: ReadableMap) {
11
+ EventAdapter.parseEvent(event)?.also {
12
+ view.broadcast.dispatchEvent(it)
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,36 @@
1
+ @file:Suppress("unused")
2
+ package com.theoplayer.broadcast
3
+
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
6
+ import com.facebook.react.bridge.ReactMethod
7
+ import com.facebook.react.bridge.ReadableMap
8
+ import com.facebook.react.module.annotations.ReactModule
9
+ import com.theoplayer.ReactTHEOplayerView
10
+ import com.theoplayer.util.ViewResolver
11
+
12
+ private const val TAG = "EventBroadcastModule"
13
+
14
+ @ReactModule(name = TAG)
15
+ class EventBroadcastModule(context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
16
+
17
+ private val viewResolver: ViewResolver
18
+
19
+ init {
20
+ viewResolver = ViewResolver(context)
21
+ }
22
+
23
+ override fun getName(): String {
24
+ return TAG
25
+ }
26
+
27
+ /**
28
+ * Receive a react-native broadcast event and route it to the player's broadcast adapter.
29
+ */
30
+ @ReactMethod
31
+ fun broadcastEvent(tag: Int, event: ReadableMap) {
32
+ viewResolver.resolveViewByTag(tag) { view: ReactTHEOplayerView? ->
33
+ view?.broadcast?.broadcastEvent(event)
34
+ }
35
+ }
36
+ }
@@ -239,3 +239,13 @@ RCT_EXTERN_METHOD(renewLicense:(nonnull NSString *)id
239
239
  drmConfig:(NSDictionary)drmConfig)
240
240
 
241
241
  @end
242
+
243
+ // ----------------------------------------------------------------------------
244
+ // Broadcast Module
245
+ // ----------------------------------------------------------------------------
246
+ @interface RCT_EXTERN_REMAP_MODULE(EventBroadcastModule, THEOplayerRCTEventBroadcastAPI, NSObject)
247
+
248
+ RCT_EXTERN_METHOD(broadcastEvent:(nonnull NSNumber *)node
249
+ event:(NSDictionary)event)
250
+
251
+ @end
@@ -98,6 +98,23 @@ class THEOplayerRCTTypeUtils {
98
98
  return TextTrackStyleEdgeStyle.none
99
99
  }
100
100
  }
101
+
102
+ class func adIntegrationKind(_ integration: String) -> AdIntegrationKind {
103
+ switch integration {
104
+ case "theo":
105
+ return AdIntegrationKind.theo
106
+ case "freewheel":
107
+ return AdIntegrationKind.freewheel
108
+ case "google-ima":
109
+ return AdIntegrationKind.google_ima
110
+ case "google-dai":
111
+ return AdIntegrationKind.google_dai
112
+ case "":
113
+ return AdIntegrationKind.defaultKind
114
+ default:
115
+ return AdIntegrationKind.defaultKind
116
+ }
117
+ }
101
118
 
102
119
  #if os(iOS)
103
120
  class func cacheStatusToString(_ status: CacheStatus) -> String {
@@ -8,6 +8,7 @@ public class THEOplayerRCTView: UIView {
8
8
  // MARK: Members
9
9
  public private(set) var player: THEOplayer?
10
10
  public private(set) var mainEventHandler: THEOplayerRCTMainEventHandler
11
+ public private(set) var broadcastEventHandler: THEOplayerRCTBroadcastEventHandler
11
12
  var textTrackEventHandler: THEOplayerRCTTextTrackEventHandler
12
13
  var mediaTrackEventHandler: THEOplayerRCTMediaTrackEventHandler
13
14
  var adEventHandler: THEOplayerRCTAdsEventHandler
@@ -44,6 +45,7 @@ public class THEOplayerRCTView: UIView {
44
45
  init() {
45
46
  // create event handlers to maintain event props
46
47
  self.mainEventHandler = THEOplayerRCTMainEventHandler()
48
+ self.broadcastEventHandler = THEOplayerRCTBroadcastEventHandler()
47
49
  self.textTrackEventHandler = THEOplayerRCTTextTrackEventHandler()
48
50
  self.mediaTrackEventHandler = THEOplayerRCTMediaTrackEventHandler()
49
51
  self.adEventHandler = THEOplayerRCTAdsEventHandler()