bitmovin-player-react-native 0.20.0 → 0.22.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.
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
19
19
  s.source_files = "ios/**/*.{h,m,mm,swift}"
20
20
 
21
21
  s.dependency "React-Core"
22
- s.dependency "BitmovinPlayer", "3.57.2"
23
- s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.18.4"
24
- s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.8.2"
22
+ s.dependency "BitmovinPlayer", "3.60.0"
23
+ s.ios.dependency "GoogleAds-IMA-iOS-SDK", "3.19.1"
24
+ s.tvos.dependency "GoogleAds-IMA-tvOS-SDK", "4.9.2"
25
25
  end
@@ -103,5 +103,5 @@ dependencies {
103
103
  // Bitmovin
104
104
  implementation 'com.google.ads.interactivemedia.v3:interactivemedia:3.31.0'
105
105
  implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
106
- implementation 'com.bitmovin.player:player:3.64.0+jason'
106
+ implementation 'com.bitmovin.player:player:3.65.0+jason'
107
107
  }
@@ -2,8 +2,7 @@ package com.bitmovin.player.reactnative
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.content.res.Configuration
5
- import android.graphics.Rect
6
- import android.view.View
5
+ import android.os.Build
7
6
  import android.view.ViewGroup
8
7
  import android.widget.FrameLayout
9
8
  import androidx.lifecycle.DefaultLifecycleObserver
@@ -17,8 +16,6 @@ import com.bitmovin.player.api.event.SourceEvent
17
16
  import com.bitmovin.player.api.ui.PlayerViewConfig
18
17
  import com.bitmovin.player.api.ui.StyleConfig
19
18
  import com.bitmovin.player.reactnative.converter.toJson
20
- import com.bitmovin.player.reactnative.ui.RNPictureInPictureDelegate
21
- import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler
22
19
  import com.facebook.react.ReactActivity
23
20
  import com.facebook.react.bridge.*
24
21
  import com.facebook.react.uimanager.events.RCTEventEmitter
@@ -101,7 +98,7 @@ private val EVENT_CLASS_TO_REACT_NATIVE_NAME_MAPPING_UI = mapOf<KClass<out Event
101
98
  @SuppressLint("ViewConstructor")
102
99
  class RNPlayerView(
103
100
  private val context: ReactApplicationContext,
104
- ) : FrameLayout(context), View.OnLayoutChangeListener, RNPictureInPictureDelegate {
101
+ ) : FrameLayout(context) {
105
102
  private val activityLifecycle = (context.currentActivity as? ReactActivity)?.lifecycle
106
103
  ?: error("Trying to create an instance of ${this::class.simpleName} while not attached to a ReactActivity")
107
104
 
@@ -153,7 +150,6 @@ class RNPlayerView(
153
150
 
154
151
  private var _playerView: PlayerView? = null
155
152
  set(value) {
156
- field?.removeOnLayoutChangeListener(this)
157
153
  field = value
158
154
  viewEventRelay.eventEmitter = field
159
155
  playerEventRelay.eventEmitter = field?.player
@@ -176,11 +172,6 @@ class RNPlayerView(
176
172
  playerEventRelay.eventEmitter = value
177
173
  }
178
174
 
179
- /**
180
- * Object that handles PiP mode changes in React Native.
181
- */
182
- var pictureInPictureHandler: RNPictureInPictureHandler? = null
183
-
184
175
  /**
185
176
  * Configures the visual presentation and behaviour of the [playerView].
186
177
  */
@@ -214,11 +205,6 @@ class RNPlayerView(
214
205
  (playerView.parent as ViewGroup?)?.removeView(playerView)
215
206
  addView(playerView, 0)
216
207
  }
217
- pictureInPictureHandler?.let {
218
- it.setDelegate(this)
219
- playerView.setPictureInPictureHandler(it)
220
- playerView.addOnLayoutChangeListener(this)
221
- }
222
208
  }
223
209
 
224
210
  /**
@@ -232,61 +218,38 @@ class RNPlayerView(
232
218
  addView(subtitleView)
233
219
  }
234
220
 
235
- /**
236
- * Called whenever this view's activity configuration changes.
237
- */
238
- override fun onConfigurationChanged(newConfig: Configuration?) {
239
- super.onConfigurationChanged(newConfig)
240
- pictureInPictureHandler?.onConfigurationChanged(newConfig)
241
- }
242
-
243
- /**
244
- * Called when the player has just entered PiP mode.
245
- */
246
- override fun onEnterPictureInPicture() {
247
- // Nothing to do
248
- }
249
-
250
- /**
251
- * Called when the player has just exited PiP mode.
252
- */
253
- override fun onExitPictureInPicture() {
254
- // Explicitly call `exitPictureInPicture()` on PlayerView when exiting PiP state, otherwise
255
- // the `PictureInPictureExit` event won't get dispatched.
256
- playerView?.exitPictureInPicture()
221
+ private fun isInPictureInPictureMode(): Boolean {
222
+ val activity = context.currentActivity ?: return false
223
+ return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
224
+ activity.isInPictureInPictureMode
225
+ } else {
226
+ false
227
+ }
257
228
  }
258
229
 
259
- /**
260
- * Called when the player's PiP mode changes with a new configuration object.
261
- */
262
- override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration?) {
263
- playerView?.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
264
- }
230
+ private var isCurrentActivityInPictureInPictureMode: Boolean = isInPictureInPictureMode()
265
231
 
266
232
  /**
267
- * Called whenever the PiP handler needs to compute the PlayerView's global visible rect.
233
+ * Called whenever this view's activity configuration changes.
268
234
  */
269
- override fun setSourceRectHint(sourceRectHint: Rect) {
270
- playerView?.getGlobalVisibleRect(sourceRectHint)
235
+ override fun onConfigurationChanged(newConfig: Configuration) {
236
+ super.onConfigurationChanged(newConfig)
237
+ if (isCurrentActivityInPictureInPictureMode != isInPictureInPictureMode()) {
238
+ isCurrentActivityInPictureInPictureMode = isInPictureInPictureMode()
239
+ onPictureInPictureModeChanged(isCurrentActivityInPictureInPictureMode, newConfig)
240
+ }
271
241
  }
272
242
 
273
- /**
274
- * Called whenever PlayerView's layout changes.
275
- */
276
- override fun onLayoutChange(
277
- view: View?,
278
- left: Int,
279
- top: Int,
280
- right: Int,
281
- bottom: Int,
282
- oldLeft: Int,
283
- oldTop: Int,
284
- oldRight: Int,
285
- oldBottom: Int,
243
+ private fun onPictureInPictureModeChanged(
244
+ isInPictureInPictureMode: Boolean,
245
+ newConfig: Configuration,
286
246
  ) {
287
- if (left != oldLeft || right != oldRight || top != oldTop || bottom != oldBottom) {
288
- // Update source rect hint whenever the player's layout change
289
- pictureInPictureHandler?.updateSourceRectHint()
247
+ val playerView = playerView ?: return
248
+ playerView.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
249
+ if (isInPictureInPictureMode) {
250
+ playerView.enterPictureInPicture()
251
+ } else {
252
+ playerView.exitPictureInPicture()
290
253
  }
291
254
  }
292
255
 
@@ -341,7 +304,7 @@ class RNPlayerView(
341
304
  */
342
305
  data class RNPlayerViewConfigWrapper(
343
306
  val playerViewConfig: PlayerViewConfig?,
344
- val pictureInPictureConfig: RNPictureInPictureHandler.PictureInPictureConfig?,
307
+ val pictureInPictureConfig: PictureInPictureConfig?,
345
308
  )
346
309
 
347
310
  data class RNStyleConfigWrapper(
@@ -352,3 +315,8 @@ data class RNStyleConfigWrapper(
352
315
  enum class UserInterfaceType {
353
316
  Bitmovin, Subtitle
354
317
  }
318
+
319
+ /**
320
+ * Configuration type for picture in picture behaviors.
321
+ */
322
+ data class PictureInPictureConfig(val isEnabled: Boolean)
@@ -164,6 +164,7 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
164
164
  val command = commandId?.toInt()?.toCommand() ?: throw IllegalArgumentException(
165
165
  "The received command is not supported by the Bitmovin Player View",
166
166
  )
167
+
167
168
  fun <T> T?.require(): T = this ?: throw InvalidParameterException("Missing parameter")
168
169
  when (command) {
169
170
  Commands.ATTACH_PLAYER -> attachPlayer(view, args?.getString(1).require(), args?.getMap(2))
@@ -172,6 +173,7 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
172
173
  view,
173
174
  args?.getString(1).require(),
174
175
  )
176
+
175
177
  Commands.SET_FULLSCREEN -> setFullscreen(view, args?.getBoolean(1).require())
176
178
  Commands.SET_SCALING_MODE -> setScalingMode(view, args?.getString(1).require())
177
179
  Commands.SET_PICTURE_IN_PICTURE -> setPictureInPicture(view, args?.getBoolean(1).require())
@@ -246,9 +248,6 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
246
248
  val playbackConfig = playerConfig?.getMap("playbackConfig")
247
249
  val isPictureInPictureEnabled = view.config?.pictureInPictureConfig?.isEnabled == true ||
248
250
  playbackConfig?.getBooleanOrNull("isPictureInPictureEnabled") == true
249
- val pictureInPictureHandler = view.pictureInPictureHandler ?: RNPictureInPictureHandler(context)
250
- view.pictureInPictureHandler = pictureInPictureHandler
251
- view.pictureInPictureHandler?.isPictureInPictureEnabled = isPictureInPictureEnabled
252
251
 
253
252
  val rnStyleConfigWrapper = playerConfig?.toRNStyleConfigWrapperFromPlayerConfig()
254
253
  val configuredPlayerViewConfig = view.config?.playerViewConfig ?: PlayerViewConfig()
@@ -272,6 +271,9 @@ class RNPlayerViewManager(private val context: ReactApplicationContext) : Simple
272
271
  LayoutParams.MATCH_PARENT,
273
272
  LayoutParams.MATCH_PARENT,
274
273
  )
274
+ if (isPictureInPictureEnabled) {
275
+ playerView.setPictureInPictureHandler(RNPictureInPictureHandler(currentActivity, player))
276
+ }
275
277
  view.setPlayerView(playerView)
276
278
  attachCustomMessageHandlerBridge(view)
277
279
  }
@@ -47,6 +47,7 @@ import com.bitmovin.player.api.ui.ScalingMode
47
47
  import com.bitmovin.player.api.ui.StyleConfig
48
48
  import com.bitmovin.player.api.ui.UiConfig
49
49
  import com.bitmovin.player.reactnative.BitmovinCastManagerOptions
50
+ import com.bitmovin.player.reactnative.PictureInPictureConfig
50
51
  import com.bitmovin.player.reactnative.RNBufferLevels
51
52
  import com.bitmovin.player.reactnative.RNPlayerViewConfigWrapper
52
53
  import com.bitmovin.player.reactnative.RNStyleConfigWrapper
@@ -70,7 +71,6 @@ import com.bitmovin.player.reactnative.extensions.withInt
70
71
  import com.bitmovin.player.reactnative.extensions.withMap
71
72
  import com.bitmovin.player.reactnative.extensions.withString
72
73
  import com.bitmovin.player.reactnative.extensions.withStringArray
73
- import com.bitmovin.player.reactnative.ui.RNPictureInPictureHandler.PictureInPictureConfig
74
74
  import com.facebook.react.bridge.*
75
75
  import java.util.UUID
76
76
 
@@ -217,6 +217,7 @@ fun ReadableMap.toAdSource(): AdSource? {
217
217
  * Converts any JS string into an `AdSourceType` enum value.
218
218
  */
219
219
  private fun String.toAdSourceType(): AdSourceType? = when (this) {
220
+ "bitmovin" -> AdSourceType.Bitmovin
220
221
  "ima" -> AdSourceType.Ima
221
222
  "progressive" -> AdSourceType.Progressive
222
223
  "unknown" -> AdSourceType.Unknown
@@ -626,6 +627,7 @@ fun AdSource.toJson(): WritableMap = Arguments.createMap().apply {
626
627
  * Converts any `AdSourceType` value into its json representation.
627
628
  */
628
629
  fun AdSourceType.toJson(): String = when (this) {
630
+ AdSourceType.Bitmovin -> "bitmovin"
629
631
  AdSourceType.Ima -> "ima"
630
632
  AdSourceType.Unknown -> "unknown"
631
633
  AdSourceType.Progressive -> "progressive"
@@ -1,200 +1,59 @@
1
1
  package com.bitmovin.player.reactnative.ui
2
2
 
3
+ import android.app.Activity
3
4
  import android.app.PictureInPictureParams
4
- import android.content.pm.PackageManager
5
- import android.content.res.Configuration
6
- import android.graphics.Rect
7
5
  import android.os.Build
6
+ import android.util.Log
8
7
  import android.util.Rational
9
8
  import androidx.annotation.RequiresApi
10
- import androidx.appcompat.app.AppCompatActivity
11
- import com.bitmovin.player.api.ui.PictureInPictureHandler
12
- import com.facebook.react.bridge.ReactApplicationContext
9
+ import com.bitmovin.player.api.Player
10
+ import com.bitmovin.player.ui.DefaultPictureInPictureHandler
11
+
12
+ private const val TAG = "RNPiPHandler"
13
+
14
+ class RNPictureInPictureHandler(
15
+ private val activity: Activity,
16
+ private val player: Player,
17
+ ) : DefaultPictureInPictureHandler(activity, player) {
18
+ // Current PiP implementation on the native side requires playerView.exitPictureInPicture() to be called
19
+ // for `PictureInPictureExit` event to be emitted.
20
+ // Additionally, the event is only emitted if `isPictureInPicture` is true. At the point in time we call
21
+ // playerView.exitPictureInPicture() the activity will already have exited the PiP mode,
22
+ // and thus the event won't be emitted. To work around this we keep track of the PiP state ourselves.
23
+ private var _isPictureInPicture = false
13
24
 
14
- /**
15
- * Delegate object for `RNPictureInPictureHandler`. It delegates all view logic that needs
16
- * to be performed during each PiP state to this object.
17
- */
18
- interface RNPictureInPictureDelegate {
19
- /**
20
- * Called whenever the handler's `isInPictureInPictureMode` changes to `true`.
21
- */
22
- fun onExitPictureInPicture()
23
-
24
- /**
25
- * Called whenever the handler's `isInPictureInPictureMode` changes to `false`.
26
- */
27
- fun onEnterPictureInPicture()
28
-
29
- /**
30
- * Called whenever the activity's PiP mode state changes with the new resources configuration.
31
- */
32
- fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration?)
33
-
34
- /**
35
- * Called whenever the handler needs to compute a new `sourceRectHint` for PiP params.
36
- * The passed rect reference is expected to be fulfilled with the PlayerView's global visible
37
- * rect.
38
- */
39
- fun setSourceRectHint(sourceRectHint: Rect)
40
- }
41
-
42
- /**
43
- * Custom PictureInPictureHandler` concrete implementation designed for React Native. It relies on
44
- * React Native's application context to manage the application's PiP state. Can be subclassed in
45
- * order to provide custom PiP capabilities.
46
- */
47
- open class RNPictureInPictureHandler(val context: ReactApplicationContext) : PictureInPictureHandler {
48
- /**
49
- * Configuration type for picture in picture behaviors.
50
- */
51
- data class PictureInPictureConfig(val isEnabled: Boolean)
52
-
53
- /**
54
- * PiP delegate object that contains the view logic to be performed on each PiP state change.
55
- */
56
- private var delegate: RNPictureInPictureDelegate? = null
57
-
58
- /**
59
- * Whether the user has enabled PiP support via `isPictureInPictureEnabled` playback configuration in JS.
60
- */
61
- var isPictureInPictureEnabled = false
62
-
63
- /**
64
- * Whether this view is currently in PiP mode.
65
- */
66
- private var isInPictureInPictureMode = false
67
-
68
- /**
69
- * Whether the current Android version supports PiP mode.
70
- */
71
- private val isPictureInPictureSupported: Boolean
72
- get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N &&
73
- context.packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)
74
-
75
- /**
76
- * Whether the picture in picture feature is available and enabled.
77
- */
78
- override val isPictureInPictureAvailable: Boolean
79
- get() = isPictureInPictureEnabled && isPictureInPictureSupported
80
-
81
- /**
82
- * Whether this view is currently in PiP mode. Required for PictureInPictureHandler interface.
83
- */
84
25
  override val isPictureInPicture: Boolean
85
- get() = isInPictureInPictureMode
86
-
87
- /**
88
- * Current React activity computed property.
89
- */
90
- private val currentActivity: AppCompatActivity?
91
- get() {
92
- if (context.hasCurrentActivity()) {
93
- return context.currentActivity as AppCompatActivity
94
- }
95
- return null
96
- }
97
-
98
- /**
99
- * Sets the new delegate object and update the activity's PiP parameters accordingly.
100
- */
101
- open fun setDelegate(delegate: RNPictureInPictureDelegate?) {
102
- this.delegate = delegate
103
- // Update the activity's PiP params once the delegate has been set.
104
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isPictureInPictureAvailable) {
105
- applyPictureInPictureParams()
106
- }
107
- }
26
+ get() = _isPictureInPicture
108
27
 
109
- /**
110
- * Called whenever bitmovin's `PlayerView` needs to enter PiP mode.
111
- */
28
+ @RequiresApi(Build.VERSION_CODES.O)
112
29
  override fun enterPictureInPicture() {
113
- if (isPictureInPictureAvailable) {
114
- currentActivity?.let {
115
- it.supportActionBar?.hide()
116
- it.enterPictureInPictureMode()
117
- }
30
+ if (!isPictureInPictureAvailable) {
31
+ Log.w(TAG, "Calling enterPictureInPicture without PiP support.")
32
+ return
118
33
  }
119
- }
120
34
 
121
- /**
122
- * Called whenever bitmovin's `PlayerView` needs to exit PiP mode.
123
- */
124
- override fun exitPictureInPicture() {
125
- if (isPictureInPictureAvailable) {
126
- currentActivity?.supportActionBar?.show()
35
+ if (isPictureInPicture) {
36
+ return
127
37
  }
128
- }
129
38
 
130
- /**
131
- * Called whenever the activity content resources have changed.
132
- */
133
- open fun onConfigurationChanged(newConfig: Configuration?) {
134
- // PiP mode is supported since Android 7.0
135
- if (isPictureInPictureAvailable) {
136
- handlePictureInPictureModeChanges(newConfig)
137
- }
138
- }
39
+ // The default implementation doesn't properly handle the case where source isn't loaded yet.
40
+ // To work around it we just use a 16:9 aspect ratio if we cannot calculate it from `playbackVideoData`.
41
+ val aspectRatio =
42
+ player.playbackVideoData
43
+ ?.let { Rational(it.width, it.height) }
44
+ ?: Rational(16, 9)
139
45
 
140
- /**
141
- * Checks whether the current activity `isInPictureInPictureMode` has changed since the last lifecycle
142
- * configuration change.
143
- */
144
- @RequiresApi(Build.VERSION_CODES.N)
145
- private fun handlePictureInPictureModeChanges(newConfig: Configuration?) = currentActivity?.let {
146
- if (isInPictureInPictureMode != it.isInPictureInPictureMode) {
147
- delegate?.onPictureInPictureModeChanged(it.isInPictureInPictureMode, newConfig)
148
- if (it.isInPictureInPictureMode) {
149
- delegate?.onEnterPictureInPicture()
150
- } else {
151
- delegate?.onExitPictureInPicture()
152
- }
153
- isInPictureInPictureMode = it.isInPictureInPictureMode
154
- }
155
- }
46
+ val params =
47
+ PictureInPictureParams.Builder()
48
+ .setAspectRatio(aspectRatio)
49
+ .build()
156
50
 
157
- /**
158
- * Applies Android recommended PiP params on the current activity for smoother transitions.
159
- *
160
- * You can read more about the recommended settings for PiP here:
161
- * - https://developer.android.com/develop/ui/views/picture-in-picture#smoother-transition
162
- * - https://developer.android.com/develop/ui/views/picture-in-picture#smoother-exit
163
- */
164
- @RequiresApi(Build.VERSION_CODES.O)
165
- private fun applyPictureInPictureParams() = currentActivity?.let {
166
- // See also: https://developer.android.com/develop/ui/views/picture-in-picture#smoother-transition
167
- val sourceRectHint = Rect()
168
- delegate?.setSourceRectHint(sourceRectHint)
169
- val ratio = Rational(16, 9)
170
- val params = PictureInPictureParams.Builder()
171
- .setAspectRatio(ratio)
172
- .setSourceRectHint(sourceRectHint)
173
- when {
174
- // See also: https://developer.android.com/develop/ui/views/picture-in-picture#smoother-exit
175
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ->
176
- params.setAutoEnterEnabled(true).setSeamlessResizeEnabled(true)
177
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ->
178
- params.setExpandedAspectRatio(ratio)
179
- }
180
- it.setPictureInPictureParams(params.build())
51
+ activity.enterPictureInPictureMode(params)
52
+ _isPictureInPicture = true
181
53
  }
182
54
 
183
- /**
184
- * Update source rect hint on activity's PiP params.
185
- */
186
- open fun updateSourceRectHint() {
187
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !isPictureInPictureAvailable) {
188
- return
189
- }
190
- currentActivity?.let {
191
- val sourceRectHint = Rect()
192
- delegate?.setSourceRectHint(sourceRectHint)
193
- it.setPictureInPictureParams(
194
- PictureInPictureParams.Builder()
195
- .setSourceRectHint(sourceRectHint)
196
- .build(),
197
- )
198
- }
55
+ override fun exitPictureInPicture() {
56
+ super.exitPictureInPicture()
57
+ _isPictureInPicture = false
199
58
  }
200
59
  }
@@ -159,6 +159,11 @@ extension RCTConvert {
159
159
  break
160
160
  }
161
161
  }
162
+ #if !os(tvOS)
163
+ if let updatesNowPlayingInfoCenter = json["updatesNowPlayingInfoCenter"] as? Bool {
164
+ tweaksConfig.updatesNowPlayingInfoCenter = updatesNowPlayingInfoCenter
165
+ }
166
+ #endif
162
167
  return tweaksConfig
163
168
  }
164
169
 
package/lib/index.d.mts CHANGED
@@ -2786,6 +2786,18 @@ interface TweaksConfig {
2786
2786
  * @platform Android
2787
2787
  */
2788
2788
  preferSoftwareDecodingForAds?: boolean;
2789
+ /**
2790
+ * Determines whether `AVKit` should update Now Playing information automatically when using System UI.
2791
+ *
2792
+ * - If set to `false`, the automatic updates of Now Playing Info sent by `AVKit` are disabled.
2793
+ * This prevents interference with manual updates you may want to perform.
2794
+ * - If set to `true`, the default behaviour is maintained, allowing `AVKit` to handle Now Playing updates.
2795
+ *
2796
+ * Default is `true`.
2797
+ *
2798
+ * @platform iOS
2799
+ */
2800
+ updatesNowPlayingInfoCenter?: boolean;
2789
2801
  }
2790
2802
 
2791
2803
  /**
package/lib/index.d.ts CHANGED
@@ -2786,6 +2786,18 @@ interface TweaksConfig {
2786
2786
  * @platform Android
2787
2787
  */
2788
2788
  preferSoftwareDecodingForAds?: boolean;
2789
+ /**
2790
+ * Determines whether `AVKit` should update Now Playing information automatically when using System UI.
2791
+ *
2792
+ * - If set to `false`, the automatic updates of Now Playing Info sent by `AVKit` are disabled.
2793
+ * This prevents interference with manual updates you may want to perform.
2794
+ * - If set to `true`, the default behaviour is maintained, allowing `AVKit` to handle Now Playing updates.
2795
+ *
2796
+ * Default is `true`.
2797
+ *
2798
+ * @platform iOS
2799
+ */
2800
+ updatesNowPlayingInfoCenter?: boolean;
2789
2801
  }
2790
2802
 
2791
2803
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitmovin-player-react-native",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Official React Native bindings for Bitmovin's mobile Player SDKs.",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
@@ -157,4 +157,16 @@ export interface TweaksConfig {
157
157
  * @platform Android
158
158
  */
159
159
  preferSoftwareDecodingForAds?: boolean;
160
+ /**
161
+ * Determines whether `AVKit` should update Now Playing information automatically when using System UI.
162
+ *
163
+ * - If set to `false`, the automatic updates of Now Playing Info sent by `AVKit` are disabled.
164
+ * This prevents interference with manual updates you may want to perform.
165
+ * - If set to `true`, the default behaviour is maintained, allowing `AVKit` to handle Now Playing updates.
166
+ *
167
+ * Default is `true`.
168
+ *
169
+ * @platform iOS
170
+ */
171
+ updatesNowPlayingInfoCenter?: boolean;
160
172
  }