bitmovin-player-react-native 1.14.0 → 1.16.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 (38) hide show
  1. package/.eslintrc.js +8 -0
  2. package/CHANGELOG.md +34 -0
  3. package/android/src/main/java/com/bitmovin/player/reactnative/OfflineModule.kt +3 -1
  4. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +107 -168
  5. package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +5 -0
  6. package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +1 -0
  7. package/android/src/main/java/com/bitmovin/player/reactnative/ui/RNPictureInPictureHandler.kt +8 -6
  8. package/build/components/PlayerView/index.d.ts +1 -1
  9. package/build/components/PlayerView/index.d.ts.map +1 -1
  10. package/build/components/PlayerView/index.js +6 -1
  11. package/build/components/PlayerView/index.js.map +1 -1
  12. package/build/components/PlayerView/properties.d.ts +7 -0
  13. package/build/components/PlayerView/properties.d.ts.map +1 -1
  14. package/build/components/PlayerView/properties.js.map +1 -1
  15. package/build/debug.d.ts +6 -0
  16. package/build/debug.d.ts.map +1 -1
  17. package/build/debug.js +11 -0
  18. package/build/debug.js.map +1 -1
  19. package/build/drm/index.d.ts.map +1 -1
  20. package/build/drm/index.js +2 -1
  21. package/build/drm/index.js.map +1 -1
  22. package/build/network/index.d.ts.map +1 -1
  23. package/build/network/index.js +4 -3
  24. package/build/network/index.js.map +1 -1
  25. package/build/playbackConfig.d.ts +7 -0
  26. package/build/playbackConfig.d.ts.map +1 -1
  27. package/build/playbackConfig.js.map +1 -1
  28. package/ios/Event+JSON.swift +2 -2
  29. package/ios/RNBitmovinPlayer.podspec +1 -1
  30. package/ios/RNPlayerView.swift +9 -0
  31. package/ios/RNPlayerViewManager.swift +3 -0
  32. package/package.json +1 -1
  33. package/src/components/PlayerView/index.tsx +13 -0
  34. package/src/components/PlayerView/properties.ts +8 -0
  35. package/src/debug.ts +12 -0
  36. package/src/drm/index.ts +2 -1
  37. package/src/network/index.ts +4 -3
  38. package/src/playbackConfig.ts +7 -0
package/.eslintrc.js CHANGED
@@ -14,5 +14,13 @@ module.exports = {
14
14
  rules: {
15
15
  '@typescript-eslint/no-floating-promises': 'error',
16
16
  'prettier/prettier': 'error',
17
+ 'no-restricted-properties': [
18
+ 'error',
19
+ {
20
+ object: 'console',
21
+ property: 'log',
22
+ message: 'Use the project logger `DebugConfig.log` instead.',
23
+ },
24
+ ],
17
25
  },
18
26
  };
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.16.0] - 2026-04-10
4
+
5
+ ### Added
6
+
7
+ - Android: `PlayerView.isPictureInPictureEnabled` to enable or disable Picture in Picture availability dynamically after player initialization
8
+
9
+ ### Fixed
10
+
11
+ - Android: `OfflineDownloadRequest.minimumBitrate` not correctly parsed from React Native for offline rendition selection
12
+
13
+ ### Changed
14
+
15
+ - `DebugConfig.setDebugLoggingEnabled` now also controls JS-side debug logging; `console.log` calls in the `Network` and `Drm` modules are suppressed unless debug logging is enabled
16
+ - Update Bitmovin's native iOS SDK version to `3.111.0`
17
+
18
+ ### Fixed
19
+
20
+ - Android: Picture in Picture fragmented rendering when resizing the PiP window
21
+
22
+ ## [1.15.0] - 2026-03-27
23
+
24
+ ### Added
25
+
26
+ - Android: `PlaybackConfig.handleAudioFocus` to control whether the player pauses playback when audio focus is lost
27
+ - iOS: `PlayerView.isPictureInPictureEnabled` to enable or disable Picture in Picture availability dynamically after player initialization
28
+
29
+ ### Changed
30
+
31
+ - Update Bitmovin's native iOS SDK version to `3.110.0`
32
+
33
+ ### Fixed
34
+
35
+ - iOS, tvOS: Error/Warning code not forwarded to the React Native bridge on error and warning events
36
+
3
37
  ## [1.14.0] - 2026-03-20
4
38
 
5
39
  ### Added
@@ -88,7 +88,9 @@ class OfflineModule : Module() {
88
88
  else -> {}
89
89
  }
90
90
 
91
- val minimumBitRate = request["minimumBitrate"] as? Int
91
+ // ReactNative translates `number` to `Double` when de/serializing,
92
+ // so we need to manually parse the property to an `Int` here
93
+ val minimumBitRate = (request["minimumBitrate"] as? Number)?.toInt()
92
94
  if (minimumBitRate != null && minimumBitRate < 0) {
93
95
  throw OfflineException.InvalidRequest()
94
96
  }
@@ -1,14 +1,12 @@
1
1
  package com.bitmovin.player.reactnative
2
2
 
3
3
  import android.annotation.SuppressLint
4
- import android.app.PictureInPictureParams
5
4
  import android.content.Context
6
5
  import android.content.res.Configuration
7
6
  import android.os.Build
8
- import android.util.DisplayMetrics
7
+ import android.view.View
9
8
  import android.view.ViewGroup
10
9
  import android.view.ViewTreeObserver
11
- import android.view.WindowManager
12
10
  import android.widget.FrameLayout
13
11
  import androidx.lifecycle.DefaultLifecycleObserver
14
12
  import androidx.lifecycle.Lifecycle
@@ -17,10 +15,8 @@ import com.bitmovin.player.PlayerView
17
15
  import com.bitmovin.player.SubtitleView
18
16
  import com.bitmovin.player.api.Player
19
17
  import com.bitmovin.player.api.event.Event
20
- import com.bitmovin.player.api.event.EventListener
21
18
  import com.bitmovin.player.api.event.PlayerEvent
22
19
  import com.bitmovin.player.api.event.SourceEvent
23
- import com.bitmovin.player.api.event.on
24
20
  import com.bitmovin.player.api.ui.PlayerViewConfig
25
21
  import com.bitmovin.player.api.ui.ScalingMode
26
22
  import com.bitmovin.player.api.ui.UiConfig
@@ -28,6 +24,8 @@ import com.bitmovin.player.reactnative.converter.toJson
28
24
  import com.bitmovin.player.reactnative.converter.toUserInterfaceType
29
25
  import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler
30
26
  import com.bitmovin.player.reactnative.util.NonFiniteSanitizer
27
+ import com.facebook.react.ReactRootView
28
+ import com.facebook.react.views.view.ReactViewGroup
31
29
  import expo.modules.kotlin.AppContext
32
30
  import expo.modules.kotlin.viewevent.EventDispatcher
33
31
  import expo.modules.kotlin.viewevent.ViewEventCallback
@@ -118,6 +116,9 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
118
116
 
119
117
  private var playerInMediaSessionService: Player? = null
120
118
 
119
+ // Setting this flag to `true` in order for React Native to re-render our view when [requestLayout] is triggered
120
+ override val shouldUseAndroidLayout: Boolean = true
121
+
121
122
  private val activityLifecycleObserver = object : DefaultLifecycleObserver {
122
123
  override fun onStart(owner: LifecycleOwner) {
123
124
  if (playerInMediaSessionService != null) {
@@ -169,6 +170,8 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
169
170
  requestLayout()
170
171
  }
171
172
 
173
+ private val reparentHelper = RNPlayerViewReparentHelper()
174
+
172
175
  init {
173
176
  // React Native has a bug that dynamically added views sometimes aren't laid out again properly.
174
177
  // Since we dynamically add and remove SurfaceView under the hood this caused the player
@@ -211,6 +214,7 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
211
214
 
212
215
  activityLifecycle?.removeObserver(activityLifecycleObserver)
213
216
  viewTreeObserver.takeIf { it.isAlive }?.removeOnGlobalLayoutListener(globalLayoutListener)
217
+ reparentHelper.dispose()
214
218
 
215
219
  // cleanup all children views explicitly,
216
220
  // so that in case react native does some view caching we are 100% the child views of this view
@@ -320,9 +324,7 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
320
324
 
321
325
  this.pictureInPictureConfig = playerViewConfigWrapper?.pictureInPictureConfig ?: PictureInPictureConfig()
322
326
  val isPictureInPictureEnabled = isPictureInPictureEnabledOnPlayer || pictureInPictureConfig.isEnabled
323
- pictureInPictureHandler = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
324
- isPictureInPictureEnabled
325
- ) {
327
+ pictureInPictureHandler = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isPictureInPictureEnabled) {
326
328
  RNPictureInPictureHandler(
327
329
  currentActivity,
328
330
  player,
@@ -437,160 +439,15 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
437
439
  playerView.enterPictureInPicture()
438
440
  }
439
441
 
440
- // Force layout update for PiP mode and ensure proper sizing
441
- playerView.requestLayout()
442
- requestLayout()
443
-
444
- // Additional PiP-specific layout handling
445
- post {
446
- val activity = appContext.activityProvider?.currentActivity
447
- if (activity != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
448
- activity.isInPictureInPictureMode
449
- ) {
450
- // Get the actual PiP window dimensions from WindowManager
451
- val windowManager = activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager
452
- val pipWidth: Int
453
- val pipHeight: Int
454
-
455
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
456
- // Use WindowMetrics for API 30+
457
- val windowMetrics = windowManager.currentWindowMetrics
458
- val windowBounds = windowMetrics.bounds
459
- pipWidth = windowBounds.width()
460
- pipHeight = windowBounds.height()
461
- } else {
462
- // Use deprecated Display.getSize() for older APIs
463
- val displayMetrics = DisplayMetrics()
464
- @Suppress("DEPRECATION")
465
- windowManager.defaultDisplay.getMetrics(displayMetrics)
466
- pipWidth = displayMetrics.widthPixels
467
- pipHeight = displayMetrics.heightPixels
468
- }
469
-
470
- // Force the ExpoView to be resized to PiP dimensions
471
- // Preserve the original layout params type to avoid ClassCastException
472
- layoutParams?.let { currentParams ->
473
- currentParams.width = pipWidth
474
- currentParams.height = pipHeight
475
- // Re-assign to trigger layout update
476
- layoutParams = currentParams
477
- }
478
-
479
- // Ensure the ExpoView container is properly sized for PiP
480
- measure(
481
- MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
482
- MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
483
- )
484
- layout(left, top, left + pipWidth, top + pipHeight)
485
-
486
- // Ensure the intermediate container is properly sized for PiP
487
- playerContainer?.let { container ->
488
- // Preserve the original layout params type for the container
489
- container.layoutParams?.let { containerParams ->
490
- containerParams.width = pipWidth
491
- containerParams.height = pipHeight
492
- container.layoutParams = containerParams
493
- }
494
- container.measure(
495
- MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
496
- MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
497
- )
498
- container.layout(0, 0, pipWidth, pipHeight)
499
- }
500
-
501
- // Ensure the PlayerView is properly sized for PiP
502
- playerView.layoutParams = FrameLayout.LayoutParams(pipWidth, pipHeight)
503
- playerView.measure(
504
- MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
505
- MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
506
- )
507
- playerView.layout(0, 0, pipWidth, pipHeight)
508
-
509
- // Ensure the SubtitleView is properly sized for PiP
510
- subtitleView?.let { subtitleView ->
511
- subtitleView.layoutParams = FrameLayout.LayoutParams(pipWidth, pipHeight)
512
- subtitleView.measure(
513
- MeasureSpec.makeMeasureSpec(pipWidth, MeasureSpec.EXACTLY),
514
- MeasureSpec.makeMeasureSpec(pipHeight, MeasureSpec.EXACTLY),
515
- )
516
- subtitleView.layout(0, 0, pipWidth, pipHeight)
517
- subtitleView.invalidate()
518
- }
519
-
520
- // Try to force a redraw
521
- playerView.invalidate()
522
- playerContainer?.invalidate()
523
- invalidate()
524
- }
442
+ if (!reparentHelper.isActive) {
443
+ reparentHelper.reparent()
525
444
  }
526
445
  } else {
527
446
  if (playerView.isPictureInPicture) {
528
447
  playerView.exitPictureInPicture()
529
448
  }
530
449
 
531
- // Restore full size layout when exiting PiP
532
- post {
533
- // Reset ExpoView to full size
534
- layoutParams?.let { currentParams ->
535
- currentParams.width = LayoutParams.MATCH_PARENT
536
- currentParams.height = LayoutParams.MATCH_PARENT
537
- layoutParams = currentParams
538
- }
539
-
540
- // Reset intermediate container to full size
541
- playerContainer?.let { container ->
542
- container.layoutParams?.let { containerParams ->
543
- containerParams.width = LayoutParams.MATCH_PARENT
544
- containerParams.height = LayoutParams.MATCH_PARENT
545
- container.layoutParams = containerParams
546
- }
547
- }
548
-
549
- // Reset PlayerView to full size
550
- playerView.layoutParams = FrameLayout.LayoutParams(
551
- FrameLayout.LayoutParams.MATCH_PARENT,
552
- FrameLayout.LayoutParams.MATCH_PARENT,
553
- )
554
-
555
- // Reset SubtitleView to full size
556
- subtitleView?.let { subtitleView ->
557
- subtitleView.layoutParams = FrameLayout.LayoutParams(
558
- FrameLayout.LayoutParams.MATCH_PARENT,
559
- FrameLayout.LayoutParams.MATCH_PARENT,
560
- )
561
- }
562
-
563
- // Force layout updates
564
- measure(
565
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
566
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
567
- )
568
- layout(left, top, right, bottom)
569
-
570
- playerContainer?.let { container ->
571
- container.measure(
572
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
573
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
574
- )
575
- container.layout(0, 0, width, height)
576
- }
577
-
578
- playerView.measure(
579
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
580
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
581
- )
582
- playerView.layout(0, 0, width, height)
583
-
584
- // Ensure SubtitleView is properly measured and laid out when exiting PiP
585
- subtitleView?.let { subtitleView ->
586
- subtitleView.measure(
587
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
588
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
589
- )
590
- subtitleView.layout(0, 0, width, height)
591
- subtitleView.invalidate()
592
- }
593
- }
450
+ reparentHelper.tryRestore()
594
451
  }
595
452
  }
596
453
 
@@ -720,6 +577,9 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
720
577
  }
721
578
 
722
579
  fun setPictureInPicture(isPictureInPicture: Boolean) {
580
+ if (isPictureInPicture && !pictureInPictureConfig.isEnabled) {
581
+ return
582
+ }
723
583
  requestedPictureInPictureValue = isPictureInPicture
724
584
  playerView?.let {
725
585
  if (it.isPictureInPicture == isPictureInPicture) {
@@ -762,19 +622,98 @@ class RNPlayerView(context: Context, appContext: AppContext) : ExpoView(context,
762
622
  }
763
623
  }
764
624
 
765
- /**
766
- * Try to measure and update this view layout as much as possible to
767
- * avoid layout problems related to React or old layout values present
768
- * in `playerView` due to being previously attached to a different parent.
769
- */
770
- override fun requestLayout() {
771
- super.requestLayout()
772
- post {
773
- measure(
774
- MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
775
- MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
625
+ fun setIsPictureInPictureEnabled(isEnabled: Boolean) {
626
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
627
+ return
628
+ }
629
+ pictureInPictureConfig = pictureInPictureConfig.copy(isEnabled = isEnabled)
630
+ if (isEnabled && pictureInPictureHandler == null) {
631
+ val currentActivity = appContext.activityProvider?.currentActivity ?: return
632
+ val player = playerView?.player ?: return
633
+ pictureInPictureHandler = RNPictureInPictureHandler(currentActivity, player, pictureInPictureConfig)
634
+ playerView?.setPictureInPictureHandler(pictureInPictureHandler)
635
+ } else if (!isEnabled && pictureInPictureHandler != null) {
636
+ pictureInPictureHandler?.dispose()
637
+ pictureInPictureHandler = null
638
+ playerView?.setPictureInPictureHandler(null)
639
+ }
640
+ }
641
+
642
+ // React Native doesn't properly handle PiP layout transitions.
643
+ // During PiP mode, we temporarily move the view higher up the hierarchy to the ReactRoot.
644
+ // This prevents fragmented rendering when the user resizes the PiP window.
645
+ // On PiP close, we re-arrange the view hierarchy to its original state
646
+ private inner class RNPlayerViewReparentHelper {
647
+ private inner class ViewHolder(
648
+ val reactRoot: ReactRootView,
649
+ val playerParentParent: ViewGroup,
650
+ val playerParent: ReactViewGroup,
651
+ val playerParentIndex: Int,
652
+ )
653
+
654
+ private inline fun <reified T : View> View.findParentOfType(): T? {
655
+ var view = this
656
+ do {
657
+ view = view.parent as? View ?: return null
658
+ } while (view !is T)
659
+ return view
660
+ }
661
+
662
+ private var viewHolder: ViewHolder? = null
663
+
664
+ val isActive: Boolean
665
+ get() = viewHolder != null
666
+
667
+ private val globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
668
+ val reactRoot = viewHolder?.reactRoot ?: return@OnGlobalLayoutListener
669
+ val view = this@RNPlayerView
670
+ view.measure(
671
+ MeasureSpec.makeMeasureSpec(reactRoot.width, MeasureSpec.EXACTLY),
672
+ MeasureSpec.makeMeasureSpec(reactRoot.height, MeasureSpec.EXACTLY),
673
+ )
674
+ view.layout(0, 0, view.measuredWidth, view.measuredHeight)
675
+ }
676
+
677
+ fun reparent() {
678
+ val playerParent = this@RNPlayerView.findParentOfType<ReactViewGroup>() ?: return
679
+ val playerParentParent = playerParent.parent as? ViewGroup ?: return
680
+ val reactRoot = playerParent.findParentOfType<ReactRootView>() ?: return
681
+
682
+ viewHolder = ViewHolder(
683
+ reactRoot = reactRoot,
684
+ playerParentParent = playerParentParent,
685
+ playerParent = playerParent,
686
+ playerParentIndex = playerParentParent.indexOfChild(playerParent),
776
687
  )
777
- layout(left, top, right, bottom)
688
+
689
+ playerParentParent.removeView(playerParent)
690
+ reactRoot.addView(playerParent)
691
+
692
+ // We attach the global layout listener to a playerParent,
693
+ // but inside the callback we are measuring each root.
694
+ // This is because the root is the first view layer that gets transformed in PiP mode.
695
+ // Measuring and layouting this should cascade down the viewHierarchy.
696
+ playerParent.viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener)
697
+ }
698
+
699
+ fun tryRestore() {
700
+ val viewHolder = viewHolder ?: return
701
+ viewHolder.reactRoot.removeView(viewHolder.playerParent)
702
+ try {
703
+ viewHolder.playerParentParent.addView(viewHolder.playerParent, viewHolder.playerParentIndex)
704
+ } catch (_: Exception) {
705
+ // In case the view hierarchy layout has changed an exception will be thrown while adding the view
706
+ // This should never happen, but we can not be sure what react-native does under the hood.
707
+ // As a fallback add the view without index (will be added as last view)
708
+ viewHolder.playerParentParent.addView(viewHolder.playerParent)
709
+ }
710
+
711
+ dispose()
712
+ }
713
+
714
+ fun dispose() {
715
+ viewHolder?.playerParent?.viewTreeObserver?.removeOnGlobalLayoutListener(globalLayoutListener)
716
+ this.viewHolder = null
778
717
  }
779
718
  }
780
719
  }
@@ -94,6 +94,11 @@ class RNPlayerViewManager : Module() {
94
94
  view.updatePictureInPictureActions(pictureInPictureActions.toPictureInPictureActions())
95
95
  }
96
96
 
97
+ AsyncFunction("setIsPictureInPictureEnabled") { view: RNPlayerView, isEnabled: Boolean ->
98
+ view.setIsPictureInPictureEnabled(isEnabled)
99
+ updateAutoPictureInPictureRegistration(view)
100
+ }
101
+
97
102
  Events(
98
103
  "onBmpEvent",
99
104
  "onBmpPlayerError",
@@ -165,6 +165,7 @@ fun Map<String, Any?>.toPlaybackConfig(): PlaybackConfig = PlaybackConfig().appl
165
165
  withBoolean("isAutoplayEnabled") { isAutoplayEnabled = it }
166
166
  withBoolean("isMuted") { isMuted = it }
167
167
  withBoolean("isTimeShiftEnabled") { isTimeShiftEnabled = it }
168
+ withBoolean("handleAudioFocus") { handleAudioFocus = it }
168
169
  }
169
170
 
170
171
  fun Map<String, Any?>.toStyleConfig(): StyleConfig = StyleConfig().apply {
@@ -53,14 +53,15 @@ class RNPictureInPictureHandler(
53
53
  playerIsPlaying = false
54
54
  }
55
55
 
56
+ private val onVideoPlaybackQualityChanged: (PlayerEvent.VideoPlaybackQualityChanged) -> Unit = {
57
+ updatePictureInPictureParams()
58
+ }
59
+
56
60
  init {
57
61
  playerIsPlaying = player.isPlaying
58
62
  subscribeToPlayerPlaybackEvents()
59
63
  updatePictureInPictureParams()
60
-
61
- player.on<PlayerEvent.VideoPlaybackQualityChanged> {
62
- updatePictureInPictureParams()
63
- }
64
+ player.on(onVideoPlaybackQualityChanged)
64
65
  }
65
66
 
66
67
  private fun subscribeToPlayerPlaybackEvents() {
@@ -88,7 +89,7 @@ class RNPictureInPictureHandler(
88
89
  player.off<PlayerEvent.AdBreakFinished>(setPlayerIsNotPlaying)
89
90
  }
90
91
 
91
- private fun getPiPAspectRation() = player.playbackVideoData
92
+ private fun getPiPAspectRatio() = player.playbackVideoData
92
93
  ?.let { Rational(it.width, it.height) }
93
94
  ?: Rational(16, 9)
94
95
 
@@ -119,7 +120,7 @@ class RNPictureInPictureHandler(
119
120
  private fun buildPictureInPictureParams(
120
121
  autoEnterEnabled: Boolean = pictureInPictureConfig.isAutoPipEnabled && playerIsPlaying,
121
122
  ) = PictureInPictureParams.Builder()
122
- .setAspectRatio(getPiPAspectRation())
123
+ .setAspectRatio(getPiPAspectRatio())
123
124
  .setActions(pictureInPictureActionHandler.buildRemoteActions())
124
125
  .apply {
125
126
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -135,6 +136,7 @@ class RNPictureInPictureHandler(
135
136
  fun dispose() {
136
137
  pictureInPictureActionHandler.dispose()
137
138
  unsubscribeToPlayerPlaybackEvents()
139
+ player.off(onVideoPlaybackQualityChanged)
138
140
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
139
141
  activity.setPictureInPictureParams(
140
142
  PictureInPictureParams.Builder()
@@ -6,5 +6,5 @@ import { PlayerViewProps } from './properties';
6
6
  *
7
7
  * @param options configuration options
8
8
  */
9
- export declare function PlayerView({ viewRef, style, player, config, fullscreenHandler, customMessageHandler, isFullscreenRequested, scalingMode, isPictureInPictureRequested, pictureInPictureActions, ...props }: PlayerViewProps): React.JSX.Element | null;
9
+ export declare function PlayerView({ viewRef, style, player, config, fullscreenHandler, customMessageHandler, isFullscreenRequested, scalingMode, isPictureInPictureRequested, pictureInPictureActions, isPictureInPictureEnabled, ...props }: PlayerViewProps): React.JSX.Element | null;
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PlayerView/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAOtE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAa/C;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,MAAM,EACN,MAAM,EACN,iBAAiB,EACjB,oBAAoB,EACpB,qBAA6B,EAC7B,WAAW,EACX,2BAAmC,EACnC,uBAAuB,EACvB,GAAG,KAAK,EACT,EAAE,eAAe,4BA6KjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PlayerView/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAOtE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAa/C;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,MAAM,EACN,MAAM,EACN,iBAAiB,EACjB,oBAAoB,EACpB,qBAA6B,EAC7B,WAAW,EACX,2BAAmC,EACnC,uBAAuB,EACvB,yBAAyB,EACzB,GAAG,KAAK,EACT,EAAE,eAAe,4BAqLjB"}
@@ -20,7 +20,7 @@ const styles = StyleSheet.create({
20
20
  *
21
21
  * @param options configuration options
22
22
  */
23
- export function PlayerView({ viewRef, style, player, config, fullscreenHandler, customMessageHandler, isFullscreenRequested = false, scalingMode, isPictureInPictureRequested = false, pictureInPictureActions, ...props }) {
23
+ export function PlayerView({ viewRef, style, player, config, fullscreenHandler, customMessageHandler, isFullscreenRequested = false, scalingMode, isPictureInPictureRequested = false, pictureInPictureActions, isPictureInPictureEnabled, ...props }) {
24
24
  // Keep the device awake while the PlayerView is mounted
25
25
  useKeepAwake();
26
26
  const nativeView = useRef(viewRef?.current || null);
@@ -73,6 +73,11 @@ export function PlayerView({ viewRef, style, player, config, fullscreenHandler,
73
73
  void nativeView.current?.updatePictureInPictureActions(pictureInPictureActions);
74
74
  }
75
75
  }, [isPlayerInitialized, pictureInPictureActions]);
76
+ useEffect(() => {
77
+ if (isPlayerInitialized && isPictureInPictureEnabled != null) {
78
+ void nativeView.current?.setIsPictureInPictureEnabled(isPictureInPictureEnabled);
79
+ }
80
+ }, [isPlayerInitialized, isPictureInPictureEnabled]);
76
81
  if (!isPlayerInitialized) {
77
82
  return null;
78
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/PlayerView/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { RefObject, useEffect, useRef, useState } from 'react';\nimport { StyleSheet } from 'react-native';\nimport { useKeepAwake } from 'expo-keep-awake';\nimport { NativePlayerView, NativePlayerViewConfig } from './native';\nimport { useProxy } from '../../hooks/useProxy';\nimport { FullscreenHandlerBridge } from '../../ui/fullscreenhandlerbridge';\nimport { CustomMessageHandlerBridge } from '../../ui/custommessagehandlerbridge';\nimport { PlayerViewProps } from './properties';\nimport { PictureInPictureAction } from './pictureInPictureAction';\nimport { addPlatformToMetadataEvent } from '../../utils/metadataPlatform';\n\n/**\n * Base style that initializes the native view frame when no width/height prop has been set.\n */\nconst styles = StyleSheet.create({\n baseStyle: {\n alignSelf: 'stretch',\n },\n});\n\n/**\n * Component that provides the Bitmovin Player UI and default UI handling to an attached `Player` instance.\n * This component needs a `Player` instance to work properly so make sure one is passed to it as a prop.\n *\n * @param options configuration options\n */\nexport function PlayerView({\n viewRef,\n style,\n player,\n config,\n fullscreenHandler,\n customMessageHandler,\n isFullscreenRequested = false,\n scalingMode,\n isPictureInPictureRequested = false,\n pictureInPictureActions,\n ...props\n}: PlayerViewProps) {\n // Keep the device awake while the PlayerView is mounted\n useKeepAwake();\n\n const nativeView = useRef<InternalPlayerViewRef>(viewRef?.current || null);\n\n // Native events proxy helper.\n const proxy = useProxy();\n // Style resulting from merging `baseStyle` and `props.style`.\n const nativeViewStyle = StyleSheet.flatten([styles.baseStyle, style]);\n\n const fullscreenBridge: React.RefObject<FullscreenHandlerBridge | undefined> =\n useRef(undefined);\n if (fullscreenHandler && !fullscreenBridge.current) {\n fullscreenBridge.current = new FullscreenHandlerBridge();\n }\n if (fullscreenBridge.current) {\n fullscreenBridge.current.setFullscreenHandler(fullscreenHandler);\n }\n\n const customMessageHandlerBridge: React.RefObject<\n CustomMessageHandlerBridge | undefined\n > = useRef(undefined);\n if (customMessageHandler && !customMessageHandlerBridge.current) {\n customMessageHandlerBridge.current = new CustomMessageHandlerBridge();\n }\n if (customMessageHandlerBridge.current && customMessageHandler) {\n customMessageHandlerBridge.current.setCustomMessageHandler(\n customMessageHandler\n );\n }\n\n const nativePlayerViewConfig: NativePlayerViewConfig = {\n playerId: player.nativeId,\n customMessageHandlerBridgeId: customMessageHandlerBridge.current?.nativeId,\n enableBackgroundPlayback:\n player.config?.playbackConfig?.isBackgroundPlaybackEnabled,\n isPictureInPictureEnabledOnPlayer:\n player.config?.playbackConfig?.isPictureInPictureEnabled,\n userInterfaceTypeName: player.config?.styleConfig?.userInterfaceType,\n playerViewConfig: config,\n };\n\n const [isPlayerInitialized, setIsPlayerInitialized] = useState(false);\n\n useEffect(() => {\n void player.initialize().then(() => {\n setIsPlayerInitialized(true);\n // call attach player on native view if switched to AsyncFunction for RNPlayerViewExpo\n });\n\n return () => {\n fullscreenBridge.current?.destroy();\n fullscreenBridge.current = undefined;\n customMessageHandlerBridge.current?.destroy();\n customMessageHandlerBridge.current = undefined;\n };\n }, [player, fullscreenBridge, customMessageHandlerBridge]);\n\n useEffect(() => {\n if (isPlayerInitialized && viewRef) {\n viewRef.current = nativeView.current;\n }\n }, [isPlayerInitialized, viewRef, nativeView]);\n\n useEffect(() => {\n if (isPlayerInitialized && pictureInPictureActions != null) {\n void nativeView.current?.updatePictureInPictureActions(\n pictureInPictureActions\n );\n }\n }, [isPlayerInitialized, pictureInPictureActions]);\n\n if (!isPlayerInitialized) {\n return null;\n }\n\n return (\n <NativePlayerView\n ref={nativeView}\n style={nativeViewStyle}\n config={nativePlayerViewConfig}\n isFullscreenRequested={isFullscreenRequested}\n isPictureInPictureRequested={isPictureInPictureRequested}\n scalingMode={scalingMode}\n fullscreenBridgeId={fullscreenBridge.current?.nativeId}\n onBmpAdBreakFinished={proxy(props.onAdBreakFinished)}\n onBmpAdBreakStarted={proxy(props.onAdBreakStarted)}\n onBmpAdClicked={proxy(props.onAdClicked)}\n onBmpAdError={proxy(props.onAdError)}\n onBmpAdFinished={proxy(props.onAdFinished)}\n onBmpAdManifestLoad={proxy(props.onAdManifestLoad)}\n onBmpAdManifestLoaded={proxy(props.onAdManifestLoaded)}\n onBmpAdQuartile={proxy(props.onAdQuartile)}\n onBmpAdScheduled={proxy(props.onAdScheduled)}\n onBmpAdSkipped={proxy(props.onAdSkipped)}\n onBmpAdStarted={proxy(props.onAdStarted)}\n onBmpCastAvailable={proxy(props.onCastAvailable)}\n onBmpCastPaused={proxy(props.onCastPaused)}\n onBmpCastPlaybackFinished={proxy(props.onCastPlaybackFinished)}\n onBmpCastPlaying={proxy(props.onCastPlaying)}\n onBmpCastStarted={proxy(props.onCastStarted)}\n onBmpCastStart={proxy(props.onCastStart)}\n onBmpCastStopped={proxy(props.onCastStopped)}\n onBmpCastTimeUpdated={proxy(props.onCastTimeUpdated)}\n onBmpCastWaitingForDevice={proxy(props.onCastWaitingForDevice)}\n onBmpCueEnter={proxy(props.onCueEnter)}\n onBmpCueExit={proxy(props.onCueExit)}\n onBmpMetadata={\n props.onMetadata\n ? (e) => props.onMetadata?.(addPlatformToMetadataEvent(e.nativeEvent))\n : undefined\n }\n onBmpMetadataParsed={\n props.onMetadataParsed\n ? (e) =>\n props.onMetadataParsed?.(\n addPlatformToMetadataEvent(e.nativeEvent)\n )\n : undefined\n }\n onBmpDestroy={proxy(props.onDestroy)}\n onBmpEvent={proxy(props.onEvent)}\n onBmpFullscreenEnabled={proxy(props.onFullscreenEnabled)}\n onBmpFullscreenDisabled={proxy(props.onFullscreenDisabled)}\n onBmpFullscreenEnter={proxy(props.onFullscreenEnter)}\n onBmpFullscreenExit={proxy(props.onFullscreenExit)}\n onBmpMuted={proxy(props.onMuted)}\n onBmpPaused={proxy(props.onPaused)}\n onBmpPictureInPictureAvailabilityChanged={proxy(\n props.onPictureInPictureAvailabilityChanged\n )}\n onBmpPictureInPictureEnter={proxy(props.onPictureInPictureEnter)}\n onBmpPictureInPictureEntered={proxy(props.onPictureInPictureEntered)}\n onBmpPictureInPictureExit={proxy(props.onPictureInPictureExit)}\n onBmpPictureInPictureExited={proxy(props.onPictureInPictureExited)}\n onBmpPlay={proxy(props.onPlay)}\n onBmpPlaybackFinished={proxy(props.onPlaybackFinished)}\n onBmpPlaybackSpeedChanged={proxy(props.onPlaybackSpeedChanged)}\n onBmpPlayerActive={proxy(props.onPlayerActive)}\n onBmpPlayerError={proxy(props.onPlayerError)}\n onBmpPlayerWarning={proxy(props.onPlayerWarning)}\n onBmpPlaying={proxy(props.onPlaying)}\n onBmpReady={proxy(props.onReady)}\n onBmpSeek={proxy(props.onSeek)}\n onBmpSeeked={proxy(props.onSeeked)}\n onBmpTimeShift={proxy(props.onTimeShift)}\n onBmpTimeShifted={proxy(props.onTimeShifted)}\n onBmpStallStarted={proxy(props.onStallStarted)}\n onBmpStallEnded={proxy(props.onStallEnded)}\n onBmpSourceError={proxy(props.onSourceError)}\n onBmpSourceLoad={proxy(props.onSourceLoad)}\n onBmpSourceLoaded={proxy(props.onSourceLoaded)}\n onBmpSourceUnloaded={proxy(props.onSourceUnloaded)}\n onBmpSourceWarning={proxy(props.onSourceWarning)}\n onBmpAudioAdded={proxy(props.onAudioAdded)}\n onBmpAudioChanged={proxy(props.onAudioChanged)}\n onBmpAudioRemoved={proxy(props.onAudioRemoved)}\n onBmpSubtitleAdded={proxy(props.onSubtitleAdded)}\n onBmpSubtitleChanged={proxy(props.onSubtitleChanged)}\n onBmpSubtitleRemoved={proxy(props.onSubtitleRemoved)}\n onBmpTimeChanged={proxy(props.onTimeChanged)}\n onBmpUnmuted={proxy(props.onUnmuted)}\n onBmpVideoDownloadQualityChanged={proxy(\n props.onVideoDownloadQualityChanged\n )}\n onBmpVideoPlaybackQualityChanged={proxy(\n props.onVideoPlaybackQualityChanged\n )}\n onBmpDownloadFinished={proxy(props.onDownloadFinished)}\n onBmpFairplayLicenseAcquired={proxy(props.onFairplayLicenseAcquired)}\n />\n );\n}\n\ninterface InternalPlayerViewRef extends RefObject<any> {\n /**\n * Update Picture in Picture actions that should be displayed on the Picture in Picture window.\n * Ideally we would just pass the props to the `NativePlayerView`, but due to a React Native limitation,\n * the props aren't passed to the native module when PiP is active on Android.\n */\n updatePictureInPictureActions: (\n actions: PictureInPictureAction[]\n ) => Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/PlayerView/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { RefObject, useEffect, useRef, useState } from 'react';\nimport { StyleSheet } from 'react-native';\nimport { useKeepAwake } from 'expo-keep-awake';\nimport { NativePlayerView, NativePlayerViewConfig } from './native';\nimport { useProxy } from '../../hooks/useProxy';\nimport { FullscreenHandlerBridge } from '../../ui/fullscreenhandlerbridge';\nimport { CustomMessageHandlerBridge } from '../../ui/custommessagehandlerbridge';\nimport { PlayerViewProps } from './properties';\nimport { PictureInPictureAction } from './pictureInPictureAction';\nimport { addPlatformToMetadataEvent } from '../../utils/metadataPlatform';\n\n/**\n * Base style that initializes the native view frame when no width/height prop has been set.\n */\nconst styles = StyleSheet.create({\n baseStyle: {\n alignSelf: 'stretch',\n },\n});\n\n/**\n * Component that provides the Bitmovin Player UI and default UI handling to an attached `Player` instance.\n * This component needs a `Player` instance to work properly so make sure one is passed to it as a prop.\n *\n * @param options configuration options\n */\nexport function PlayerView({\n viewRef,\n style,\n player,\n config,\n fullscreenHandler,\n customMessageHandler,\n isFullscreenRequested = false,\n scalingMode,\n isPictureInPictureRequested = false,\n pictureInPictureActions,\n isPictureInPictureEnabled,\n ...props\n}: PlayerViewProps) {\n // Keep the device awake while the PlayerView is mounted\n useKeepAwake();\n\n const nativeView = useRef<InternalPlayerViewRef>(viewRef?.current || null);\n\n // Native events proxy helper.\n const proxy = useProxy();\n // Style resulting from merging `baseStyle` and `props.style`.\n const nativeViewStyle = StyleSheet.flatten([styles.baseStyle, style]);\n\n const fullscreenBridge: React.RefObject<FullscreenHandlerBridge | undefined> =\n useRef(undefined);\n if (fullscreenHandler && !fullscreenBridge.current) {\n fullscreenBridge.current = new FullscreenHandlerBridge();\n }\n if (fullscreenBridge.current) {\n fullscreenBridge.current.setFullscreenHandler(fullscreenHandler);\n }\n\n const customMessageHandlerBridge: React.RefObject<\n CustomMessageHandlerBridge | undefined\n > = useRef(undefined);\n if (customMessageHandler && !customMessageHandlerBridge.current) {\n customMessageHandlerBridge.current = new CustomMessageHandlerBridge();\n }\n if (customMessageHandlerBridge.current && customMessageHandler) {\n customMessageHandlerBridge.current.setCustomMessageHandler(\n customMessageHandler\n );\n }\n\n const nativePlayerViewConfig: NativePlayerViewConfig = {\n playerId: player.nativeId,\n customMessageHandlerBridgeId: customMessageHandlerBridge.current?.nativeId,\n enableBackgroundPlayback:\n player.config?.playbackConfig?.isBackgroundPlaybackEnabled,\n isPictureInPictureEnabledOnPlayer:\n player.config?.playbackConfig?.isPictureInPictureEnabled,\n userInterfaceTypeName: player.config?.styleConfig?.userInterfaceType,\n playerViewConfig: config,\n };\n\n const [isPlayerInitialized, setIsPlayerInitialized] = useState(false);\n\n useEffect(() => {\n void player.initialize().then(() => {\n setIsPlayerInitialized(true);\n // call attach player on native view if switched to AsyncFunction for RNPlayerViewExpo\n });\n\n return () => {\n fullscreenBridge.current?.destroy();\n fullscreenBridge.current = undefined;\n customMessageHandlerBridge.current?.destroy();\n customMessageHandlerBridge.current = undefined;\n };\n }, [player, fullscreenBridge, customMessageHandlerBridge]);\n\n useEffect(() => {\n if (isPlayerInitialized && viewRef) {\n viewRef.current = nativeView.current;\n }\n }, [isPlayerInitialized, viewRef, nativeView]);\n\n useEffect(() => {\n if (isPlayerInitialized && pictureInPictureActions != null) {\n void nativeView.current?.updatePictureInPictureActions(\n pictureInPictureActions\n );\n }\n }, [isPlayerInitialized, pictureInPictureActions]);\n\n useEffect(() => {\n if (isPlayerInitialized && isPictureInPictureEnabled != null) {\n void nativeView.current?.setIsPictureInPictureEnabled(\n isPictureInPictureEnabled\n );\n }\n }, [isPlayerInitialized, isPictureInPictureEnabled]);\n\n if (!isPlayerInitialized) {\n return null;\n }\n\n return (\n <NativePlayerView\n ref={nativeView}\n style={nativeViewStyle}\n config={nativePlayerViewConfig}\n isFullscreenRequested={isFullscreenRequested}\n isPictureInPictureRequested={isPictureInPictureRequested}\n scalingMode={scalingMode}\n fullscreenBridgeId={fullscreenBridge.current?.nativeId}\n onBmpAdBreakFinished={proxy(props.onAdBreakFinished)}\n onBmpAdBreakStarted={proxy(props.onAdBreakStarted)}\n onBmpAdClicked={proxy(props.onAdClicked)}\n onBmpAdError={proxy(props.onAdError)}\n onBmpAdFinished={proxy(props.onAdFinished)}\n onBmpAdManifestLoad={proxy(props.onAdManifestLoad)}\n onBmpAdManifestLoaded={proxy(props.onAdManifestLoaded)}\n onBmpAdQuartile={proxy(props.onAdQuartile)}\n onBmpAdScheduled={proxy(props.onAdScheduled)}\n onBmpAdSkipped={proxy(props.onAdSkipped)}\n onBmpAdStarted={proxy(props.onAdStarted)}\n onBmpCastAvailable={proxy(props.onCastAvailable)}\n onBmpCastPaused={proxy(props.onCastPaused)}\n onBmpCastPlaybackFinished={proxy(props.onCastPlaybackFinished)}\n onBmpCastPlaying={proxy(props.onCastPlaying)}\n onBmpCastStarted={proxy(props.onCastStarted)}\n onBmpCastStart={proxy(props.onCastStart)}\n onBmpCastStopped={proxy(props.onCastStopped)}\n onBmpCastTimeUpdated={proxy(props.onCastTimeUpdated)}\n onBmpCastWaitingForDevice={proxy(props.onCastWaitingForDevice)}\n onBmpCueEnter={proxy(props.onCueEnter)}\n onBmpCueExit={proxy(props.onCueExit)}\n onBmpMetadata={\n props.onMetadata\n ? (e) => props.onMetadata?.(addPlatformToMetadataEvent(e.nativeEvent))\n : undefined\n }\n onBmpMetadataParsed={\n props.onMetadataParsed\n ? (e) =>\n props.onMetadataParsed?.(\n addPlatformToMetadataEvent(e.nativeEvent)\n )\n : undefined\n }\n onBmpDestroy={proxy(props.onDestroy)}\n onBmpEvent={proxy(props.onEvent)}\n onBmpFullscreenEnabled={proxy(props.onFullscreenEnabled)}\n onBmpFullscreenDisabled={proxy(props.onFullscreenDisabled)}\n onBmpFullscreenEnter={proxy(props.onFullscreenEnter)}\n onBmpFullscreenExit={proxy(props.onFullscreenExit)}\n onBmpMuted={proxy(props.onMuted)}\n onBmpPaused={proxy(props.onPaused)}\n onBmpPictureInPictureAvailabilityChanged={proxy(\n props.onPictureInPictureAvailabilityChanged\n )}\n onBmpPictureInPictureEnter={proxy(props.onPictureInPictureEnter)}\n onBmpPictureInPictureEntered={proxy(props.onPictureInPictureEntered)}\n onBmpPictureInPictureExit={proxy(props.onPictureInPictureExit)}\n onBmpPictureInPictureExited={proxy(props.onPictureInPictureExited)}\n onBmpPlay={proxy(props.onPlay)}\n onBmpPlaybackFinished={proxy(props.onPlaybackFinished)}\n onBmpPlaybackSpeedChanged={proxy(props.onPlaybackSpeedChanged)}\n onBmpPlayerActive={proxy(props.onPlayerActive)}\n onBmpPlayerError={proxy(props.onPlayerError)}\n onBmpPlayerWarning={proxy(props.onPlayerWarning)}\n onBmpPlaying={proxy(props.onPlaying)}\n onBmpReady={proxy(props.onReady)}\n onBmpSeek={proxy(props.onSeek)}\n onBmpSeeked={proxy(props.onSeeked)}\n onBmpTimeShift={proxy(props.onTimeShift)}\n onBmpTimeShifted={proxy(props.onTimeShifted)}\n onBmpStallStarted={proxy(props.onStallStarted)}\n onBmpStallEnded={proxy(props.onStallEnded)}\n onBmpSourceError={proxy(props.onSourceError)}\n onBmpSourceLoad={proxy(props.onSourceLoad)}\n onBmpSourceLoaded={proxy(props.onSourceLoaded)}\n onBmpSourceUnloaded={proxy(props.onSourceUnloaded)}\n onBmpSourceWarning={proxy(props.onSourceWarning)}\n onBmpAudioAdded={proxy(props.onAudioAdded)}\n onBmpAudioChanged={proxy(props.onAudioChanged)}\n onBmpAudioRemoved={proxy(props.onAudioRemoved)}\n onBmpSubtitleAdded={proxy(props.onSubtitleAdded)}\n onBmpSubtitleChanged={proxy(props.onSubtitleChanged)}\n onBmpSubtitleRemoved={proxy(props.onSubtitleRemoved)}\n onBmpTimeChanged={proxy(props.onTimeChanged)}\n onBmpUnmuted={proxy(props.onUnmuted)}\n onBmpVideoDownloadQualityChanged={proxy(\n props.onVideoDownloadQualityChanged\n )}\n onBmpVideoPlaybackQualityChanged={proxy(\n props.onVideoPlaybackQualityChanged\n )}\n onBmpDownloadFinished={proxy(props.onDownloadFinished)}\n onBmpFairplayLicenseAcquired={proxy(props.onFairplayLicenseAcquired)}\n />\n );\n}\n\ninterface InternalPlayerViewRef extends RefObject<any> {\n /**\n * Update Picture in Picture actions that should be displayed on the Picture in Picture window.\n * Ideally we would just pass the props to the `NativePlayerView`, but due to a React Native limitation,\n * the props aren't passed to the native module when PiP is active on Android.\n */\n updatePictureInPictureActions: (\n actions: PictureInPictureAction[]\n ) => Promise<void>;\n /**\n * Enables or disables Picture in Picture mode availability.\n */\n setIsPictureInPictureEnabled: (isEnabled: boolean) => Promise<void>;\n}\n"]}
@@ -65,6 +65,13 @@ export interface BasePlayerViewProps {
65
65
  * - iOS: All actions enabled
66
66
  */
67
67
  pictureInPictureActions?: PictureInPictureAction[];
68
+ /**
69
+ * Enables or disables Picture in Picture mode availability.
70
+ * When disabled, `isPictureInPictureRequested` property has no effect.
71
+ *
72
+ * Can be changed dynamically after the player is initialized.
73
+ */
74
+ isPictureInPictureEnabled?: boolean;
68
75
  }
69
76
  /**
70
77
  * {@link PlayerView} component props.
@@ -1 +1 @@
1
- {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../../src/components/PlayerView/properties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAEtC;;OAEG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAE5C;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;OAGG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAE1B;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACpD;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,mBAAmB,EAAE,gBAAgB;IAC5E,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACzB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../../src/components/PlayerView/properties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAEtC;;OAEG;IACH,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAE5C;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B;;;OAGG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAE1B;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAC;IAEnD;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,mBAAmB,EAAE,gBAAgB;IAC5E,OAAO,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;IACzB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"properties.js","sourceRoot":"","sources":["../../../src/components/PlayerView/properties.ts"],"names":[],"mappings":"","sourcesContent":["import { PlayerViewEvents } from './events';\nimport { Player } from '../../player';\nimport { FullscreenHandler, CustomMessageHandler } from '../../ui';\nimport { ScalingMode } from '../../styleConfig';\nimport { ViewStyle } from 'react-native';\nimport { PlayerViewConfig } from './playerViewConfig';\nimport { PictureInPictureAction } from './pictureInPictureAction';\nimport { RefObject } from 'react';\n\n/**\n * Base `PlayerView` component props.\n * Used to establish common props between `NativePlayerView` and {@link PlayerView}.\n */\nexport interface BasePlayerViewProps {\n ref?: RefObject<null>;\n /**\n * The {@link FullscreenHandler} that is used by the {@link PlayerView} to control the fullscreen mode.\n */\n fullscreenHandler?: FullscreenHandler;\n\n /**\n * The {@link CustomMessageHandler} that can be used to directly communicate with the embedded Bitmovin Web UI.\n */\n customMessageHandler?: CustomMessageHandler;\n\n /**\n * Can be set to `true` to request fullscreen mode, or `false` to request exit of fullscreen mode.\n * Should not be used to get the current fullscreen state. Use {@link PlayerViewEvents.onFullscreenEnter} and {@link PlayerViewEvents.onFullscreenExit}\n * or the {@link FullscreenHandler.isFullscreenActive} property to get the current state.\n * Using this property to change the fullscreen state, it is ensured that the embedded Player UI is also aware\n * of potential fullscreen state changes.\n * To use this property, a {@link FullscreenHandler} must be set.\n */\n isFullscreenRequested?: boolean;\n\n /**\n * A value defining how the video is displayed within the parent container's bounds.\n * Possible values are defined in {@link ScalingMode}.\n */\n scalingMode?: ScalingMode;\n\n /**\n * Can be set to `true` to request Picture in Picture mode, or `false` to request exit of Picture in Picture mode.\n * Should not be used to get the current Picture in Picture state. Use {@link PlayerViewEvents.onPictureInPictureEnter} and {@link PlayerViewEvents.onPictureInPictureExit}.\n */\n isPictureInPictureRequested?: boolean;\n\n /**\n * Style of the {@link PlayerView}.\n */\n style?: ViewStyle;\n\n /**\n * Configures the visual presentation and behaviour of the {@link PlayerView}.\n * The value must not be altered after setting it initially.\n */\n config?: PlayerViewConfig;\n\n /**\n * Picture in Picture actions that should be displayed on the Picture in Picture window.\n *\n * Limitations:\n * - On Android if an empty list is passed and {@link MediaControlConfig.isEnabled} is set to true\n * play, pause, next, and previous controls will appear, due to the default Android Picture in Picture implementation:\n * https://developer.android.com/develop/ui/views/picture-in-picture#add_controls\n * Set {@link MediaControlConfig.isEnabled} to false if this is\n * not the desired behaviour.\n * - on iOS/tvOS if {@link PictureInPictureAction.TogglePlayback} is not specified also other actions are\n * disabled due to OS limitations.\n *\n * Default value is `undefined`, which translates to:\n * - Android: No actions, unless {@link MediaControlConfig.isEnabled} is set to true\n * - iOS: All actions enabled\n */\n pictureInPictureActions?: PictureInPictureAction[];\n}\n\n/**\n * {@link PlayerView} component props.\n */\nexport interface PlayerViewProps extends BasePlayerViewProps, PlayerViewEvents {\n viewRef?: RefObject<any>;\n /**\n * {@link Player} instance (generally returned from {@link usePlayer} hook) that will control\n * and render audio/video inside the {@link PlayerView}.\n */\n player: Player;\n}\n"]}
1
+ {"version":3,"file":"properties.js","sourceRoot":"","sources":["../../../src/components/PlayerView/properties.ts"],"names":[],"mappings":"","sourcesContent":["import { PlayerViewEvents } from './events';\nimport { Player } from '../../player';\nimport { FullscreenHandler, CustomMessageHandler } from '../../ui';\nimport { ScalingMode } from '../../styleConfig';\nimport { ViewStyle } from 'react-native';\nimport { PlayerViewConfig } from './playerViewConfig';\nimport { PictureInPictureAction } from './pictureInPictureAction';\nimport { RefObject } from 'react';\n\n/**\n * Base `PlayerView` component props.\n * Used to establish common props between `NativePlayerView` and {@link PlayerView}.\n */\nexport interface BasePlayerViewProps {\n ref?: RefObject<null>;\n /**\n * The {@link FullscreenHandler} that is used by the {@link PlayerView} to control the fullscreen mode.\n */\n fullscreenHandler?: FullscreenHandler;\n\n /**\n * The {@link CustomMessageHandler} that can be used to directly communicate with the embedded Bitmovin Web UI.\n */\n customMessageHandler?: CustomMessageHandler;\n\n /**\n * Can be set to `true` to request fullscreen mode, or `false` to request exit of fullscreen mode.\n * Should not be used to get the current fullscreen state. Use {@link PlayerViewEvents.onFullscreenEnter} and {@link PlayerViewEvents.onFullscreenExit}\n * or the {@link FullscreenHandler.isFullscreenActive} property to get the current state.\n * Using this property to change the fullscreen state, it is ensured that the embedded Player UI is also aware\n * of potential fullscreen state changes.\n * To use this property, a {@link FullscreenHandler} must be set.\n */\n isFullscreenRequested?: boolean;\n\n /**\n * A value defining how the video is displayed within the parent container's bounds.\n * Possible values are defined in {@link ScalingMode}.\n */\n scalingMode?: ScalingMode;\n\n /**\n * Can be set to `true` to request Picture in Picture mode, or `false` to request exit of Picture in Picture mode.\n * Should not be used to get the current Picture in Picture state. Use {@link PlayerViewEvents.onPictureInPictureEnter} and {@link PlayerViewEvents.onPictureInPictureExit}.\n */\n isPictureInPictureRequested?: boolean;\n\n /**\n * Style of the {@link PlayerView}.\n */\n style?: ViewStyle;\n\n /**\n * Configures the visual presentation and behaviour of the {@link PlayerView}.\n * The value must not be altered after setting it initially.\n */\n config?: PlayerViewConfig;\n\n /**\n * Picture in Picture actions that should be displayed on the Picture in Picture window.\n *\n * Limitations:\n * - On Android if an empty list is passed and {@link MediaControlConfig.isEnabled} is set to true\n * play, pause, next, and previous controls will appear, due to the default Android Picture in Picture implementation:\n * https://developer.android.com/develop/ui/views/picture-in-picture#add_controls\n * Set {@link MediaControlConfig.isEnabled} to false if this is\n * not the desired behaviour.\n * - on iOS/tvOS if {@link PictureInPictureAction.TogglePlayback} is not specified also other actions are\n * disabled due to OS limitations.\n *\n * Default value is `undefined`, which translates to:\n * - Android: No actions, unless {@link MediaControlConfig.isEnabled} is set to true\n * - iOS: All actions enabled\n */\n pictureInPictureActions?: PictureInPictureAction[];\n\n /**\n * Enables or disables Picture in Picture mode availability.\n * When disabled, `isPictureInPictureRequested` property has no effect.\n *\n * Can be changed dynamically after the player is initialized.\n */\n isPictureInPictureEnabled?: boolean;\n}\n\n/**\n * {@link PlayerView} component props.\n */\nexport interface PlayerViewProps extends BasePlayerViewProps, PlayerViewEvents {\n viewRef?: RefObject<any>;\n /**\n * {@link Player} instance (generally returned from {@link usePlayer} hook) that will control\n * and render audio/video inside the {@link PlayerView}.\n */\n player: Player;\n}\n"]}
package/build/debug.d.ts CHANGED
@@ -42,5 +42,11 @@ export declare class DebugConfig {
42
42
  * @defaultValue `false`
43
43
  */
44
44
  static setDebugLoggingEnabled(value: boolean): Promise<void>;
45
+ /**
46
+ * Logs a message to the console if debug logging is enabled.
47
+ *
48
+ * @param args - Arguments to pass to `console.log`.
49
+ */
50
+ static log(...args: unknown[]): void;
45
51
  }
46
52
  //# sourceMappingURL=debug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,eAAe,CAAS;IAEvC;;;;OAIG;IACH,MAAM,KAAK,qBAAqB,IAAI,OAAO,CAE1C;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;WACU,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAInE"}
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,eAAe,CAAS;IAEvC;;;;OAIG;IACH,MAAM,KAAK,qBAAqB,IAAI,OAAO,CAE1C;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;WACU,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlE;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAMrC"}
package/build/debug.js CHANGED
@@ -48,5 +48,16 @@ export class DebugConfig {
48
48
  DebugConfig._isDebugEnabled = value;
49
49
  await DebugModule.setDebugLoggingEnabled(value);
50
50
  }
51
+ /**
52
+ * Logs a message to the console if debug logging is enabled.
53
+ *
54
+ * @param args - Arguments to pass to `console.log`.
55
+ */
56
+ static log(...args) {
57
+ if (DebugConfig._isDebugEnabled) {
58
+ // eslint-disable-next-line no-restricted-properties
59
+ console.log(...args);
60
+ }
61
+ }
51
62
  }
52
63
  //# sourceMappingURL=debug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAEhD;;GAEG;AACH,MAAM,OAAO,WAAW;IACd,MAAM,CAAC,eAAe,GAAG,KAAK,CAAC;IAEvC;;;;OAIG;IACH,MAAM,KAAK,qBAAqB;QAC9B,OAAO,WAAW,CAAC,eAAe,CAAC;IACrC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,KAAc;QAChD,WAAW,CAAC,eAAe,GAAG,KAAK,CAAC;QACpC,MAAM,WAAW,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC","sourcesContent":["import DebugModule from './modules/DebugModule';\n\n/**\n * Global debug configuration for all Bitmovin components.\n */\nexport class DebugConfig {\n private static _isDebugEnabled = false;\n\n /**\n * Retrieves the current debug logging state.\n *\n * @returns `true` if debug logging is enabled, otherwise `false`.\n */\n static get isDebugLoggingEnabled(): boolean {\n return DebugConfig._isDebugEnabled;\n }\n\n /**\n * Enables or disables global debug logging for all Bitmovin components.\n *\n * Debug logging provides detailed information primarily for debugging purposes,\n * helping to diagnose problems and trace the flow of execution within the Player.\n *\n * ### Warning:\n * This option **should not be enabled in production** as it may log sensitive or confidential\n * information to the console.\n *\n * ## Platform-Specific Logging Behavior\n * ---\n * - **iOS:** logs are printed using `NSLog` at the verbose log level.\n * - **Android:** logs are printed using `android.util.Log` with the following tags:\n * - `BitmovinPlayer`\n * - `BitmovinPlayerView`\n * - `BitmovinOffline`\n * - `BitmovinSource`\n * - `BitmovinExoPlayer`\n *\n * ## Limitations\n * ---\n * **Android**\n * - This flag **must** be set **before** creating any Bitmovin component to take effect.\n *\n * ## Usage Notes\n * ---\n * - We recommend setting this flag during your app's initialization phase, such as in the\n * application's entry point (e.g. `App.tsx`).\n *\n * @defaultValue `false`\n */\n static async setDebugLoggingEnabled(value: boolean): Promise<void> {\n DebugConfig._isDebugEnabled = value;\n await DebugModule.setDebugLoggingEnabled(value);\n }\n}\n"]}
1
+ {"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAEhD;;GAEG;AACH,MAAM,OAAO,WAAW;IACd,MAAM,CAAC,eAAe,GAAG,KAAK,CAAC;IAEvC;;;;OAIG;IACH,MAAM,KAAK,qBAAqB;QAC9B,OAAO,WAAW,CAAC,eAAe,CAAC;IACrC,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,KAAc;QAChD,WAAW,CAAC,eAAe,GAAG,KAAK,CAAC;QACpC,MAAM,WAAW,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,GAAG,IAAe;QAC3B,IAAI,WAAW,CAAC,eAAe,EAAE,CAAC;YAChC,oDAAoD;YACpD,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC","sourcesContent":["import DebugModule from './modules/DebugModule';\n\n/**\n * Global debug configuration for all Bitmovin components.\n */\nexport class DebugConfig {\n private static _isDebugEnabled = false;\n\n /**\n * Retrieves the current debug logging state.\n *\n * @returns `true` if debug logging is enabled, otherwise `false`.\n */\n static get isDebugLoggingEnabled(): boolean {\n return DebugConfig._isDebugEnabled;\n }\n\n /**\n * Enables or disables global debug logging for all Bitmovin components.\n *\n * Debug logging provides detailed information primarily for debugging purposes,\n * helping to diagnose problems and trace the flow of execution within the Player.\n *\n * ### Warning:\n * This option **should not be enabled in production** as it may log sensitive or confidential\n * information to the console.\n *\n * ## Platform-Specific Logging Behavior\n * ---\n * - **iOS:** logs are printed using `NSLog` at the verbose log level.\n * - **Android:** logs are printed using `android.util.Log` with the following tags:\n * - `BitmovinPlayer`\n * - `BitmovinPlayerView`\n * - `BitmovinOffline`\n * - `BitmovinSource`\n * - `BitmovinExoPlayer`\n *\n * ## Limitations\n * ---\n * **Android**\n * - This flag **must** be set **before** creating any Bitmovin component to take effect.\n *\n * ## Usage Notes\n * ---\n * - We recommend setting this flag during your app's initialization phase, such as in the\n * application's entry point (e.g. `App.tsx`).\n *\n * @defaultValue `false`\n */\n static async setDebugLoggingEnabled(value: boolean): Promise<void> {\n DebugConfig._isDebugEnabled = value;\n await DebugModule.setDebugLoggingEnabled(value);\n }\n\n /**\n * Logs a message to the console if debug logging is enabled.\n *\n * @param args - Arguments to pass to `console.log`.\n */\n static log(...args: unknown[]): void {\n if (DebugConfig._isDebugEnabled) {\n // eslint-disable-next-line no-restricted-properties\n console.log(...args);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/drm/index.ts"],"names":[],"mappings":"AAEA,OAAO,cAAc,EAAE,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAIlD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,oBAAoB;IACrD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,GAAI,SAAQ,cAAc,CAAC,SAAS,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC;;OAEG;IACH,aAAa,UAAS;IACtB;;OAEG;IACH,WAAW,UAAS;IAEpB,OAAO,CAAC,kBAAkB,CAA2B;gBAEzC,MAAM,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM;IAKvD;;OAEG;IACH,UAAU,sBAWR;IAEF;;OAEG;IACH,OAAO,sBAQL;IAEF;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkE3B;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB,CAK1B;IAEF;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB,CAkBtB;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB,CAY1B;IAEF;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB,CAYtB;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,yBAAyB,CAS/B;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB,CAMxB;CACH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/drm/index.ts"],"names":[],"mappings":"AAEA,OAAO,cAAc,EAAE,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKlD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,oBAAoB;IACrD;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,GAAI,SAAQ,cAAc,CAAC,SAAS,CAAC;IAChD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC;;OAEG;IACH,aAAa,UAAS;IACtB;;OAEG;IACH,WAAW,UAAS;IAEpB,OAAO,CAAC,kBAAkB,CAA2B;gBAEzC,MAAM,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM;IAKvD;;OAEG;IACH,UAAU,sBAWR;IAEF;;OAEG;IACH,OAAO,sBAQL;IAEF;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkE3B;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB,CAK1B;IAEF;;;;;;;;OAQG;IACH,OAAO,CAAC,gBAAgB,CAkBtB;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,oBAAoB,CAY1B;IAEF;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB,CAYtB;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,yBAAyB,CAS/B;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,kBAAkB,CAMxB;CACH"}
@@ -2,6 +2,7 @@ import { Platform } from 'react-native';
2
2
  import NativeInstance from '../nativeInstance';
3
3
  import { FairplayDrmApi } from './fairplayDrmApi';
4
4
  import DrmModule from './drmModule';
5
+ import { DebugConfig } from '../debug';
5
6
  // Export config types and API classes from DRM module.
6
7
  export { FairplayDrmApi };
7
8
  /**
@@ -194,7 +195,7 @@ export class Drm extends NativeInstance {
194
195
  * @param contentId - The extracted contentId string.
195
196
  */
196
197
  onPrepareContentId = (id, contentId) => {
197
- console.log('onPrepareContentId', contentId);
198
+ DebugConfig.log('onPrepareContentId', contentId);
198
199
  if (this.config?.fairplay?.prepareContentId) {
199
200
  const result = this.config?.fairplay?.prepareContentId?.(contentId);
200
201
  DrmModule.setPreparedContentId(id, result);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drm/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from 'react-native';\nimport { EventSubscription } from 'expo-modules-core';\nimport NativeInstance, { NativeInstanceConfig } from '../nativeInstance';\nimport { FairplayConfig } from './fairplayConfig';\nimport { WidevineConfig } from './widevineConfig';\nimport { FairplayDrmApi } from './fairplayDrmApi';\nimport DrmModule from './drmModule';\n\n// Export config types and API classes from DRM module.\nexport { FairplayConfig, WidevineConfig, FairplayDrmApi };\n\n/**\n * Represents the general Streaming DRM config.\n */\nexport interface DrmConfig extends NativeInstanceConfig {\n /**\n * FairPlay specific configuration.\n *\n * @platform iOS\n */\n fairplay?: FairplayConfig;\n /**\n * Widevine specific configuration.\n *\n * @platform Android, iOS (only for casting).\n */\n widevine?: WidevineConfig;\n}\n\n/**\n * Represents a native DRM configuration object.\n * @internal\n */\nexport class Drm extends NativeInstance<DrmConfig> {\n /**\n * Provides FairPlay-specific DRM runtime APIs such as {@link FairplayDrmApi.renewExpiringLicense}.\n *\n * @platform iOS, tvOS\n */\n readonly fairplay: FairplayDrmApi;\n /**\n * Whether this object's native instance has been created.\n */\n isInitialized = false;\n /**\n * Whether this object's native instance has been disposed.\n */\n isDestroyed = false;\n\n private eventSubscriptions: EventSubscription[] = [];\n\n constructor(config?: DrmConfig, sourceNativeId?: string) {\n super(config);\n this.fairplay = new FairplayDrmApi(sourceNativeId ?? '');\n }\n\n /**\n * Allocates the DRM config instance and its resources natively.\n */\n initialize = async () => {\n if (!this.isInitialized) {\n // Set up event listeners for DRM preparation callbacks\n this.setupEventListeners();\n\n // Create native configuration object using Expo module.\n if (this.config) {\n await DrmModule.initializeWithConfig(this.nativeId, this.config);\n }\n this.isInitialized = true;\n }\n };\n\n /**\n * Destroys the native DRM config and releases all of its allocated resources.\n */\n destroy = async () => {\n if (!this.isDestroyed) {\n await DrmModule.destroy(this.nativeId);\n // Clean up event subscriptions\n this.eventSubscriptions.forEach((subscription) => subscription.remove());\n this.eventSubscriptions = [];\n this.isDestroyed = true;\n }\n };\n\n /**\n * Sets up event listeners for all DRM preparation callbacks\n */\n private setupEventListeners() {\n // iOS-only events\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareCertificate',\n ({ nativeId, id, certificate }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareCertificate(id, certificate);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareSyncMessage',\n ({ nativeId, id, syncMessage, assetId }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareSyncMessage(id, syncMessage, assetId);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareLicenseServerUrl',\n ({ nativeId, id, licenseServerUrl }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareLicenseServerUrl(id, licenseServerUrl);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareContentId',\n ({ nativeId, id, contentId }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareContentId(id, contentId);\n }\n )\n );\n\n // Cross-platform events\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareMessage',\n ({ nativeId, id, data, message, assetId }) => {\n if (nativeId !== this.nativeId) return;\n // Android sends 'data', iOS sends 'message'\n this.onPrepareMessage(id, data || message, assetId);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareLicense',\n ({ nativeId, id, data, license }) => {\n if (nativeId !== this.nativeId) return;\n // Android sends 'data', iOS sends 'license'\n this.onPrepareLicense(id, data || license);\n }\n )\n );\n }\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareCertificate` function to native's `certificate` data and store\n * the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareCertificate` is dispatched.\n *\n * @param certificate - Base64 encoded certificate data.\n */\n private onPrepareCertificate = (id: string, certificate: string) => {\n if (this.config?.fairplay?.prepareCertificate) {\n const result = this.config?.fairplay?.prepareCertificate?.(certificate);\n DrmModule.setPreparedCertificate(id, result);\n }\n };\n\n /**\n * Applies the user-defined `prepareMessage` function to native's `message` data and store\n * the result back in `DrmModule`.\n *\n * Called from native code when `prepareMessage` is dispatched.\n *\n * @param message - Base64 encoded message data.\n * @param assetId - Optional asset ID. Only sent by iOS.\n */\n private onPrepareMessage = (\n id: string,\n message?: string,\n assetId?: string\n ) => {\n if (!message) {\n DrmModule.setPreparedMessage(id, undefined);\n return;\n }\n const config =\n Platform.OS === 'ios' ? this.config?.fairplay : this.config?.widevine;\n if (config && config.prepareMessage) {\n const result =\n Platform.OS === 'ios'\n ? (config as FairplayConfig).prepareMessage?.(message, assetId!)\n : (config as WidevineConfig).prepareMessage?.(message);\n DrmModule.setPreparedMessage(id, result);\n }\n };\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareSyncMessage` function to native's `syncMessage` data and\n * store the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareSyncMessage` is dispatched.\n *\n * @param syncMessage - Base64 encoded sync SPC message data.\n */\n private onPrepareSyncMessage = (\n id: string,\n syncMessage: string,\n assetId: string\n ) => {\n if (this.config?.fairplay?.prepareSyncMessage) {\n const result = this.config?.fairplay?.prepareSyncMessage?.(\n syncMessage,\n assetId\n );\n DrmModule.setPreparedSyncMessage(id, result);\n }\n };\n\n /**\n * Applies the user-defined `prepareLicense` function to native's `license` data and store\n * the result back in `DrmModule`.\n *\n * Called from native code when `prepareLicense` is dispatched.\n *\n * @param license - Base64 encoded license data.\n */\n private onPrepareLicense = (id: string, license?: string) => {\n if (!license) {\n DrmModule.setPreparedLicense(id, undefined);\n return;\n }\n const prepareLicense =\n Platform.OS === 'ios'\n ? this.config?.fairplay?.prepareLicense\n : this.config?.widevine?.prepareLicense;\n if (prepareLicense) {\n DrmModule.setPreparedLicense(id, prepareLicense(license));\n }\n };\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareLicenseServerUrl` function to native's `licenseServerUrl` data\n * and store the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareLicenseServerUrl` is dispatched.\n *\n * @param licenseServerUrl - The license server URL string.\n */\n private onPrepareLicenseServerUrl = (\n id: string,\n licenseServerUrl: string\n ) => {\n if (this.config?.fairplay?.prepareLicenseServerUrl) {\n const result =\n this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl);\n DrmModule.setPreparedLicenseServerUrl(id, result);\n }\n };\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareContentId` function to native's `contentId` string\n * and store the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareContentId` is dispatched.\n *\n * @param contentId - The extracted contentId string.\n */\n private onPrepareContentId = (id: string, contentId: string) => {\n console.log('onPrepareContentId', contentId);\n if (this.config?.fairplay?.prepareContentId) {\n const result = this.config?.fairplay?.prepareContentId?.(contentId);\n DrmModule.setPreparedContentId(id, result);\n }\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drm/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,cAAwC,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,SAAS,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEvC,uDAAuD;AACvD,OAAO,EAAkC,cAAc,EAAE,CAAC;AAoB1D;;;GAGG;AACH,MAAM,OAAO,GAAI,SAAQ,cAAyB;IAChD;;;;OAIG;IACM,QAAQ,CAAiB;IAClC;;OAEG;IACH,aAAa,GAAG,KAAK,CAAC;IACtB;;OAEG;IACH,WAAW,GAAG,KAAK,CAAC;IAEZ,kBAAkB,GAAwB,EAAE,CAAC;IAErD,YAAY,MAAkB,EAAE,cAAuB;QACrD,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACH,UAAU,GAAG,KAAK,IAAI,EAAE;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,uDAAuD;YACvD,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE3B,wDAAwD;YACxD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,MAAM,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YACnE,CAAC;YACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC;IAEF;;OAEG;IACH,OAAO,GAAG,KAAK,IAAI,EAAE;QACnB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvC,+BAA+B;YAC/B,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;YACzE,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;YAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC;IAEF;;OAEG;IACK,mBAAmB;QACzB,kBAAkB;QAClB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,SAAS,CAAC,WAAW,CACnB,sBAAsB,EACtB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;YAChC,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACvC,IAAI,CAAC,oBAAoB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC7C,CAAC,CACF,CACF,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,SAAS,CAAC,WAAW,CACnB,sBAAsB,EACtB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE;YACzC,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACvC,IAAI,CAAC,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC,CACF,CACF,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,SAAS,CAAC,WAAW,CACnB,2BAA2B,EAC3B,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE;YACrC,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACvC,IAAI,CAAC,yBAAyB,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;QACvD,CAAC,CACF,CACF,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,SAAS,CAAC,WAAW,CACnB,oBAAoB,EACpB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;YAC9B,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACvC,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACzC,CAAC,CACF,CACF,CAAC;QAEF,wBAAwB;QACxB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,SAAS,CAAC,WAAW,CACnB,kBAAkB,EAClB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE;YAC3C,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACvC,4CAA4C;YAC5C,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,IAAI,IAAI,OAAO,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC,CACF,CACF,CAAC;QAEF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAC1B,SAAS,CAAC,WAAW,CACnB,kBAAkB,EAClB,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;YAClC,IAAI,QAAQ,KAAK,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACvC,4CAA4C;YAC5C,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,IAAI,IAAI,OAAO,CAAC,CAAC;QAC7C,CAAC,CACF,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACK,oBAAoB,GAAG,CAAC,EAAU,EAAE,WAAmB,EAAE,EAAE;QACjE,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC,WAAW,CAAC,CAAC;YACxE,SAAS,CAAC,sBAAsB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC;IAEF;;;;;;;;OAQG;IACK,gBAAgB,GAAG,CACzB,EAAU,EACV,OAAgB,EAChB,OAAgB,EAChB,EAAE;QACF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GACV,QAAQ,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;QACxE,IAAI,MAAM,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YACpC,MAAM,MAAM,GACV,QAAQ,CAAC,EAAE,KAAK,KAAK;gBACnB,CAAC,CAAE,MAAyB,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,OAAQ,CAAC;gBAChE,CAAC,CAAE,MAAyB,CAAC,cAAc,EAAE,CAAC,OAAO,CAAC,CAAC;YAC3D,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC,CAAC;IAEF;;;;;;;;;OASG;IACK,oBAAoB,GAAG,CAC7B,EAAU,EACV,WAAmB,EACnB,OAAe,EACf,EAAE;QACF,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;YAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CACxD,WAAW,EACX,OAAO,CACR,CAAC;YACF,SAAS,CAAC,sBAAsB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC;IAEF;;;;;;;OAOG;IACK,gBAAgB,GAAG,CAAC,EAAU,EAAE,OAAgB,EAAE,EAAE;QAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QACD,MAAM,cAAc,GAClB,QAAQ,CAAC,EAAE,KAAK,KAAK;YACnB,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc;YACvC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC;QAC5C,IAAI,cAAc,EAAE,CAAC;YACnB,SAAS,CAAC,kBAAkB,CAAC,EAAE,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC;IAEF;;;;;;;;;OASG;IACK,yBAAyB,GAAG,CAClC,EAAU,EACV,gBAAwB,EACxB,EAAE;QACF,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAC;YACnD,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,uBAAuB,EAAE,CAAC,gBAAgB,CAAC,CAAC;YACrE,SAAS,CAAC,2BAA2B,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF;;;;;;;;;OASG;IACK,kBAAkB,GAAG,CAAC,EAAU,EAAE,SAAiB,EAAE,EAAE;QAC7D,WAAW,CAAC,GAAG,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;QACjD,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,SAAS,CAAC,CAAC;YACpE,SAAS,CAAC,oBAAoB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,CAAC;CACH","sourcesContent":["import { Platform } from 'react-native';\nimport { EventSubscription } from 'expo-modules-core';\nimport NativeInstance, { NativeInstanceConfig } from '../nativeInstance';\nimport { FairplayConfig } from './fairplayConfig';\nimport { WidevineConfig } from './widevineConfig';\nimport { FairplayDrmApi } from './fairplayDrmApi';\nimport DrmModule from './drmModule';\nimport { DebugConfig } from '../debug';\n\n// Export config types and API classes from DRM module.\nexport { FairplayConfig, WidevineConfig, FairplayDrmApi };\n\n/**\n * Represents the general Streaming DRM config.\n */\nexport interface DrmConfig extends NativeInstanceConfig {\n /**\n * FairPlay specific configuration.\n *\n * @platform iOS\n */\n fairplay?: FairplayConfig;\n /**\n * Widevine specific configuration.\n *\n * @platform Android, iOS (only for casting).\n */\n widevine?: WidevineConfig;\n}\n\n/**\n * Represents a native DRM configuration object.\n * @internal\n */\nexport class Drm extends NativeInstance<DrmConfig> {\n /**\n * Provides FairPlay-specific DRM runtime APIs such as {@link FairplayDrmApi.renewExpiringLicense}.\n *\n * @platform iOS, tvOS\n */\n readonly fairplay: FairplayDrmApi;\n /**\n * Whether this object's native instance has been created.\n */\n isInitialized = false;\n /**\n * Whether this object's native instance has been disposed.\n */\n isDestroyed = false;\n\n private eventSubscriptions: EventSubscription[] = [];\n\n constructor(config?: DrmConfig, sourceNativeId?: string) {\n super(config);\n this.fairplay = new FairplayDrmApi(sourceNativeId ?? '');\n }\n\n /**\n * Allocates the DRM config instance and its resources natively.\n */\n initialize = async () => {\n if (!this.isInitialized) {\n // Set up event listeners for DRM preparation callbacks\n this.setupEventListeners();\n\n // Create native configuration object using Expo module.\n if (this.config) {\n await DrmModule.initializeWithConfig(this.nativeId, this.config);\n }\n this.isInitialized = true;\n }\n };\n\n /**\n * Destroys the native DRM config and releases all of its allocated resources.\n */\n destroy = async () => {\n if (!this.isDestroyed) {\n await DrmModule.destroy(this.nativeId);\n // Clean up event subscriptions\n this.eventSubscriptions.forEach((subscription) => subscription.remove());\n this.eventSubscriptions = [];\n this.isDestroyed = true;\n }\n };\n\n /**\n * Sets up event listeners for all DRM preparation callbacks\n */\n private setupEventListeners() {\n // iOS-only events\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareCertificate',\n ({ nativeId, id, certificate }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareCertificate(id, certificate);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareSyncMessage',\n ({ nativeId, id, syncMessage, assetId }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareSyncMessage(id, syncMessage, assetId);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareLicenseServerUrl',\n ({ nativeId, id, licenseServerUrl }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareLicenseServerUrl(id, licenseServerUrl);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareContentId',\n ({ nativeId, id, contentId }) => {\n if (nativeId !== this.nativeId) return;\n this.onPrepareContentId(id, contentId);\n }\n )\n );\n\n // Cross-platform events\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareMessage',\n ({ nativeId, id, data, message, assetId }) => {\n if (nativeId !== this.nativeId) return;\n // Android sends 'data', iOS sends 'message'\n this.onPrepareMessage(id, data || message, assetId);\n }\n )\n );\n\n this.eventSubscriptions.push(\n DrmModule.addListener(\n 'onPrepareLicense',\n ({ nativeId, id, data, license }) => {\n if (nativeId !== this.nativeId) return;\n // Android sends 'data', iOS sends 'license'\n this.onPrepareLicense(id, data || license);\n }\n )\n );\n }\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareCertificate` function to native's `certificate` data and store\n * the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareCertificate` is dispatched.\n *\n * @param certificate - Base64 encoded certificate data.\n */\n private onPrepareCertificate = (id: string, certificate: string) => {\n if (this.config?.fairplay?.prepareCertificate) {\n const result = this.config?.fairplay?.prepareCertificate?.(certificate);\n DrmModule.setPreparedCertificate(id, result);\n }\n };\n\n /**\n * Applies the user-defined `prepareMessage` function to native's `message` data and store\n * the result back in `DrmModule`.\n *\n * Called from native code when `prepareMessage` is dispatched.\n *\n * @param message - Base64 encoded message data.\n * @param assetId - Optional asset ID. Only sent by iOS.\n */\n private onPrepareMessage = (\n id: string,\n message?: string,\n assetId?: string\n ) => {\n if (!message) {\n DrmModule.setPreparedMessage(id, undefined);\n return;\n }\n const config =\n Platform.OS === 'ios' ? this.config?.fairplay : this.config?.widevine;\n if (config && config.prepareMessage) {\n const result =\n Platform.OS === 'ios'\n ? (config as FairplayConfig).prepareMessage?.(message, assetId!)\n : (config as WidevineConfig).prepareMessage?.(message);\n DrmModule.setPreparedMessage(id, result);\n }\n };\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareSyncMessage` function to native's `syncMessage` data and\n * store the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareSyncMessage` is dispatched.\n *\n * @param syncMessage - Base64 encoded sync SPC message data.\n */\n private onPrepareSyncMessage = (\n id: string,\n syncMessage: string,\n assetId: string\n ) => {\n if (this.config?.fairplay?.prepareSyncMessage) {\n const result = this.config?.fairplay?.prepareSyncMessage?.(\n syncMessage,\n assetId\n );\n DrmModule.setPreparedSyncMessage(id, result);\n }\n };\n\n /**\n * Applies the user-defined `prepareLicense` function to native's `license` data and store\n * the result back in `DrmModule`.\n *\n * Called from native code when `prepareLicense` is dispatched.\n *\n * @param license - Base64 encoded license data.\n */\n private onPrepareLicense = (id: string, license?: string) => {\n if (!license) {\n DrmModule.setPreparedLicense(id, undefined);\n return;\n }\n const prepareLicense =\n Platform.OS === 'ios'\n ? this.config?.fairplay?.prepareLicense\n : this.config?.widevine?.prepareLicense;\n if (prepareLicense) {\n DrmModule.setPreparedLicense(id, prepareLicense(license));\n }\n };\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareLicenseServerUrl` function to native's `licenseServerUrl` data\n * and store the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareLicenseServerUrl` is dispatched.\n *\n * @param licenseServerUrl - The license server URL string.\n */\n private onPrepareLicenseServerUrl = (\n id: string,\n licenseServerUrl: string\n ) => {\n if (this.config?.fairplay?.prepareLicenseServerUrl) {\n const result =\n this.config?.fairplay?.prepareLicenseServerUrl?.(licenseServerUrl);\n DrmModule.setPreparedLicenseServerUrl(id, result);\n }\n };\n\n /**\n * iOS only.\n *\n * Applies the user-defined `prepareContentId` function to native's `contentId` string\n * and store the result back in `DrmModule`.\n *\n * Called from native code when `FairplayConfig.prepareContentId` is dispatched.\n *\n * @param contentId - The extracted contentId string.\n */\n private onPrepareContentId = (id: string, contentId: string) => {\n DebugConfig.log('onPrepareContentId', contentId);\n if (this.config?.fairplay?.prepareContentId) {\n const result = this.config?.fairplay?.prepareContentId?.(contentId);\n DrmModule.setPreparedContentId(id, result);\n }\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/network/index.ts"],"names":[],"mappings":"AACA,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAE/C,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,EACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAErE;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,cAAc,CAAC,aAAa,CAAC;IACxD;;OAEG;IACH,aAAa,UAAS;IACtB;;OAEG;IACH,WAAW,UAAS;IAEpB,OAAO,CAAC,mCAAmC,CAAC,CAAoB;IAChE,OAAO,CAAC,oCAAoC,CAAC,CAAoB;IAEjE;;OAEG;IACH,UAAU,sBAgCR;IAEF;;OAEG;IACH,OAAO,sBASL;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,uBAAuB,CAa7B;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB,CAa9B;CACH"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/network/index.ts"],"names":[],"mappings":"AACA,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAG/C,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,EACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAErE;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,cAAc,CAAC,aAAa,CAAC;IACxD;;OAEG;IACH,aAAa,UAAS;IACtB;;OAEG;IACH,WAAW,UAAS;IAEpB,OAAO,CAAC,mCAAmC,CAAC,CAAoB;IAChE,OAAO,CAAC,oCAAoC,CAAC,CAAoB;IAEjE;;OAEG;IACH,UAAU,sBAgCR;IAEF;;OAEG;IACH,OAAO,sBASL;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,uBAAuB,CAa7B;IAEF;;;;;;;;;OASG;IACH,OAAO,CAAC,wBAAwB,CAa9B;CACH"}
@@ -1,5 +1,6 @@
1
1
  import NativeInstance from '../nativeInstance';
2
2
  import NetworkModule from './networkModule';
3
+ import { DebugConfig } from '../debug';
3
4
  import { HttpRequestType, } from './networkConfig';
4
5
  export { HttpRequestType };
5
6
  /**
@@ -22,17 +23,17 @@ export class Network extends NativeInstance {
22
23
  */
23
24
  initialize = async () => {
24
25
  if (!this.isInitialized) {
25
- console.log('Initializing Network config:', this.nativeId);
26
+ DebugConfig.log('Initializing Network config:', this.nativeId);
26
27
  // Set up event listeners for HTTP request/response preprocessing
27
28
  this.onPreprocessHttpRequestSubscription = NetworkModule.addListener('onPreprocessHttpRequest', ({ nativeId, requestId, type, request }) => {
28
- console.log(`Received HTTP Request [${type}]:`, request);
29
+ DebugConfig.log(`Received HTTP Request [${type}]:`, request);
29
30
  if (nativeId !== this.nativeId) {
30
31
  return;
31
32
  }
32
33
  this.onPreprocessHttpRequest(requestId, type, request);
33
34
  });
34
35
  this.onPreprocessHttpResponseSubscription = NetworkModule.addListener('onPreprocessHttpResponse', ({ nativeId, responseId, type, response }) => {
35
- console.log(`Received HTTP Response [${type}]:`, response);
36
+ DebugConfig.log(`Received HTTP Response [${type}]:`, response);
36
37
  if (nativeId !== this.nativeId) {
37
38
  return;
38
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/network/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventSubscription } from 'expo-modules-core';\nimport NativeInstance from '../nativeInstance';\nimport NetworkModule from './networkModule';\nimport {\n HttpRequestType,\n HttpRequest,\n HttpResponse,\n NetworkConfig,\n} from './networkConfig';\n\nexport { HttpRequestType, HttpRequest, HttpResponse, NetworkConfig };\n\n/**\n * Represents a native Network configuration object.\n * @internal\n */\nexport class Network extends NativeInstance<NetworkConfig> {\n /**\n * Whether this object's native instance has been created.\n */\n isInitialized = false;\n /**\n * Whether this object's native instance has been disposed.\n */\n isDestroyed = false;\n\n private onPreprocessHttpRequestSubscription?: EventSubscription;\n private onPreprocessHttpResponseSubscription?: EventSubscription;\n\n /**\n * Allocates the Network config instance and its resources natively.\n */\n initialize = async () => {\n if (!this.isInitialized) {\n console.log('Initializing Network config:', this.nativeId);\n // Set up event listeners for HTTP request/response preprocessing\n this.onPreprocessHttpRequestSubscription = NetworkModule.addListener(\n 'onPreprocessHttpRequest',\n ({ nativeId, requestId, type, request }) => {\n console.log(`Received HTTP Request [${type}]:`, request);\n if (nativeId !== this.nativeId) {\n return;\n }\n this.onPreprocessHttpRequest(requestId, type, request);\n }\n );\n\n this.onPreprocessHttpResponseSubscription = NetworkModule.addListener(\n 'onPreprocessHttpResponse',\n ({ nativeId, responseId, type, response }) => {\n console.log(`Received HTTP Response [${type}]:`, response);\n if (nativeId !== this.nativeId) {\n return;\n }\n this.onPreprocessHttpResponse(responseId, type, response);\n }\n );\n\n // Create native configuration object using Expo module\n if (this.config) {\n await NetworkModule.initializeWithConfig(this.nativeId, this.config);\n }\n this.isInitialized = true;\n }\n };\n\n /**\n * Destroys the native Network config and releases all of its allocated resources.\n */\n destroy = async () => {\n if (!this.isDestroyed) {\n await NetworkModule.destroy(this.nativeId);\n this.onPreprocessHttpRequestSubscription?.remove();\n this.onPreprocessHttpResponseSubscription?.remove();\n this.onPreprocessHttpRequestSubscription = undefined;\n this.onPreprocessHttpResponseSubscription = undefined;\n this.isDestroyed = true;\n }\n };\n\n /**\n * Applies the user-defined `preprocessHttpRequest` function to native's `type` and `request` data and store\n * the result back in `NetworkModule`.\n *\n * Called from native code when `NetworkConfig.preprocessHttpRequest` is dispatched.\n *\n * @param requestId Passed through to identify the completion handler of the request on native.\n * @param type Type of the request to be made.\n * @param request The HTTP request to process.\n */\n private onPreprocessHttpRequest = (\n requestId: string,\n type: HttpRequestType,\n request: HttpRequest\n ) => {\n this.config\n ?.preprocessHttpRequest?.(type, request)\n .then((resultRequest) =>\n NetworkModule.setPreprocessedHttpRequest(requestId, resultRequest)\n )\n .catch(() =>\n NetworkModule.setPreprocessedHttpRequest(requestId, request)\n );\n };\n\n /**\n * Applies the user-defined `preprocessHttpResponse` function to native's `type` and `response` data and store\n * the result back in `NetworkModule`.\n *\n * Called from native code when `NetworkConfig.preprocessHttpResponse` is dispatched.\n *\n * @param responseId Passed through to identify the completion handler of the response on native.\n * @param type Type of the request to be made.\n * @param response The HTTP response to process.\n */\n private onPreprocessHttpResponse = (\n responseId: string,\n type: HttpRequestType,\n response: HttpResponse\n ) => {\n this.config\n ?.preprocessHttpResponse?.(type, response)\n .then((resultResponse) =>\n NetworkModule.setPreprocessedHttpResponse(responseId, resultResponse)\n )\n .catch(() =>\n NetworkModule.setPreprocessedHttpResponse(responseId, response)\n );\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/network/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventSubscription } from 'expo-modules-core';\nimport NativeInstance from '../nativeInstance';\nimport NetworkModule from './networkModule';\nimport { DebugConfig } from '../debug';\nimport {\n HttpRequestType,\n HttpRequest,\n HttpResponse,\n NetworkConfig,\n} from './networkConfig';\n\nexport { HttpRequestType, HttpRequest, HttpResponse, NetworkConfig };\n\n/**\n * Represents a native Network configuration object.\n * @internal\n */\nexport class Network extends NativeInstance<NetworkConfig> {\n /**\n * Whether this object's native instance has been created.\n */\n isInitialized = false;\n /**\n * Whether this object's native instance has been disposed.\n */\n isDestroyed = false;\n\n private onPreprocessHttpRequestSubscription?: EventSubscription;\n private onPreprocessHttpResponseSubscription?: EventSubscription;\n\n /**\n * Allocates the Network config instance and its resources natively.\n */\n initialize = async () => {\n if (!this.isInitialized) {\n DebugConfig.log('Initializing Network config:', this.nativeId);\n // Set up event listeners for HTTP request/response preprocessing\n this.onPreprocessHttpRequestSubscription = NetworkModule.addListener(\n 'onPreprocessHttpRequest',\n ({ nativeId, requestId, type, request }) => {\n DebugConfig.log(`Received HTTP Request [${type}]:`, request);\n if (nativeId !== this.nativeId) {\n return;\n }\n this.onPreprocessHttpRequest(requestId, type, request);\n }\n );\n\n this.onPreprocessHttpResponseSubscription = NetworkModule.addListener(\n 'onPreprocessHttpResponse',\n ({ nativeId, responseId, type, response }) => {\n DebugConfig.log(`Received HTTP Response [${type}]:`, response);\n if (nativeId !== this.nativeId) {\n return;\n }\n this.onPreprocessHttpResponse(responseId, type, response);\n }\n );\n\n // Create native configuration object using Expo module\n if (this.config) {\n await NetworkModule.initializeWithConfig(this.nativeId, this.config);\n }\n this.isInitialized = true;\n }\n };\n\n /**\n * Destroys the native Network config and releases all of its allocated resources.\n */\n destroy = async () => {\n if (!this.isDestroyed) {\n await NetworkModule.destroy(this.nativeId);\n this.onPreprocessHttpRequestSubscription?.remove();\n this.onPreprocessHttpResponseSubscription?.remove();\n this.onPreprocessHttpRequestSubscription = undefined;\n this.onPreprocessHttpResponseSubscription = undefined;\n this.isDestroyed = true;\n }\n };\n\n /**\n * Applies the user-defined `preprocessHttpRequest` function to native's `type` and `request` data and store\n * the result back in `NetworkModule`.\n *\n * Called from native code when `NetworkConfig.preprocessHttpRequest` is dispatched.\n *\n * @param requestId Passed through to identify the completion handler of the request on native.\n * @param type Type of the request to be made.\n * @param request The HTTP request to process.\n */\n private onPreprocessHttpRequest = (\n requestId: string,\n type: HttpRequestType,\n request: HttpRequest\n ) => {\n this.config\n ?.preprocessHttpRequest?.(type, request)\n .then((resultRequest) =>\n NetworkModule.setPreprocessedHttpRequest(requestId, resultRequest)\n )\n .catch(() =>\n NetworkModule.setPreprocessedHttpRequest(requestId, request)\n );\n };\n\n /**\n * Applies the user-defined `preprocessHttpResponse` function to native's `type` and `response` data and store\n * the result back in `NetworkModule`.\n *\n * Called from native code when `NetworkConfig.preprocessHttpResponse` is dispatched.\n *\n * @param responseId Passed through to identify the completion handler of the response on native.\n * @param type Type of the request to be made.\n * @param response The HTTP response to process.\n */\n private onPreprocessHttpResponse = (\n responseId: string,\n type: HttpRequestType,\n response: HttpResponse\n ) => {\n this.config\n ?.preprocessHttpResponse?.(type, response)\n .then((resultResponse) =>\n NetworkModule.setPreprocessedHttpResponse(responseId, resultResponse)\n )\n .catch(() =>\n NetworkModule.setPreprocessedHttpResponse(responseId, response)\n );\n };\n}\n"]}
@@ -65,6 +65,13 @@ export interface PlaybackConfig {
65
65
  * ```
66
66
  */
67
67
  isBackgroundPlaybackEnabled?: boolean;
68
+ /**
69
+ * Whether to automate audio focus management, allowing the player to pause when other apps request focus.
70
+ *
71
+ * @defaultValue `false`
72
+ * @platform Android
73
+ */
74
+ handleAudioFocus?: boolean;
68
75
  /**
69
76
  * Whether the Picture in Picture mode option is enabled or not. Default is `false`.
70
77
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"playbackConfig.d.ts","sourceRoot":"","sources":["../src/playbackConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;;;;;;;;;OAWG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B"}
1
+ {"version":3,"file":"playbackConfig.d.ts","sourceRoot":"","sources":["../src/playbackConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;;;OAWG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"playbackConfig.js","sourceRoot":"","sources":["../src/playbackConfig.ts"],"names":[],"mappings":"","sourcesContent":["import { DecoderConfig } from './decoder/decoderConfig';\n\n/**\n * Configures the playback behaviour of the player.\n */\nexport interface PlaybackConfig {\n /**\n * Whether the player starts playing automatically after loading a source or not. Default is `false`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isAutoplayEnabled: true,\n * },\n * });\n * ```\n */\n isAutoplayEnabled?: boolean;\n /**\n * Whether the sound is muted on startup or not. Default value is `false`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isMuted: true,\n * },\n * });\n * ```\n */\n isMuted?: boolean;\n /**\n * Whether time shift / DVR for live streams is enabled or not. Default is `true`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isTimeShiftEnabled: false,\n * },\n * });\n * ```\n */\n isTimeShiftEnabled?: boolean;\n /**\n * Whether background playback is enabled or not.\n * Default is `false`.\n *\n * When set to `true`, playback is not automatically paused\n * anymore when the app moves to the background.\n * When set to `true`, also make sure to properly configure your app to allow\n * background playback.\n *\n * Default is `false`.\n *\n * @remarks\n * - On Android, {@link MediaControlConfig.isEnabled} has to be `true` for\n * background playback to work.\n * - On tvOS, background playback is only supported for audio-only content.\n *\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isBackgroundPlaybackEnabled: true,\n * },\n * });\n * ```\n */\n isBackgroundPlaybackEnabled?: boolean;\n /**\n * Whether the Picture in Picture mode option is enabled or not. Default is `false`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isPictureInPictureEnabled: true,\n * },\n * });\n * ```\n * @deprecated Use {@link PictureInPictureConfig.isEnabled} instead.\n */\n isPictureInPictureEnabled?: boolean;\n\n /**\n * Configures decoder behaviour.\n *\n * @platform Android\n */\n decoderConfig?: DecoderConfig;\n}\n"]}
1
+ {"version":3,"file":"playbackConfig.js","sourceRoot":"","sources":["../src/playbackConfig.ts"],"names":[],"mappings":"","sourcesContent":["import { DecoderConfig } from './decoder/decoderConfig';\n\n/**\n * Configures the playback behaviour of the player.\n */\nexport interface PlaybackConfig {\n /**\n * Whether the player starts playing automatically after loading a source or not. Default is `false`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isAutoplayEnabled: true,\n * },\n * });\n * ```\n */\n isAutoplayEnabled?: boolean;\n /**\n * Whether the sound is muted on startup or not. Default value is `false`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isMuted: true,\n * },\n * });\n * ```\n */\n isMuted?: boolean;\n /**\n * Whether time shift / DVR for live streams is enabled or not. Default is `true`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isTimeShiftEnabled: false,\n * },\n * });\n * ```\n */\n isTimeShiftEnabled?: boolean;\n /**\n * Whether background playback is enabled or not.\n * Default is `false`.\n *\n * When set to `true`, playback is not automatically paused\n * anymore when the app moves to the background.\n * When set to `true`, also make sure to properly configure your app to allow\n * background playback.\n *\n * Default is `false`.\n *\n * @remarks\n * - On Android, {@link MediaControlConfig.isEnabled} has to be `true` for\n * background playback to work.\n * - On tvOS, background playback is only supported for audio-only content.\n *\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isBackgroundPlaybackEnabled: true,\n * },\n * });\n * ```\n */\n isBackgroundPlaybackEnabled?: boolean;\n /**\n * Whether to automate audio focus management, allowing the player to pause when other apps request focus.\n *\n * @defaultValue `false`\n * @platform Android\n */\n handleAudioFocus?: boolean;\n /**\n * Whether the Picture in Picture mode option is enabled or not. Default is `false`.\n * @example\n * ```\n * const player = new Player({\n * playbackConfig: {\n * isPictureInPictureEnabled: true,\n * },\n * });\n * ```\n * @deprecated Use {@link PictureInPictureConfig.isEnabled} instead.\n */\n isPictureInPictureEnabled?: boolean;\n\n /**\n * Configures decoder behaviour.\n *\n * @platform Android\n */\n decoderConfig?: DecoderConfig;\n}\n"]}
@@ -90,7 +90,7 @@ extension TimeChangedEvent: JsonConvertible {
90
90
  }
91
91
 
92
92
  private protocol ErrorEventType: Event, JsonConvertible {
93
- associatedtype Code
93
+ associatedtype Code: RawRepresentable where Code.RawValue == Int
94
94
  var code: Code { get }
95
95
  var data: DeficiencyData? { get }
96
96
  var message: String { get }
@@ -100,7 +100,7 @@ extension ErrorEventType {
100
100
  func toJSON() -> [AnyHashable: Any] {
101
101
  toEventJSON {
102
102
  var json: [AnyHashable: Any] = [
103
- "code": code,
103
+ "code": code.rawValue,
104
104
  "message": message
105
105
  ]
106
106
  if let data {
@@ -28,7 +28,7 @@ Pod::Spec.new do |s|
28
28
  s.static_framework = true
29
29
 
30
30
  s.dependency 'ExpoModulesCore'
31
- s.dependency "BitmovinPlayer", "3.109.0"
31
+ s.dependency "BitmovinPlayer", "3.111.0"
32
32
  s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.26.1"
33
33
  s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.15.1"
34
34
 
@@ -30,6 +30,9 @@ public class RNPlayerView: ExpoView {
30
30
  if let requestedPictureInPictureValue {
31
31
  setPictureInPicture(enterPictureInPicture: requestedPictureInPictureValue)
32
32
  }
33
+ if let isPictureInPictureEnabledValue {
34
+ playerView.pictureInPicture.isEnabled = isPictureInPictureEnabledValue
35
+ }
33
36
  }
34
37
  }
35
38
 
@@ -39,6 +42,7 @@ public class RNPlayerView: ExpoView {
39
42
  private var scalingMode: ScalingMode?
40
43
  private var requestedFullscreenValue: Bool?
41
44
  private var requestedPictureInPictureValue: Bool?
45
+ private var isPictureInPictureEnabledValue: Bool?
42
46
  private var avPlayerViewControllerTransitionForced = false
43
47
 
44
48
  let onBmpEvent = EventDispatcher()
@@ -234,6 +238,11 @@ public class RNPlayerView: ExpoView {
234
238
  playerView.tweaks.hidePlaybackControlsInPictureInPicture = !actions.contains(.togglePlayback)
235
239
  #endif
236
240
  }
241
+
242
+ internal func setIsPictureInPictureEnabled(_ isEnabled: Bool) {
243
+ isPictureInPictureEnabledValue = isEnabled
244
+ playerView?.pictureInPicture.isEnabled = isEnabled
245
+ }
237
246
  }
238
247
 
239
248
  private extension RNPlayerView {
@@ -32,6 +32,9 @@ public class RNPlayerViewManager: Module {
32
32
  AsyncFunction("updatePictureInPictureActions") { (view: RNPlayerView, pictureInPictureActions: [String]) in
33
33
  view.updatePictureInPictureActions(actions: RCTConvert.pictureInPictureActions(pictureInPictureActions))
34
34
  }
35
+ AsyncFunction("setIsPictureInPictureEnabled") { (view: RNPlayerView, isEnabled: Bool) in
36
+ view.setIsPictureInPictureEnabled(isEnabled)
37
+ }
35
38
  Events(
36
39
  "onBmpEvent",
37
40
  "onBmpPlayerActive",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitmovin-player-react-native",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "Official React Native bindings for Bitmovin's mobile Player SDKs.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -35,6 +35,7 @@ export function PlayerView({
35
35
  scalingMode,
36
36
  isPictureInPictureRequested = false,
37
37
  pictureInPictureActions,
38
+ isPictureInPictureEnabled,
38
39
  ...props
39
40
  }: PlayerViewProps) {
40
41
  // Keep the device awake while the PlayerView is mounted
@@ -109,6 +110,14 @@ export function PlayerView({
109
110
  }
110
111
  }, [isPlayerInitialized, pictureInPictureActions]);
111
112
 
113
+ useEffect(() => {
114
+ if (isPlayerInitialized && isPictureInPictureEnabled != null) {
115
+ void nativeView.current?.setIsPictureInPictureEnabled(
116
+ isPictureInPictureEnabled
117
+ );
118
+ }
119
+ }, [isPlayerInitialized, isPictureInPictureEnabled]);
120
+
112
121
  if (!isPlayerInitialized) {
113
122
  return null;
114
123
  }
@@ -220,4 +229,8 @@ interface InternalPlayerViewRef extends RefObject<any> {
220
229
  updatePictureInPictureActions: (
221
230
  actions: PictureInPictureAction[]
222
231
  ) => Promise<void>;
232
+ /**
233
+ * Enables or disables Picture in Picture mode availability.
234
+ */
235
+ setIsPictureInPictureEnabled: (isEnabled: boolean) => Promise<void>;
223
236
  }
@@ -73,6 +73,14 @@ export interface BasePlayerViewProps {
73
73
  * - iOS: All actions enabled
74
74
  */
75
75
  pictureInPictureActions?: PictureInPictureAction[];
76
+
77
+ /**
78
+ * Enables or disables Picture in Picture mode availability.
79
+ * When disabled, `isPictureInPictureRequested` property has no effect.
80
+ *
81
+ * Can be changed dynamically after the player is initialized.
82
+ */
83
+ isPictureInPictureEnabled?: boolean;
76
84
  }
77
85
 
78
86
  /**
package/src/debug.ts CHANGED
@@ -51,4 +51,16 @@ export class DebugConfig {
51
51
  DebugConfig._isDebugEnabled = value;
52
52
  await DebugModule.setDebugLoggingEnabled(value);
53
53
  }
54
+
55
+ /**
56
+ * Logs a message to the console if debug logging is enabled.
57
+ *
58
+ * @param args - Arguments to pass to `console.log`.
59
+ */
60
+ static log(...args: unknown[]): void {
61
+ if (DebugConfig._isDebugEnabled) {
62
+ // eslint-disable-next-line no-restricted-properties
63
+ console.log(...args);
64
+ }
65
+ }
54
66
  }
package/src/drm/index.ts CHANGED
@@ -5,6 +5,7 @@ import { FairplayConfig } from './fairplayConfig';
5
5
  import { WidevineConfig } from './widevineConfig';
6
6
  import { FairplayDrmApi } from './fairplayDrmApi';
7
7
  import DrmModule from './drmModule';
8
+ import { DebugConfig } from '../debug';
8
9
 
9
10
  // Export config types and API classes from DRM module.
10
11
  export { FairplayConfig, WidevineConfig, FairplayDrmApi };
@@ -276,7 +277,7 @@ export class Drm extends NativeInstance<DrmConfig> {
276
277
  * @param contentId - The extracted contentId string.
277
278
  */
278
279
  private onPrepareContentId = (id: string, contentId: string) => {
279
- console.log('onPrepareContentId', contentId);
280
+ DebugConfig.log('onPrepareContentId', contentId);
280
281
  if (this.config?.fairplay?.prepareContentId) {
281
282
  const result = this.config?.fairplay?.prepareContentId?.(contentId);
282
283
  DrmModule.setPreparedContentId(id, result);
@@ -1,6 +1,7 @@
1
1
  import { EventSubscription } from 'expo-modules-core';
2
2
  import NativeInstance from '../nativeInstance';
3
3
  import NetworkModule from './networkModule';
4
+ import { DebugConfig } from '../debug';
4
5
  import {
5
6
  HttpRequestType,
6
7
  HttpRequest,
@@ -32,12 +33,12 @@ export class Network extends NativeInstance<NetworkConfig> {
32
33
  */
33
34
  initialize = async () => {
34
35
  if (!this.isInitialized) {
35
- console.log('Initializing Network config:', this.nativeId);
36
+ DebugConfig.log('Initializing Network config:', this.nativeId);
36
37
  // Set up event listeners for HTTP request/response preprocessing
37
38
  this.onPreprocessHttpRequestSubscription = NetworkModule.addListener(
38
39
  'onPreprocessHttpRequest',
39
40
  ({ nativeId, requestId, type, request }) => {
40
- console.log(`Received HTTP Request [${type}]:`, request);
41
+ DebugConfig.log(`Received HTTP Request [${type}]:`, request);
41
42
  if (nativeId !== this.nativeId) {
42
43
  return;
43
44
  }
@@ -48,7 +49,7 @@ export class Network extends NativeInstance<NetworkConfig> {
48
49
  this.onPreprocessHttpResponseSubscription = NetworkModule.addListener(
49
50
  'onPreprocessHttpResponse',
50
51
  ({ nativeId, responseId, type, response }) => {
51
- console.log(`Received HTTP Response [${type}]:`, response);
52
+ DebugConfig.log(`Received HTTP Response [${type}]:`, response);
52
53
  if (nativeId !== this.nativeId) {
53
54
  return;
54
55
  }
@@ -66,6 +66,13 @@ export interface PlaybackConfig {
66
66
  * ```
67
67
  */
68
68
  isBackgroundPlaybackEnabled?: boolean;
69
+ /**
70
+ * Whether to automate audio focus management, allowing the player to pause when other apps request focus.
71
+ *
72
+ * @defaultValue `false`
73
+ * @platform Android
74
+ */
75
+ handleAudioFocus?: boolean;
69
76
  /**
70
77
  * Whether the Picture in Picture mode option is enabled or not. Default is `false`.
71
78
  * @example