bitmovin-player-react-native 0.5.0 → 0.6.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.
package/README.md CHANGED
@@ -69,9 +69,10 @@ Features of the native mobile Player SDKs are progressively being implemented in
69
69
  | Playback of DRM-protected assets | :white_check_mark: Available since v0.2.0 |
70
70
  | Subtitles & Captions | :white_check_mark: Available since v0.2.0 |
71
71
  | Advertising | :white_check_mark: Available since v0.4.0 |
72
+ | Analytics | :white_check_mark: Available since v0.5.0 |
72
73
  | Playlist API | :x: Not available |
74
+ | Casting | :x: Not available |
73
75
  | Offline Playback | :x: Not available |
74
- | Analytics | :x: Coming Q1 2023 |
75
76
 
76
77
  ## Installation
77
78
 
@@ -460,9 +461,9 @@ const drmSource: SourceConfig = {
460
461
  };
461
462
  ```
462
463
 
463
- The [`FairplayConfig`](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm.ts#L10) interface provides a bunch of hooks that can be used to fetch and transform different DRM related data. Check out the [docs](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm.ts#L10) for a complete list and detailed information on them.
464
+ The [`FairplayConfig`](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm/fairplayConfig.ts) interface provides a bunch of hooks that can be used to fetch and transform different DRM related data. Check out the [docs]([https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm/fairplayConfig.ts](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/src/drm/fairplayConfig.ts)) for a complete list and detailed information on them.
464
465
 
465
- Also, don't forget to check out the [example](https://github.com/bitmovin/bitmovin-player-react-native/tree/development/example) app for a complete iOS/Android [DRM example](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/example/src/screens/BasicDRMPlayback.tsx).
466
+ Also, don't forget to check out the [example](https://github.com/bitmovin/bitmovin-player-react-native/tree/development/example) app for a complete iOS/Android [DRM example](https://github.com/bitmovin/bitmovin-player-react-native/blob/development/example/src/screens/BasicDrmPlayback.tsx).
466
467
 
467
468
  ### Adding external subtitle tracks
468
469
 
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
19
19
  s.source_files = "ios/**/*.{h,m,mm,swift}"
20
20
 
21
21
  s.dependency "React-Core"
22
- s.dependency "BitmovinPlayer", "3.32.0"
22
+ s.dependency "BitmovinPlayer", "3.36.0"
23
23
  s.dependency "BitmovinAnalyticsCollector/Core", "2.9.4"
24
24
  s.dependency "BitmovinAnalyticsCollector/BitmovinPlayer", "2.9.4"
25
25
  s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.17.0"
@@ -53,6 +53,6 @@ dependencies {
53
53
  implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.26.0'
54
54
  implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
55
55
  implementation 'com.bitmovin.analytics:collector-bitmovin-player:2.12.1'
56
- implementation 'com.bitmovin.player:player:3.26.1'
56
+ implementation 'com.bitmovin.player:player:3.35.0'
57
57
  implementation 'com.facebook.react:react-native:+'
58
58
  }
@@ -0,0 +1,47 @@
1
+ package com.bitmovin.player.reactnative
2
+
3
+ import com.bitmovin.player.api.event.Event
4
+ import com.bitmovin.player.api.event.EventEmitter
5
+ import kotlin.reflect.KClass
6
+
7
+ private data class Subscription<E : Event>(
8
+ val eventClass: KClass<out E>,
9
+ val action: (E) -> Unit,
10
+ )
11
+
12
+ /**
13
+ * Attaches and detaches listener for the provided forwarding events on the current [EventEmitter] instance and
14
+ * relays the received events together with their associated name to the provided event output.
15
+ */
16
+ class EventRelay<E : EventEmitter<T>, T : Event>(
17
+ /**
18
+ * List of events that should be relayed and their associated name.
19
+ */
20
+ forwardingEventClassesAndNameMapping: Map<KClass<out T>, String>,
21
+ /**
22
+ * Is called for every relayed event together with its associated name.
23
+ */
24
+ private val eventOutput: (String, Event) -> Unit
25
+ ) {
26
+ private val eventListeners = forwardingEventClassesAndNameMapping.map {
27
+ Subscription(it.key) { event -> eventOutput(it.value, event) }
28
+ }
29
+
30
+ /**
31
+ * The [EventEmitter] for which the events are relayed.
32
+ */
33
+ var eventEmitter: E? = null
34
+ set(value) {
35
+ field?.detachListeners(eventListeners)
36
+ field = value
37
+ value?.attachListeners(eventListeners)
38
+ }
39
+ }
40
+
41
+ private fun <T : Event, E : T> EventEmitter<T>.attachListeners(eventListener: List<Subscription<E>>) {
42
+ eventListener.forEach { on(it.eventClass, it.action) }
43
+ }
44
+
45
+ private fun <T : Event, E : T> EventEmitter<T>.detachListeners(eventListener: List<Subscription<E>>) {
46
+ eventListener.forEach { off(it.eventClass, it.action) }
47
+ }
@@ -261,6 +261,38 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
261
261
  }
262
262
  }
263
263
 
264
+ /**
265
+ * Resolve `nativeId`'s player available audio tracks.
266
+ * @param nativeId Target player Id.
267
+ * @param promise JS promise object.
268
+ */
269
+ @ReactMethod
270
+ fun getAvailableAudioTracks(nativeId: NativeId, promise: Promise) {
271
+ uiManager()?.addUIBlock {
272
+ val audioTracks = Arguments.createArray()
273
+ players[nativeId]?.source?.availableAudioTracks?.let { tracks ->
274
+ tracks.forEach {
275
+ audioTracks.pushMap(JsonConverter.fromAudioTrack(it))
276
+ }
277
+ }
278
+ promise.resolve(audioTracks)
279
+ }
280
+ }
281
+
282
+ /**
283
+ * Set `nativeId`'s player audio track.
284
+ * @param nativeId Target player Id.
285
+ * @param trackIdentifier The audio track identifier.
286
+ * @param promise JS promise object.
287
+ */
288
+ @ReactMethod
289
+ fun setAudioTrack(nativeId: NativeId, trackIdentifier: String, promise: Promise) {
290
+ uiManager()?.addUIBlock {
291
+ players[nativeId]?.source?.setAudioTrack(trackIdentifier)
292
+ promise.resolve(null)
293
+ }
294
+ }
295
+
264
296
  /**
265
297
  * Resolve `nativeId`'s player available subtitle tracks.
266
298
  * @param nativeId Target player Id.
@@ -279,6 +311,20 @@ class PlayerModule(private val context: ReactApplicationContext) : ReactContextB
279
311
  }
280
312
  }
281
313
 
314
+ /**
315
+ * Set `nativeId`'s player subtitle track.
316
+ * @param nativeId Target player Id.
317
+ * @param trackIdentifier The subtitle track identifier.
318
+ * @param promise JS promise object.
319
+ */
320
+ @ReactMethod
321
+ fun setSubtitleTrack(nativeId: NativeId, trackIdentifier: String?, promise: Promise) {
322
+ uiManager()?.addUIBlock {
323
+ players[nativeId]?.source?.setSubtitleTrack(trackIdentifier)
324
+ promise.resolve(null)
325
+ }
326
+ }
327
+
282
328
  /**
283
329
  * Schedules an `AdItem` in the `nativeId`'s associated player.
284
330
  * @param nativeId Target player id.
@@ -11,7 +11,6 @@ import com.bitmovin.player.api.Player
11
11
  import com.bitmovin.player.api.event.Event
12
12
  import com.bitmovin.player.api.event.PlayerEvent
13
13
  import com.bitmovin.player.api.event.SourceEvent
14
- import com.bitmovin.player.api.event.on
15
14
  import com.bitmovin.player.reactnative.converter.JsonConverter
16
15
  import com.bitmovin.player.reactnative.ui.RNPictureInPictureDelegate
17
16
  import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler
@@ -19,6 +18,59 @@ import com.facebook.react.bridge.LifecycleEventListener
19
18
  import com.facebook.react.bridge.ReactApplicationContext
20
19
  import com.facebook.react.bridge.ReactContext
21
20
  import com.facebook.react.uimanager.events.RCTEventEmitter
21
+ import kotlin.reflect.KClass
22
+
23
+ private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING = mapOf(
24
+ PlayerEvent::class to "event",
25
+ PlayerEvent.Error::class to "playerError",
26
+ PlayerEvent.Warning::class to "playerWarning",
27
+ PlayerEvent.Destroy::class to "destroy",
28
+ PlayerEvent.Muted::class to "muted",
29
+ PlayerEvent.Unmuted::class to "unmuted",
30
+ PlayerEvent.Ready::class to "ready",
31
+ PlayerEvent.Paused::class to "paused",
32
+ PlayerEvent.Play::class to "play",
33
+ PlayerEvent.Playing::class to "playing",
34
+ PlayerEvent.PlaybackFinished::class to "playbackFinished",
35
+ PlayerEvent.Seek::class to "seek",
36
+ PlayerEvent.Seeked::class to "seeked",
37
+ PlayerEvent.StallStarted::class to "stallStarted",
38
+ PlayerEvent.StallEnded::class to "stallEnded",
39
+ PlayerEvent.TimeChanged::class to "timeChanged",
40
+ SourceEvent.Load::class to "sourceLoad",
41
+ SourceEvent.Loaded::class to "sourceLoaded",
42
+ SourceEvent.Unloaded::class to "sourceUnloaded",
43
+ SourceEvent.Error::class to "sourceError",
44
+ SourceEvent.Warning::class to "sourceWarning",
45
+ SourceEvent.SubtitleTrackAdded::class to "subtitleAdded",
46
+ SourceEvent.SubtitleTrackChanged::class to "subtitleChanged",
47
+ SourceEvent.SubtitleTrackRemoved::class to "subtitleRemoved",
48
+ SourceEvent.AudioTrackAdded::class to "audioAdded",
49
+ SourceEvent.AudioTrackChanged::class to "audioChanged",
50
+ SourceEvent.AudioTrackRemoved::class to "audioRemoved",
51
+ PlayerEvent.AdBreakFinished::class to "adBreakFinished",
52
+ PlayerEvent.AdBreakStarted::class to "adBreakStarted",
53
+ PlayerEvent.AdClicked::class to "adClicked",
54
+ PlayerEvent.AdError::class to "adError",
55
+ PlayerEvent.AdFinished::class to "adFinished",
56
+ PlayerEvent.AdManifestLoad::class to "adManifestLoad",
57
+ PlayerEvent.AdManifestLoaded::class to "adManifestLoaded",
58
+ PlayerEvent.AdQuartile::class to "adQuartile",
59
+ PlayerEvent.AdScheduled::class to "adScheduled",
60
+ PlayerEvent.AdSkipped::class to "adSkipped",
61
+ PlayerEvent.AdStarted::class to "adStarted",
62
+ PlayerEvent.VideoPlaybackQualityChanged::class to "videoPlaybackQualityChanged",
63
+ )
64
+
65
+ private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI = mapOf<KClass<out Event>, String>(
66
+ PlayerEvent.PictureInPictureAvailabilityChanged::class to "pictureInPictureAvailabilityChanged",
67
+ PlayerEvent.PictureInPictureEnter::class to "pictureInPictureEnter",
68
+ PlayerEvent.PictureInPictureExit::class to "pictureInPictureExit",
69
+ PlayerEvent.FullscreenEnabled::class to "fullscreenEnabled",
70
+ PlayerEvent.FullscreenDisabled::class to "fullscreenDisabled",
71
+ PlayerEvent.FullscreenEnter::class to "fullscreenEnter",
72
+ PlayerEvent.FullscreenExit::class to "fullscreenExit",
73
+ )
22
74
 
23
75
  /**
24
76
  * Native view wrapper for component instances. It both serves as the main view
@@ -28,10 +80,26 @@ import com.facebook.react.uimanager.events.RCTEventEmitter
28
80
  @SuppressLint("ViewConstructor")
29
81
  class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context),
30
82
  LifecycleEventListener, View.OnLayoutChangeListener, RNPictureInPictureDelegate {
83
+ /**
84
+ * Relays the provided set of events, emitted by the player, together with the associated name
85
+ * to the `eventOutput` callback.
86
+ */
87
+ private val playerEventRelay = EventRelay<Player, Event>(EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING, ::emitEvent)
88
+ /**
89
+ * Relays the provided set of events, emitted by the player view, together with the associated name
90
+ * to the `eventOutput` callback.
91
+ */
92
+ private val viewEventRelay = EventRelay<PlayerView, Event>(EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI, ::emitEvent)
93
+
31
94
  /**
32
95
  * Associated bitmovin's `PlayerView`.
33
96
  */
34
97
  var playerView: PlayerView? = null
98
+ set(value) {
99
+ field = value
100
+ viewEventRelay.eventEmitter = field
101
+ playerEventRelay.eventEmitter = field?.player
102
+ }
35
103
 
36
104
  /**
37
105
  * Handy property accessor for `playerView`'s player instance.
@@ -40,6 +108,7 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
40
108
  get() = playerView?.player
41
109
  set(value) {
42
110
  playerView?.player = value
111
+ playerEventRelay.eventEmitter = value
43
112
  }
44
113
 
45
114
  /**
@@ -64,7 +133,8 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
64
133
  * Cleans up the resources and listeners produced by this view.
65
134
  */
66
135
  fun dispose() {
67
- stopBubblingEvents()
136
+ viewEventRelay.eventEmitter = null
137
+ playerEventRelay.eventEmitter = null
68
138
  context.removeLifecycleEventListener(this)
69
139
  playerView?.removeOnLayoutChangeListener(this)
70
140
  }
@@ -102,7 +172,6 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
102
172
  if (playerView.parent != this) {
103
173
  (playerView.parent as ViewGroup?)?.removeView(playerView)
104
174
  addView(playerView)
105
- startBubblingEvents()
106
175
  }
107
176
  pictureInPictureHandler?.let {
108
177
  it.setDelegate(this)
@@ -180,418 +249,12 @@ class RNPlayerView(val context: ReactApplicationContext) : LinearLayout(context)
180
249
  post {
181
250
  measure(
182
251
  MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
183
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY))
252
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
253
+ )
184
254
  layout(left, top, right, bottom)
185
255
  }
186
256
  }
187
257
 
188
- /**
189
- * `onEvent` event callback.
190
- */
191
- private val onEvent: (PlayerEvent) -> Unit = {
192
- emitEvent("event", it)
193
- }
194
-
195
- /**
196
- * `onPlayerError` event callback.
197
- */
198
- private val onPlayerError: (PlayerEvent.Error) -> Unit = {
199
- emitEvent("playerError", it)
200
- }
201
-
202
- /**
203
- * `onPlayerWarning` event callback.
204
- */
205
- private val onPlayerWarning: (PlayerEvent.Warning) -> Unit = {
206
- emitEvent("playerWarning", it)
207
- }
208
-
209
- /**
210
- * `onDestroy` event callback.
211
- */
212
- private val onDestroy: (PlayerEvent.Destroy) -> Unit = {
213
- emitEvent("destroy", it)
214
- }
215
-
216
- /**
217
- * `onMuted` event callback.
218
- */
219
- private val onMuted: (PlayerEvent.Muted) -> Unit = {
220
- emitEvent("muted", it)
221
- }
222
-
223
- /**
224
- * `onUnmuted` event callback.
225
- */
226
- private val onUnmuted: (PlayerEvent.Unmuted) -> Unit = {
227
- emitEvent("unmuted", it)
228
- }
229
-
230
- /**
231
- * `onReady` event callback.
232
- */
233
- private val onReady: (PlayerEvent.Ready) -> Unit = {
234
- emitEvent("ready", it)
235
- }
236
-
237
- /**
238
- * `onPaused` event callback.
239
- */
240
- private val onPaused: (PlayerEvent.Paused) -> Unit = {
241
- emitEvent("paused", it)
242
- }
243
-
244
- /**
245
- * `onPlay` event callback.
246
- */
247
- private val onPlay: (PlayerEvent.Play) -> Unit = {
248
- emitEvent("play", it)
249
- }
250
-
251
- /**
252
- * `onPlaying` event callback.
253
- */
254
- private val onPlaying: (PlayerEvent.Playing) -> Unit = {
255
- emitEvent("playing", it)
256
- }
257
-
258
- /**
259
- * `onPlaybackFinished` event callback.
260
- */
261
- private val onPlaybackFinished: (PlayerEvent.PlaybackFinished) -> Unit = {
262
- emitEvent("playbackFinished", it)
263
- }
264
-
265
- /**
266
- * `onSeek` event callback.
267
- */
268
- private val onSeek: (PlayerEvent.Seek) -> Unit = {
269
- emitEvent("seek", it)
270
- }
271
-
272
- /**
273
- * `onSeeked` event callback.
274
- */
275
- private val onSeeked: (PlayerEvent.Seeked) -> Unit = {
276
- emitEvent("seeked", it)
277
- }
278
-
279
- /**
280
- * `onStallStarted` event callback.
281
- */
282
- private val onStallStarted: (PlayerEvent.StallStarted) -> Unit = {
283
- emitEvent("stallStarted", it)
284
- }
285
-
286
- /**
287
- * `onStallEnded` event callback.
288
- */
289
- private val onStallEnded: (PlayerEvent.StallEnded) -> Unit = {
290
- emitEvent("stallEnded", it)
291
- }
292
-
293
- /**
294
- * `onTimeChanged` event callback.
295
- */
296
- private val onTimeChanged: (PlayerEvent.TimeChanged) -> Unit = {
297
- emitEvent("timeChanged", it)
298
- }
299
-
300
- /**
301
- * `onSourceLoad` event callback.
302
- */
303
- private val onSourceLoad: (SourceEvent.Load) -> Unit = {
304
- emitEvent("sourceLoad", it)
305
- }
306
-
307
- /**
308
- * `onSourceLoaded` event callback.
309
- */
310
- private val onSourceLoaded: (SourceEvent.Loaded) -> Unit = {
311
- emitEvent("sourceLoaded", it)
312
- }
313
-
314
- /**
315
- * `onSourceUnloaded` event callback.
316
- */
317
- private val onSourceUnloaded: (SourceEvent.Unloaded) -> Unit = {
318
- emitEvent("sourceUnloaded", it)
319
- }
320
-
321
- /**
322
- * `onSourceError` event callback.
323
- */
324
- private val onSourceError: (SourceEvent.Error) -> Unit = {
325
- emitEvent("sourceError", it)
326
- }
327
-
328
- /**
329
- * `onSourceWarning` event callback.
330
- */
331
- private val onSourceWarning: (SourceEvent.Warning) -> Unit = {
332
- emitEvent("sourceWarning", it)
333
- }
334
-
335
- /**
336
- * `onSubtitleAdded` event callback.
337
- */
338
- private val onSubtitleAdded: (SourceEvent.SubtitleTrackAdded) -> Unit = {
339
- emitEvent("subtitleAdded", it)
340
- }
341
-
342
- /**
343
- * `onSubtitleChanged` event callback.
344
- */
345
- private val onSubtitleChanged: (SourceEvent.SubtitleTrackChanged) -> Unit = {
346
- emitEvent("subtitleChanged", it)
347
- }
348
-
349
- /**
350
- * `onSubtitleRemoved` event callback.
351
- */
352
- private val onSubtitleRemoved: (SourceEvent.SubtitleTrackRemoved) -> Unit = {
353
- emitEvent("subtitleRemoved", it)
354
- }
355
-
356
- /**
357
- * `onPictureInPictureAvailabilityChanged` event callback.
358
- */
359
- private val onPictureInPictureAvailabilityChanged: (PlayerEvent.PictureInPictureAvailabilityChanged) -> Unit = {
360
- emitEvent("pictureInPictureAvailabilityChanged", it)
361
- }
362
-
363
- /**
364
- * `onPictureInPictureEnter` event callback.
365
- */
366
- private val onPictureInPictureEnter: (PlayerEvent.PictureInPictureEnter) -> Unit = {
367
- emitEvent("pictureInPictureEnter", it)
368
- }
369
-
370
- /**
371
- * `onPictureInPictureExit` event callback.
372
- */
373
- private val onPictureInPictureExit: (PlayerEvent.PictureInPictureExit) -> Unit = {
374
- emitEvent("pictureInPictureExit", it)
375
- }
376
-
377
- /**
378
- * `onAdBreakFinished` event callback.
379
- */
380
- private val onAdBreakFinished: (PlayerEvent.AdBreakFinished) -> Unit = {
381
- emitEvent("adBreakFinished", it)
382
- }
383
-
384
- /**
385
- * `onAdBreakStarted` event callback.
386
- */
387
- private val onAdBreakStarted: (PlayerEvent.AdBreakStarted) -> Unit = {
388
- emitEvent("adBreakStarted", it)
389
- }
390
-
391
- /**
392
- * `onAdClicked` event callback.
393
- */
394
- private val onAdClicked: (PlayerEvent.AdClicked) -> Unit = {
395
- emitEvent("adClicked", it)
396
- }
397
-
398
- /**
399
- * `onAdError` event callback.
400
- */
401
- private val onAdError: (PlayerEvent.AdError) -> Unit = {
402
- emitEvent("adError", it)
403
- }
404
-
405
- /**
406
- * `onAdFinished` event callback.
407
- */
408
- private val onAdFinished: (PlayerEvent.AdFinished) -> Unit = {
409
- emitEvent("adFinished", it)
410
- }
411
-
412
- /**
413
- * `onAdManifestLoad` event callback.
414
- */
415
- private val onAdManifestLoad: (PlayerEvent.AdManifestLoad) -> Unit = {
416
- emitEvent("adManifestLoad", it)
417
- }
418
-
419
- /**
420
- * `onAdManifestLoaded` event callback.
421
- */
422
- private val onAdManifestLoaded: (PlayerEvent.AdManifestLoaded) -> Unit = {
423
- emitEvent("adManifestLoaded", it)
424
- }
425
-
426
- /**
427
- * `onAdQuartile` event callback.
428
- */
429
- private val onAdQuartile: (PlayerEvent.AdQuartile) -> Unit = {
430
- emitEvent("adQuartile", it)
431
- }
432
-
433
- /**
434
- * `onAdScheduled` event callback.
435
- */
436
- private val onAdScheduled: (PlayerEvent.AdScheduled) -> Unit = {
437
- emitEvent("adScheduled", it)
438
- }
439
-
440
- /**
441
- * `onAdSkipped` event callback.
442
- */
443
- private val onAdSkipped: (PlayerEvent.AdSkipped) -> Unit = {
444
- emitEvent("adSkipped", it)
445
- }
446
-
447
- /**
448
- * `onAdStarted` event callback.
449
- */
450
- private val onAdStarted: (PlayerEvent.AdStarted) -> Unit = {
451
- emitEvent("adStarted", it)
452
- }
453
-
454
- /**
455
- * `onVideoPlaybackQualityChanged` event callback.
456
- */
457
- private val onVideoPlaybackQualityChanged: (PlayerEvent.VideoPlaybackQualityChanged) -> Unit = {
458
- emitEvent("videoPlaybackQualityChanged", it)
459
- }
460
-
461
- /**
462
- * `onFullscreenEnabled` event callback.
463
- */
464
- private val onFullscreenEnabled: (PlayerEvent.FullscreenEnabled) -> Unit = {
465
- emitEvent("fullscreenEnabled", it)
466
- }
467
-
468
- /**
469
- * `onFullscreenEnabled` event callback.
470
- */
471
- private val onFullscreenDisabled: (PlayerEvent.FullscreenDisabled) -> Unit = {
472
- emitEvent("fullscreenDisabled", it)
473
- }
474
-
475
- /**
476
- * `onFullscreenEnter` event callback.
477
- */
478
- private val onFullscreenEnter: (PlayerEvent.FullscreenEnter) -> Unit = {
479
- emitEvent("fullscreenEnter", it)
480
- }
481
-
482
- /**
483
- * `onFullscreenEnter` event callback.
484
- */
485
- private val onFullscreenExit: (PlayerEvent.FullscreenExit) -> Unit = {
486
- emitEvent("fullscreenExit", it)
487
- }
488
-
489
- /**
490
- * Start listening and emitting player events as bubbling events to the js side.
491
- */
492
- fun startBubblingEvents() {
493
- player?.apply {
494
- on(onEvent)
495
- on(onPlayerError)
496
- on(onPlayerWarning)
497
- on(onDestroy)
498
- on(onMuted)
499
- on(onUnmuted)
500
- on(onReady)
501
- on(onPaused)
502
- on(onPlay)
503
- on(onPlaying)
504
- on(onPlaybackFinished)
505
- on(onSeek)
506
- on(onSeeked)
507
- on(onStallStarted)
508
- on(onStallEnded)
509
- on(onTimeChanged)
510
- on(onSourceLoad)
511
- on(onSourceLoaded)
512
- on(onSourceUnloaded)
513
- on(onSourceError)
514
- on(onSourceWarning)
515
- on(onSubtitleAdded)
516
- on(onSubtitleChanged)
517
- on(onSubtitleRemoved)
518
- on(onAdBreakFinished)
519
- on(onAdBreakStarted)
520
- on(onAdClicked)
521
- on(onAdError)
522
- on(onAdFinished)
523
- on(onAdManifestLoad)
524
- on(onAdManifestLoaded)
525
- on(onAdQuartile)
526
- on(onAdScheduled)
527
- on(onAdSkipped)
528
- on(onAdStarted)
529
- on(onVideoPlaybackQualityChanged)
530
- }
531
- playerView?.apply {
532
- on(onPictureInPictureAvailabilityChanged)
533
- on(onPictureInPictureEnter)
534
- on(onPictureInPictureExit)
535
- on(onFullscreenEnabled)
536
- on(onFullscreenDisabled)
537
- on(onFullscreenEnter)
538
- on(onFullscreenExit)
539
- }
540
- }
541
-
542
- /**
543
- * Stop listening for player events and cease to emit bubbling events.
544
- */
545
- fun stopBubblingEvents() {
546
- player?.apply {
547
- off(onEvent)
548
- off(onPlayerError)
549
- off(onPlayerWarning)
550
- off(onDestroy)
551
- off(onMuted)
552
- off(onUnmuted)
553
- off(onReady)
554
- off(onPaused)
555
- off(onPlay)
556
- off(onPlaying)
557
- off(onPlaybackFinished)
558
- off(onSeek)
559
- off(onSeeked)
560
- off(onStallStarted)
561
- off(onStallEnded)
562
- off(onTimeChanged)
563
- off(onSourceLoad)
564
- off(onSourceLoaded)
565
- off(onSourceUnloaded)
566
- off(onSourceError)
567
- off(onSourceWarning)
568
- off(onSubtitleAdded)
569
- off(onSubtitleChanged)
570
- off(onSubtitleRemoved)
571
- off(onAdBreakFinished)
572
- off(onAdBreakStarted)
573
- off(onAdClicked)
574
- off(onAdError)
575
- off(onAdFinished)
576
- off(onAdManifestLoad)
577
- off(onAdManifestLoaded)
578
- off(onAdQuartile)
579
- off(onAdScheduled)
580
- off(onAdSkipped)
581
- off(onAdStarted)
582
- off(onVideoPlaybackQualityChanged)
583
- }
584
- playerView?.apply {
585
- off(onPictureInPictureAvailabilityChanged)
586
- off(onPictureInPictureEnter)
587
- off(onPictureInPictureExit)
588
- off(onFullscreenEnabled)
589
- off(onFullscreenDisabled)
590
- off(onFullscreenEnter)
591
- off(onFullscreenExit)
592
- }
593
- }
594
-
595
258
  /**
596
259
  * Emits a bubbling event with payload to js.
597
260
  * @param event Native event name.
@@ -78,6 +78,9 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
78
78
  "sourceUnloaded" to "onSourceUnloaded",
79
79
  "sourceError" to "onSourceError",
80
80
  "sourceWarning" to "onSourceWarning",
81
+ "audioAdded" to "onAudioAdded",
82
+ "audioChanged" to "onAudioChanged",
83
+ "audioRemoved" to "onAudioRemoved",
81
84
  "subtitleAdded" to "onSubtitleAdded",
82
85
  "subtitleChanged" to "onSubtitleChanged",
83
86
  "subtitleRemoved" to "onSubtitleRemoved",