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.
- package/.eslintrc.js +8 -0
- package/CHANGELOG.md +34 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/OfflineModule.kt +3 -1
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerView.kt +107 -168
- package/android/src/main/java/com/bitmovin/player/reactnative/RNPlayerViewManager.kt +5 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/converter/JsonConverter.kt +1 -0
- package/android/src/main/java/com/bitmovin/player/reactnative/ui/RNPictureInPictureHandler.kt +8 -6
- package/build/components/PlayerView/index.d.ts +1 -1
- package/build/components/PlayerView/index.d.ts.map +1 -1
- package/build/components/PlayerView/index.js +6 -1
- package/build/components/PlayerView/index.js.map +1 -1
- package/build/components/PlayerView/properties.d.ts +7 -0
- package/build/components/PlayerView/properties.d.ts.map +1 -1
- package/build/components/PlayerView/properties.js.map +1 -1
- package/build/debug.d.ts +6 -0
- package/build/debug.d.ts.map +1 -1
- package/build/debug.js +11 -0
- package/build/debug.js.map +1 -1
- package/build/drm/index.d.ts.map +1 -1
- package/build/drm/index.js +2 -1
- package/build/drm/index.js.map +1 -1
- package/build/network/index.d.ts.map +1 -1
- package/build/network/index.js +4 -3
- package/build/network/index.js.map +1 -1
- package/build/playbackConfig.d.ts +7 -0
- package/build/playbackConfig.d.ts.map +1 -1
- package/build/playbackConfig.js.map +1 -1
- package/ios/Event+JSON.swift +2 -2
- package/ios/RNBitmovinPlayer.podspec +1 -1
- package/ios/RNPlayerView.swift +9 -0
- package/ios/RNPlayerViewManager.swift +3 -0
- package/package.json +1 -1
- package/src/components/PlayerView/index.tsx +13 -0
- package/src/components/PlayerView/properties.ts +8 -0
- package/src/debug.ts +12 -0
- package/src/drm/index.ts +2 -1
- package/src/network/index.ts +4 -3
- 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
|
-
|
|
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.
|
|
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
|
-
|
|
441
|
-
|
|
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
|
-
|
|
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
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
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
|
-
|
|
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 {
|
package/android/src/main/java/com/bitmovin/player/reactnative/ui/RNPictureInPictureHandler.kt
CHANGED
|
@@ -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
|
|
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(
|
|
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,
|
|
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;
|
|
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
|
package/build/debug.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
package/build/debug.js.map
CHANGED
|
@@ -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"]}
|
package/build/drm/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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"}
|
package/build/drm/index.js
CHANGED
|
@@ -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
|
-
|
|
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);
|
package/build/drm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;AAEpC,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,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;QAC7C,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';\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":"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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';\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;
|
|
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"}
|
package/build/network/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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":"AACA,OAAO,cAAc,MAAM,mBAAmB,CAAC;AAC/C,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,eAAe,GAIhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,eAAe,EAA4C,CAAC;AAErE;;;GAGG;AACH,MAAM,OAAO,OAAQ,SAAQ,cAA6B;IACxD;;OAEG;IACH,aAAa,GAAG,KAAK,CAAC;IACtB;;OAEG;IACH,WAAW,GAAG,KAAK,CAAC;IAEZ,mCAAmC,CAAqB;IACxD,oCAAoC,CAAqB;IAEjE;;OAEG;IACH,UAAU,GAAG,KAAK,IAAI,EAAE;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,
|
|
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"]}
|
package/ios/Event+JSON.swift
CHANGED
|
@@ -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.
|
|
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
|
|
package/ios/RNPlayerView.swift
CHANGED
|
@@ -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
|
@@ -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
|
-
|
|
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);
|
package/src/network/index.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
52
|
+
DebugConfig.log(`Received HTTP Response [${type}]:`, response);
|
|
52
53
|
if (nativeId !== this.nativeId) {
|
|
53
54
|
return;
|
|
54
55
|
}
|
package/src/playbackConfig.ts
CHANGED
|
@@ -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
|