react-native-theoplayer 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/android/build.gradle +4 -2
  3. package/android/local/com/theoplayer/android-connector/mediasession/4.12.0-local/mediasession-4.12.0-local.aar +0 -0
  4. package/android/local/com/theoplayer/android-connector/mediasession/{4.11.0-local/mediasession-4.11.0-local.pom → 4.12.0-local/mediasession-4.12.0-local.pom} +1 -1
  5. package/android/local/com/theoplayer/android-connector/mediasession/maven-metadata-local.xml +4 -4
  6. package/android/src/main/AndroidManifest.xml +1 -0
  7. package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +28 -0
  8. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +1 -1
  9. package/android/src/main/java/com/theoplayer/ReactTHEOplayerContext.kt +48 -21
  10. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +1 -3
  11. package/android/src/main/java/com/theoplayer/audio/BackgroundAudioConfig.kt +0 -7
  12. package/android/src/main/java/com/theoplayer/audio/BackgroundAudioConfigAdapter.kt +1 -5
  13. package/android/src/main/java/com/theoplayer/audio/MediaNotificationBuilder.kt +1 -3
  14. package/android/src/main/java/com/theoplayer/presentation/PresentationManager.kt +5 -12
  15. package/ios/THEOplayerRCTMainEventHandler.swift +1 -1
  16. package/ios/THEOplayerRCTPlayerAPI.swift +2 -3
  17. package/ios/THEOplayerRCTView.swift +7 -2
  18. package/ios/pip/THEOplayerRCTPipControlsManager.swift +33 -28
  19. package/ios/pip/THEOplayerRCTView+PipConfig.swift +9 -14
  20. package/lib/commonjs/api/backgroundAudio/BackgroundAudioConfiguration.js.map +1 -1
  21. package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
  22. package/lib/commonjs/api/utils/RetryConfiguration.js +2 -0
  23. package/lib/commonjs/api/utils/RetryConfiguration.js.map +1 -0
  24. package/lib/module/api/backgroundAudio/BackgroundAudioConfiguration.js.map +1 -1
  25. package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
  26. package/lib/module/api/utils/RetryConfiguration.js +2 -0
  27. package/lib/module/api/utils/RetryConfiguration.js.map +1 -0
  28. package/lib/typescript/api/backgroundAudio/BackgroundAudioConfiguration.d.ts +0 -9
  29. package/lib/typescript/api/config/PlayerConfiguration.d.ts +8 -0
  30. package/lib/typescript/api/utils/RetryConfiguration.d.ts +21 -0
  31. package/package.json +3 -3
  32. package/react-native-theoplayer.podspec +7 -3
  33. package/src/api/backgroundAudio/BackgroundAudioConfiguration.ts +0 -10
  34. package/src/api/config/PlayerConfiguration.ts +9 -0
  35. package/src/api/utils/RetryConfiguration.ts +23 -0
  36. package/android/local/com/theoplayer/android-connector/mediasession/4.11.0-local/mediasession-4.11.0-local.aar +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.2.0] - 23-04-12
9
+
10
+ ### Fixed
11
+
12
+ - Fixed an issue on Android and iOS where error codes were not correctly formatted.
13
+
14
+ ### Added
15
+
16
+ - Added `RetryConfiguration` on `PlayerConfiguration` for Web and Android.
17
+
18
+ ### Changed
19
+
20
+ - Set minimum THEOplayer dependency version to 5.0.1 for Web, iOS and Android.
21
+ - Set `MediaPlaybackService` disabled by default on Android.
22
+
23
+ ## [2.1.0] - 23-04-09
24
+
25
+ ### Fixed
26
+
27
+ - Fixed invalid location of the typescript declaration file.
28
+ - Fixed an issue on Android where the player would not pause when closing the app while background playback is disabled.
29
+
30
+ ### Changed
31
+
32
+ - Removed `backgroundAudioConfiguration.mediaPlaybackServiceEnabled` property on Android. Disabling background playback disables the service as well.
33
+
8
34
  ## [2.0.0] - 23-04-06
9
35
 
10
36
  ### Added
@@ -105,9 +105,11 @@ dependencies {
105
105
  implementation "com.theoplayer.theoplayer-sdk-android:ads-wrapper:4.8.0"
106
106
  implementation "androidx.appcompat:appcompat:1.4.+"
107
107
 
108
- def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '+')
108
+ // The minimum supported version is 5.0.1
109
+ def theoplayer_sdk_version = safeExtGet('THEOplayer_sdk', '[5.0.1,)')
110
+
109
111
  // def theoplayer_mediasession_version = safeExtGet('THEOplayer_mediasession', theoplayer_sdk_version)
110
- def theoplayer_mediasession_version = "4.11.0-local"
112
+ def theoplayer_mediasession_version = "4.12.0-local"
111
113
  def enabledV4 = theoplayer_sdk_version.toString().startsWith("4.")
112
114
  def core_prefix = enabledV4 ? 'unified' : 'core'
113
115
  def integration_prefix = enabledV4 ? 'unified' : 'integration'
@@ -3,7 +3,7 @@
3
3
  <modelVersion>4.0.0</modelVersion>
4
4
  <groupId>com.theoplayer.android-connector</groupId>
5
5
  <artifactId>mediasession</artifactId>
6
- <version>4.11.0-local</version>
6
+ <version>4.12.0-local</version>
7
7
  <packaging>aar</packaging>
8
8
  <dependencies>
9
9
  <dependency>
@@ -3,11 +3,11 @@
3
3
  <groupId>com.theoplayer.android-connector</groupId>
4
4
  <artifactId>mediasession</artifactId>
5
5
  <versioning>
6
- <latest>4.11.0-local</latest>
7
- <release>4.11.0-local</release>
6
+ <latest>4.12.0-local</latest>
7
+ <release>4.12.0-local</release>
8
8
  <versions>
9
- <version>4.11.0-local</version>
9
+ <version>4.12.0-local</version>
10
10
  </versions>
11
- <lastUpdated>20230403121710</lastUpdated>
11
+ <lastUpdated>20230408184844</lastUpdated>
12
12
  </versioning>
13
13
  </metadata>
@@ -32,6 +32,7 @@
32
32
  android:name="com.theoplayer.audio.MediaPlaybackService"
33
33
  android:description="@string/background_playback_service_description"
34
34
  android:exported="false"
35
+ android:enabled="false"
35
36
  android:foregroundServiceType="mediaPlayback">
36
37
  <intent-filter>
37
38
  <action android:name="android.media.browse.MediaBrowserService" />
@@ -10,6 +10,7 @@ import com.theoplayer.android.api.ads.GoogleImaConfiguration
10
10
  import com.theoplayer.android.api.cast.CastStrategy
11
11
  import com.google.android.gms.cast.framework.CastContext
12
12
  import com.theoplayer.android.api.pip.PipConfiguration
13
+ import com.theoplayer.android.api.player.NetworkConfiguration
13
14
 
14
15
  private const val TAG = "PlayerConfigAdapter"
15
16
  private const val PROP_ADS_CONFIGURATION = "ads"
@@ -24,6 +25,10 @@ private const val PROP_CAST_CONFIGURATION = "cast"
24
25
  private const val PROP_CAST_STRATEGY = "strategy"
25
26
  private const val PROP_CHROMECAST_CONFIG = "chromecast"
26
27
  private const val PROP_CHROMECAST_APPID = "appID"
28
+ private const val PROP_RETRY_CONFIG = "retryConfiguration"
29
+ private const val PROP_RETRY_MAX_RETRIES = "maxRetries"
30
+ private const val PROP_RETRY_MIN_BACKOFF = "minimumBackoff"
31
+ private const val PROP_RETRY_MAX_BACKOFF = "maximumBackoff"
27
32
 
28
33
  object PlayerConfigAdapter {
29
34
 
@@ -45,6 +50,12 @@ object PlayerConfigAdapter {
45
50
  if (configProps.hasKey(PROP_CHROMELESS)) {
46
51
  configBuilder.chromeless(configProps.getBoolean(PROP_CHROMELESS))
47
52
  }
53
+ if (configProps.hasKey(PROP_RETRY_CONFIG)) {
54
+ val networkConfig = networkConfigurationFromProps(configProps.getMap(PROP_RETRY_CONFIG))
55
+ if (networkConfig != null) {
56
+ configBuilder.networkConfiguration(networkConfig)
57
+ }
58
+ }
48
59
  applyCastConfigurationFromProps(configBuilder, configProps.getMap(PROP_CAST_CONFIGURATION))
49
60
  configBuilder.pipConfiguration(PipConfiguration.Builder().build())
50
61
  }
@@ -72,6 +83,23 @@ object PlayerConfigAdapter {
72
83
  return builder.build()
73
84
  }
74
85
 
86
+ private fun networkConfigurationFromProps(configProps: ReadableMap?): NetworkConfiguration? {
87
+ if (configProps == null) {
88
+ return null
89
+ }
90
+ val builder = NetworkConfiguration.Builder()
91
+ if (configProps.hasKey(PROP_RETRY_MAX_RETRIES)) {
92
+ builder.maxRetries(configProps.getInt(PROP_RETRY_MAX_RETRIES))
93
+ }
94
+ if (configProps.hasKey(PROP_RETRY_MIN_BACKOFF)) {
95
+ builder.minimumBackOff(configProps.getDouble(PROP_RETRY_MIN_BACKOFF).toLong())
96
+ }
97
+ if (configProps.hasKey(PROP_RETRY_MAX_BACKOFF)) {
98
+ builder.maximumBackOff(configProps.getDouble(PROP_RETRY_MAX_BACKOFF).toLong())
99
+ }
100
+ return builder.build()
101
+ }
102
+
75
103
  private fun applyCastConfigurationFromProps(
76
104
  configBuilder: THEOplayerConfig.Builder,
77
105
  castConfig: ReadableMap?
@@ -249,7 +249,7 @@ class PlayerEventEmitter internal constructor(
249
249
  }
250
250
 
251
251
  fun emitError(exception: THEOplayerException) {
252
- emitError(exception.code.name, exception.message)
252
+ emitError(exception.code.id.toString(), exception.message)
253
253
  }
254
254
 
255
255
  fun emitPresentationModeChange(
@@ -39,12 +39,9 @@ class ReactTHEOplayerContext private constructor(
39
39
  private var binder: MediaPlaybackService.MediaPlaybackBinder? = null
40
40
  private var mediaSessionConnector: MediaSessionConnector? = null
41
41
 
42
- var backgroundAudioConfig: BackgroundAudioConfig = BackgroundAudioConfig(
43
- enabled = false,
44
- mediaPlaybackServiceEnabled = true
45
- )
42
+ var backgroundAudioConfig: BackgroundAudioConfig = BackgroundAudioConfig(enabled = false)
46
43
  set(value) {
47
- applyBackgroundPlaybackConfig(value)
44
+ applyBackgroundPlaybackConfig(value, field)
48
45
  field = value
49
46
  }
50
47
 
@@ -56,14 +53,18 @@ class ReactTHEOplayerContext private constructor(
56
53
  var daiIntegration: GoogleDaiIntegration? = null
57
54
  var imaIntegration: GoogleImaIntegration? = null
58
55
  var castIntegration: CastIntegration? = null
56
+ var wasPlayingOnHostPause: Boolean = false
59
57
 
60
58
  private val isBackgroundAudioEnabled: Boolean
61
- get() = backgroundAudioConfig.enabled && backgroundAudioConfig.mediaPlaybackServiceEnabled
59
+ get() = backgroundAudioConfig.enabled
62
60
 
63
61
  companion object {
64
62
  private var mediaControlledInstance: ReactTHEOplayerContext? = null
65
63
 
66
- fun create(reactContext: ThemedReactContext, playerConfig: THEOplayerConfig): ReactTHEOplayerContext {
64
+ fun create(
65
+ reactContext: ThemedReactContext,
66
+ playerConfig: THEOplayerConfig
67
+ ): ReactTHEOplayerContext {
67
68
  return ReactTHEOplayerContext(reactContext).apply {
68
69
  initializePlayerView(playerConfig)
69
70
  }
@@ -74,7 +75,10 @@ class ReactTHEOplayerContext private constructor(
74
75
  override fun onServiceConnected(className: ComponentName, service: IBinder) {
75
76
  binder = service as MediaPlaybackService.MediaPlaybackBinder
76
77
 
77
- // Get media session
78
+ // Clean-up any existing media session connector
79
+ mediaSessionConnector?.destroy()
80
+
81
+ // Get media session connector from service
78
82
  mediaSessionConnector = binder?.mediaSessionConnector
79
83
  mediaSessionConnector?.player = player
80
84
  mediaSessionConnector?.setMediaSessionMetadata(player.source)
@@ -91,17 +95,37 @@ class ReactTHEOplayerContext private constructor(
91
95
  }
92
96
  }
93
97
 
94
- private fun applyBackgroundPlaybackConfig(config: BackgroundAudioConfig) {
95
- if (BuildConfig.USE_PLAYBACK_SERVICE) {
96
- reactContext.applicationContext.packageManager.setComponentEnabledSetting(
97
- ComponentName(reactContext.applicationContext, MediaPlaybackService::class.java),
98
- if (config.mediaPlaybackServiceEnabled) PackageManager.COMPONENT_ENABLED_STATE_ENABLED
99
- else PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
100
- PackageManager.DONT_KILL_APP
101
- )
98
+ private fun setPlaybackServiceEnabled(enabled: Boolean) {
99
+ reactContext.applicationContext.packageManager.setComponentEnabledSetting(
100
+ ComponentName(reactContext.applicationContext, MediaPlaybackService::class.java),
101
+ if (enabled) PackageManager.COMPONENT_ENABLED_STATE_ENABLED
102
+ else PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
103
+ PackageManager.DONT_KILL_APP
104
+ )
105
+ }
106
+
107
+ private fun applyBackgroundPlaybackConfig(
108
+ config: BackgroundAudioConfig,
109
+ prevConfig: BackgroundAudioConfig?
110
+ ) {
111
+ if (prevConfig?.enabled == config.enabled) {
112
+ // No changes
113
+ return
102
114
  }
103
115
 
104
- binder?.setEnablePlaybackControls(config.enabled)
116
+ if (BuildConfig.USE_PLAYBACK_SERVICE) {
117
+ if (prevConfig?.enabled != true && config.enabled) {
118
+ // Enabling background playback
119
+ setPlaybackServiceEnabled(true)
120
+ bindMediaPlaybackService()
121
+ } else if (prevConfig?.enabled == true) {
122
+ // Disabling background playback
123
+ binder?.stopForegroundService()
124
+ unbindMediaPlaybackService()
125
+ setPlaybackServiceEnabled(false)
126
+ initDefaultMediaSession()
127
+ }
128
+ }
105
129
  }
106
130
 
107
131
  private fun bindMediaPlaybackService() {
@@ -128,6 +152,7 @@ class ReactTHEOplayerContext private constructor(
128
152
  reactContext.unbindService(connection)
129
153
  }
130
154
  }
155
+ binder = null
131
156
  }
132
157
 
133
158
  private fun initializePlayerView(playerConfig: THEOplayerConfig) {
@@ -156,13 +181,13 @@ class ReactTHEOplayerContext private constructor(
156
181
 
157
182
  if (mediaControlledInstance == null) {
158
183
  mediaControlledInstance = this
159
- if (!BuildConfig.USE_PLAYBACK_SERVICE) {
184
+ if (!BuildConfig.USE_PLAYBACK_SERVICE || !isBackgroundAudioEnabled) {
160
185
  initDefaultMediaSession()
161
186
  }
162
187
  }
163
188
 
164
189
  // Apply initial backgroundPlayback config
165
- applyBackgroundPlaybackConfig(backgroundAudioConfig)
190
+ applyBackgroundPlaybackConfig(backgroundAudioConfig, null)
166
191
  }
167
192
 
168
193
  private fun initDefaultMediaSession() {
@@ -225,7 +250,7 @@ class ReactTHEOplayerContext private constructor(
225
250
  }
226
251
 
227
252
  private val onPlay = EventListener<PlayEvent> {
228
- if (BuildConfig.USE_PLAYBACK_SERVICE) {
253
+ if (BuildConfig.USE_PLAYBACK_SERVICE && isBackgroundAudioEnabled) {
229
254
  bindMediaPlaybackService()
230
255
  }
231
256
  binder?.updateNotification(PlaybackStateCompat.STATE_PLAYING)
@@ -266,8 +291,10 @@ class ReactTHEOplayerContext private constructor(
266
291
  * The host activity is paused.
267
292
  */
268
293
  fun onHostPause() {
294
+ // Keep current playing state when going to background
295
+ wasPlayingOnHostPause = !player.isPaused
296
+
269
297
  if (!isBackgroundAudioEnabled) {
270
- mediaSessionConnector?.setActive(false)
271
298
  playerView.onPause()
272
299
  }
273
300
  }
@@ -85,9 +85,7 @@ class ReactTHEOplayerView(private val reactContext: ThemedReactContext) :
85
85
  if (BuildConfig.LOG_VIEW_EVENTS) {
86
86
  Log.d(TAG, "onHostPause")
87
87
  }
88
- if (presentationManager?.shouldPauseOnHostPause != false) {
89
- playerContext?.onHostPause()
90
- }
88
+ playerContext?.onHostPause()
91
89
  }
92
90
 
93
91
  /**
@@ -7,11 +7,4 @@ data class BackgroundAudioConfig(
7
7
  * @defaultValue `false`
8
8
  */
9
9
  val enabled: Boolean,
10
-
11
- /**
12
- * Set whether the mediaPlaybackService is enabled.
13
- *
14
- * @defaultValue `true`
15
- */
16
- val mediaPlaybackServiceEnabled: Boolean
17
10
  )
@@ -4,16 +4,12 @@ import com.facebook.react.bridge.ReadableMap
4
4
 
5
5
  object BackgroundAudioConfigAdapter {
6
6
  private const val PROP_ENABLED = "enabled"
7
- private const val PROP_SERVICE_ENABLED = "mediaPlaybackServiceEnabled"
8
7
 
9
8
  private const val DEFAULT_ENABLED = false
10
- private const val DEFAULT_SERVICE_ENABLED = true
11
9
 
12
10
  fun fromProps(props: ReadableMap?): BackgroundAudioConfig {
13
11
  val enabled =
14
12
  if (props?.hasKey(PROP_ENABLED) == true) props.getBoolean(PROP_ENABLED) else DEFAULT_ENABLED
15
- val serviceEnabled =
16
- if (props?.hasKey(PROP_SERVICE_ENABLED) == true) props.getBoolean(PROP_SERVICE_ENABLED) else DEFAULT_SERVICE_ENABLED
17
- return BackgroundAudioConfig(enabled, serviceEnabled)
13
+ return BackgroundAudioConfig(enabled)
18
14
  }
19
15
  }
@@ -141,9 +141,7 @@ class MediaNotificationBuilder(
141
141
 
142
142
  // Associate the notification with your session. This allows third-party apps and
143
143
  // companion devices to access and control the session.
144
- if (enableMediaControls) {
145
- style.setMediaSession(mediaSession.sessionToken)
146
- }
144
+ style.setMediaSession(mediaSession.sessionToken)
147
145
 
148
146
  // Add up to 3 actions to be shown in the notification's standard-sized contentView.
149
147
  style.setShowActionsInCompactView(0)
@@ -81,18 +81,6 @@ class PresentationManager(
81
81
  )
82
82
  }
83
83
 
84
- /**
85
- * Whether playback should be allowed to continue when the activity is paused.
86
- *
87
- * Pause if:
88
- * - No PiP available: Build.VERSION.SDK_INT < Build.VERSION_CODES.N (API 24), or;
89
- * - Not in PiP mode, and;
90
- * - Not configured to automatically go into PiP when going to the background.
91
- */
92
- val shouldPauseOnHostPause: Boolean
93
- get() = Build.VERSION.SDK_INT < Build.VERSION_CODES.N ||
94
- (reactContext.currentActivity?.isInPictureInPictureMode != true && pipConfig.startsAutomatically != true)
95
-
96
84
  fun destroy() {
97
85
  try {
98
86
  reactContext.currentActivity?.unregisterReceiver(onUserLeaveHintReceiver)
@@ -241,6 +229,11 @@ class PresentationManager(
241
229
  currentPresentationMode = presentationMode
242
230
  eventEmitter.emitPresentationModeChange(presentationMode, prevPresentationMode, context)
243
231
 
232
+ // Resume playing when going to PiP and player was playing
233
+ if (presentationMode == PresentationMode.PICTURE_IN_PICTURE && viewCtx.wasPlayingOnHostPause) {
234
+ viewCtx.player.play()
235
+ }
236
+
244
237
  // Apply background audio config when closing PiP window
245
238
  if (context?.pip == PresentationModeChangePipContext.CLOSED && !viewCtx.backgroundAudioConfig.enabled) {
246
239
  viewCtx.player.pause()
@@ -239,7 +239,7 @@ class THEOplayerRCTMainEventHandler {
239
239
  if let forwardedErrorEvent = self?.onNativeError,
240
240
  let errorObject = event.errorObject
241
241
  {
242
- let errorCodeString = String(describing: errorObject.code)
242
+ let errorCodeString = String(errorObject.code.rawValue)
243
243
  let errorCodeMessage = errorObject.message
244
244
  forwardedErrorEvent(
245
245
  [
@@ -124,9 +124,9 @@ class THEOplayerRCTPlayerAPI: NSObject, RCTBridgeModule {
124
124
  @objc(setPipConfig:pipConfig:)
125
125
  func setPipConfig(_ node: NSNumber, pipConfig: NSDictionary) -> Void {
126
126
  DispatchQueue.main.async {
127
- let newPipConfig: PipConfig = self.parsePipConfig(configDict: pipConfig)
128
127
  if let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView {
129
- theView.pipConfig = newPipConfig
128
+ let pipConfig = self.parsePipConfig(configDict: pipConfig)
129
+ theView.pipConfig = pipConfig
130
130
  }
131
131
  }
132
132
  return
@@ -134,7 +134,6 @@ class THEOplayerRCTPlayerAPI: NSObject, RCTBridgeModule {
134
134
 
135
135
  private func parsePipConfig(configDict: NSDictionary) -> PipConfig {
136
136
  var pipConfig = PipConfig()
137
- pipConfig.retainPresentationModeOnSourceChange = configDict["retainPresentationModeOnSourceChange"] as? Bool ?? false
138
137
  pipConfig.canStartPictureInPictureAutomaticallyFromInline = configDict["startsAutomatically"] as? Bool ?? false
139
138
  return pipConfig
140
139
  }
@@ -15,10 +15,15 @@ public class THEOplayerRCTView: UIView {
15
15
  var nowPlayingManager: THEOplayerRCTNowPlayingManager
16
16
  var remoteCommandsManager: THEOplayerRCTRemoteCommandsManager
17
17
  var pipControlsManager: THEOplayerRCTPipControlsManager
18
+ var presentationModeContext = THEOplayerRCTPresentationModeContext()
18
19
  var adsConfig = AdsConfig()
19
20
  var castConfig = CastConfig()
20
- var pipConfig = PipConfig()
21
- var presentationModeContext = THEOplayerRCTPresentationModeContext()
21
+
22
+ var pipConfig = PipConfig() {
23
+ didSet {
24
+ self.pipControlsManager.setPipConfig(pipConfig)
25
+ }
26
+ }
22
27
  var backgroundAudioConfig = BackgroundAudioConfig() {
23
28
  didSet {
24
29
  self.remoteCommandsManager.setBackGroundAudioConfig(backgroundAudioConfig)
@@ -8,18 +8,9 @@ import MediaPlayer
8
8
  class THEOplayerRCTPipControlsManager: NSObject {
9
9
  // MARK: Members
10
10
  private weak var player: THEOplayer?
11
- private var _nativePictureInPictureController: Any?
12
11
  private var isLive: Bool = false
13
12
  private var inAd: Bool = false
14
-
15
- @available(tvOS 14.0, *)
16
- private weak var nativePictureInPictureController: AVPictureInPictureController? {
17
- get {
18
- return _nativePictureInPictureController as? AVPictureInPictureController
19
- } set {
20
- _nativePictureInPictureController = newValue
21
- }
22
- }
13
+ private var pipConfig = PipConfig()
23
14
 
24
15
  // MARK: player Listeners
25
16
  private var durationChangeListener: EventListener?
@@ -43,11 +34,13 @@ class THEOplayerRCTPipControlsManager: NSObject {
43
34
  self.attachListeners()
44
35
  }
45
36
 
46
- @available(tvOS 14.0, *)
47
- func setNativePictureInPictureController(_ nativePictureInPictureController: AVPictureInPictureController?) {
48
- self.nativePictureInPictureController = nativePictureInPictureController;
49
- if self.nativePictureInPictureController != nil,
50
- let player = self.player,
37
+ func setPipConfig(_ newPipConfig: PipConfig) {
38
+ self.pipConfig = newPipConfig
39
+ self.updatePipControls()
40
+ }
41
+
42
+ func willStartPip() {
43
+ if let player = self.player,
51
44
  let duration = player.duration {
52
45
  self.isLive = duration.isInfinite
53
46
  #if (GOOGLE_IMA || GOOGLE_DAI) || canImport(THEOplayerGoogleIMAIntegration)
@@ -60,16 +53,32 @@ class THEOplayerRCTPipControlsManager: NSObject {
60
53
  #endif
61
54
  }
62
55
  }
63
-
64
- @available(tvOS 14.0, *)
56
+
65
57
  private func updatePipControls() {
66
- if let controller = self.nativePictureInPictureController {
67
- if #available(iOS 14.0, *) {
68
- controller.requiresLinearPlayback = self.isLive || self.inAd
69
- if DEBUG_PIPCONTROLS { print("[NATIVE] Pip controls updated for \(self.isLive ? "LIVE" : "VOD") (\(self.inAd ? "AD IS PLAYING" : "NO AD PLAYING")).") }
70
- }
58
+ if let player = self.player,
59
+ let pip = player.pip {
60
+ pip.configure(configuration: self.newPipConfiguration())
61
+ if DEBUG_PIPCONTROLS { print("[NATIVE] Pip controls updated for \(self.isLive ? "LIVE" : "VOD") (\(self.inAd ? "AD IS PLAYING" : "NO AD PLAYING")). (requiresLinearPlayback = \(self.isLive || self.inAd), canStartPictureInPictureAutomaticallyFromInline = \(self.pipConfig.canStartPictureInPictureAutomaticallyFromInline))") }
71
62
  }
72
63
  }
64
+
65
+ #if os(iOS)
66
+
67
+ func newPipConfiguration() -> PiPConfiguration {
68
+ return PiPConfiguration(retainPresentationModeOnSourceChange: false,
69
+ nativePictureInPicture: true,
70
+ canStartPictureInPictureAutomaticallyFromInline: self.pipConfig.canStartPictureInPictureAutomaticallyFromInline,
71
+ requiresLinearPlayback: self.isLive || self.inAd)
72
+ }
73
+
74
+ #elseif os(tvOS)
75
+
76
+ func newPipConfiguration() -> PiPConfiguration {
77
+ return PiPConfiguration(retainPresentationModeOnSourceChange: false,
78
+ requiresLinearPlayback: self.isLive || self.inAd)
79
+ }
80
+
81
+ #endif
73
82
 
74
83
  private func attachListeners() {
75
84
  guard let player = self.player else {
@@ -80,9 +89,7 @@ class THEOplayerRCTPipControlsManager: NSObject {
80
89
  self.durationChangeListener = player.addEventListener(type: PlayerEventTypes.DURATION_CHANGE) { [weak self] event in
81
90
  if let duration = event.duration {
82
91
  self?.isLive = duration.isInfinite
83
- if #available(iOS 14.0, tvOS 14.0, *) {
84
- self?.updatePipControls()
85
- }
92
+ self?.updatePipControls()
86
93
  }
87
94
  }
88
95
 
@@ -90,9 +97,7 @@ class THEOplayerRCTPipControlsManager: NSObject {
90
97
  self.sourceChangeListener = player.addEventListener(type: PlayerEventTypes.SOURCE_CHANGE) { [weak self] event in
91
98
  self?.isLive = false
92
99
  self?.inAd = false
93
- if #available(iOS 14.0, tvOS 14.0, *) {
94
- self?.updatePipControls()
95
- }
100
+ self?.updatePipControls()
96
101
  }
97
102
 
98
103
  #if (GOOGLE_IMA || GOOGLE_DAI) || canImport(THEOplayerGoogleIMAIntegration)
@@ -5,25 +5,25 @@ import AVKit
5
5
  import THEOplayerSDK
6
6
 
7
7
  struct PipConfig {
8
- var retainPresentationModeOnSourceChange: Bool = false // external config
9
- var canStartPictureInPictureAutomaticallyFromInline: Bool = false // external config
8
+ var canStartPictureInPictureAutomaticallyFromInline: Bool = false
10
9
  }
11
10
 
12
-
13
11
  extension THEOplayerRCTView: AVPictureInPictureControllerDelegate {
14
12
 
15
13
  #if os(iOS)
16
14
 
17
- func playerPipConfiguration() -> PiPConfiguration? {
18
- return PiPConfiguration(retainPresentationModeOnSourceChange: self.pipConfig.retainPresentationModeOnSourceChange,
15
+ func playerPipConfiguration() -> PiPConfiguration {
16
+ return PiPConfiguration(retainPresentationModeOnSourceChange: false,
19
17
  nativePictureInPicture: true,
20
- canStartPictureInPictureAutomaticallyFromInline: self.pipConfig.canStartPictureInPictureAutomaticallyFromInline)
18
+ canStartPictureInPictureAutomaticallyFromInline: self.pipConfig.canStartPictureInPictureAutomaticallyFromInline,
19
+ requiresLinearPlayback: false)
21
20
  }
22
21
 
23
22
  #elseif os(tvOS)
24
23
 
25
- func playerPipConfiguration() -> PiPConfiguration? {
26
- return PiPConfiguration(retainPresentationModeOnSourceChange: self.pipConfig.retainPresentationModeOnSourceChange)
24
+ func playerPipConfiguration() -> PiPConfiguration {
25
+ return PiPConfiguration(retainPresentationModeOnSourceChange: false,
26
+ requiresLinearPlayback: false)
27
27
  }
28
28
 
29
29
  #endif
@@ -41,12 +41,7 @@ extension THEOplayerRCTView: AVPictureInPictureControllerDelegate {
41
41
  @available(tvOS 14.0, *)
42
42
  public func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
43
43
  self.presentationModeContext.pipContext = .PIP_CLOSED
44
- self.pipControlsManager.setNativePictureInPictureController(pictureInPictureController)
45
- }
46
-
47
- @available(tvOS 14.0, *)
48
- public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
49
- self.pipControlsManager.setNativePictureInPictureController(nil)
44
+ self.pipControlsManager.willStartPip()
50
45
  }
51
46
 
52
47
  @available(tvOS 14.0, *)
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["BackgroundAudioConfiguration.ts"],"sourcesContent":["/**\n * Describes the configuration of the background audio feature.\n *\n * @public\n */\nexport interface BackgroundAudioConfiguration {\n /**\n * Whether background audio should be enabled when transitioning to background.\n *\n * @defaultValue `false`\n */\n readonly enabled?: boolean;\n\n /**\n * Whether Android's mediaPlaybackService is enabled.\n *\n * The mediaPlaybackService is a MediaBrowserService that provides notifications and background playback.\n * It can be dynamically disabled if the host app already registers a MediaBrowserService that conflicts with this one.\n *\n * @defaultValue `true`\n */\n readonly mediaPlaybackServiceEnabled?: boolean;\n}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["BackgroundAudioConfiguration.ts"],"sourcesContent":["/**\n * Describes the configuration of the background audio feature.\n *\n * @public\n */\nexport interface BackgroundAudioConfiguration {\n /**\n * Whether background audio should be enabled when transitioning to background.\n *\n * @defaultValue `false`\n */\n readonly enabled?: boolean;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["PlayerConfiguration.ts"],"sourcesContent":["import type { AdsConfiguration } from '../ads/AdsConfiguration';\nimport type { CastConfiguration } from '../cast/CastConfiguration';\nimport type { MediaControlConfiguration } from '../media/MediaControlConfiguration';\n\nexport interface PlayerConfiguration {\n /**\n * The directory in which the THEOplayer library worker files are located.\n * These worker files are THEOplayer.transmux.*\n *\n * @remarks\n * <br/> - This parameter is required when using a HLS source and has no default.\n *\n * @example\n * `'/lib/theoplayer/'`\n */\n libraryLocation?: string;\n\n /**\n * The muted autoplay policy for web.\n *\n * @remarks\n * <br/> - The muted autoplay policy is impacted by this property and {@link SourceConfiguration.mutedAutoplay}.\n *\n * @defaultValue `'none'`.\n */\n mutedAutoplay?: MutedAutoplayConfiguration;\n\n /**\n * The ads configuration for the player.\n */\n ads?: AdsConfiguration;\n\n /**\n * The cast configuration for the player.\n */\n cast?: CastConfiguration;\n\n /**\n * The configuration of media controls and media sessions across platforms.\n */\n mediaControl?: MediaControlConfiguration;\n\n /**\n * The license for the player\n */\n readonly license?: string;\n\n /**\n * The url to fetch the license for the player\n */\n readonly licenseUrl?: string;\n\n /**\n * Sets whether the native player is chromeless (without UI).\n */\n readonly chromeless?: boolean;\n}\n\n/**\n * The muted autoplay policy of a player for web.\n * <br/> - `'none'`: Disallow muted autoplay. If the player is requested to autoplay while unmuted, and the platform does not support unmuted autoplay, the player will not start playback.\n * <br/> - `'all'`: Allow muted autoplay. If the player is requested to autoplay while unmuted, and the platform supports muted autoplay, the player will start muted playback.\n * <br/> - `'content'`: Allow muted autoplay only for the main content. Disallow muted autoplay for e.g. advertisements. (Not yet supported.)\n *\n * @public\n */\nexport type MutedAutoplayConfiguration = 'none' | 'all' | 'content';\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["PlayerConfiguration.ts"],"sourcesContent":["import type { AdsConfiguration } from '../ads/AdsConfiguration';\nimport type { CastConfiguration } from '../cast/CastConfiguration';\nimport type { MediaControlConfiguration } from '../media/MediaControlConfiguration';\nimport type { RetryConfiguration } from '../utils/RetryConfiguration';\n\nexport interface PlayerConfiguration {\n /**\n * The directory in which the THEOplayer library worker files are located.\n * These worker files are THEOplayer.transmux.*\n *\n * @remarks\n * <br/> - This parameter is required when using a HLS source and has no default.\n *\n * @example\n * `'/lib/theoplayer/'`\n */\n libraryLocation?: string;\n\n /**\n * The muted autoplay policy for web.\n *\n * @remarks\n * <br/> - The muted autoplay policy is impacted by this property and {@link SourceConfiguration.mutedAutoplay}.\n *\n * @defaultValue `'none'`.\n */\n mutedAutoplay?: MutedAutoplayConfiguration;\n\n /**\n * The ads configuration for the player.\n */\n ads?: AdsConfiguration;\n\n /**\n * The cast configuration for the player.\n */\n cast?: CastConfiguration;\n\n /**\n * The configuration of media controls and media sessions across platforms.\n */\n mediaControl?: MediaControlConfiguration;\n\n /**\n * The license for the player\n */\n readonly license?: string;\n\n /**\n * The url to fetch the license for the player\n */\n readonly licenseUrl?: string;\n\n /**\n * Sets whether the native player is chromeless (without UI).\n */\n readonly chromeless?: boolean;\n\n /**\n * The retry configuration for the player.\n *\n * @remarks\n * <br/> - This parameter only applies to Web and Android platforms.\n */\n readonly retryConfiguration?: RetryConfiguration;\n}\n\n/**\n * The muted autoplay policy of a player for web.\n * <br/> - `'none'`: Disallow muted autoplay. If the player is requested to autoplay while unmuted, and the platform does not support unmuted autoplay, the player will not start playback.\n * <br/> - `'all'`: Allow muted autoplay. If the player is requested to autoplay while unmuted, and the platform supports muted autoplay, the player will start muted playback.\n * <br/> - `'content'`: Allow muted autoplay only for the main content. Disallow muted autoplay for e.g. advertisements. (Not yet supported.)\n *\n * @public\n */\nexport type MutedAutoplayConfiguration = 'none' | 'all' | 'content';\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=RetryConfiguration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["RetryConfiguration.ts"],"sourcesContent":["/**\n * Object containing values used for the player's retry mechanisms.\n */\nexport interface RetryConfiguration {\n /**\n * The maximum amount of retries before the player throws a fatal error.\n * Defaults to `Infinity`.\n */\n readonly maxRetries?: number;\n\n /**\n * The initial delay in milliseconds before a retry request occurs.\n * Exponential backoff will be applied on this value.\n * Defaults to `200`.\n */\n readonly minimumBackoff?: number;\n\n /**\n * The maximum amount of delay in milliseconds between retry requests.\n * Defaults to `30000`.\n */\n readonly maximumBackoff?: number;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["BackgroundAudioConfiguration.ts"],"sourcesContent":["/**\n * Describes the configuration of the background audio feature.\n *\n * @public\n */\nexport interface BackgroundAudioConfiguration {\n /**\n * Whether background audio should be enabled when transitioning to background.\n *\n * @defaultValue `false`\n */\n readonly enabled?: boolean;\n\n /**\n * Whether Android's mediaPlaybackService is enabled.\n *\n * The mediaPlaybackService is a MediaBrowserService that provides notifications and background playback.\n * It can be dynamically disabled if the host app already registers a MediaBrowserService that conflicts with this one.\n *\n * @defaultValue `true`\n */\n readonly mediaPlaybackServiceEnabled?: boolean;\n}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["BackgroundAudioConfiguration.ts"],"sourcesContent":["/**\n * Describes the configuration of the background audio feature.\n *\n * @public\n */\nexport interface BackgroundAudioConfiguration {\n /**\n * Whether background audio should be enabled when transitioning to background.\n *\n * @defaultValue `false`\n */\n readonly enabled?: boolean;\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["PlayerConfiguration.ts"],"sourcesContent":["import type { AdsConfiguration } from '../ads/AdsConfiguration';\nimport type { CastConfiguration } from '../cast/CastConfiguration';\nimport type { MediaControlConfiguration } from '../media/MediaControlConfiguration';\n\nexport interface PlayerConfiguration {\n /**\n * The directory in which the THEOplayer library worker files are located.\n * These worker files are THEOplayer.transmux.*\n *\n * @remarks\n * <br/> - This parameter is required when using a HLS source and has no default.\n *\n * @example\n * `'/lib/theoplayer/'`\n */\n libraryLocation?: string;\n\n /**\n * The muted autoplay policy for web.\n *\n * @remarks\n * <br/> - The muted autoplay policy is impacted by this property and {@link SourceConfiguration.mutedAutoplay}.\n *\n * @defaultValue `'none'`.\n */\n mutedAutoplay?: MutedAutoplayConfiguration;\n\n /**\n * The ads configuration for the player.\n */\n ads?: AdsConfiguration;\n\n /**\n * The cast configuration for the player.\n */\n cast?: CastConfiguration;\n\n /**\n * The configuration of media controls and media sessions across platforms.\n */\n mediaControl?: MediaControlConfiguration;\n\n /**\n * The license for the player\n */\n readonly license?: string;\n\n /**\n * The url to fetch the license for the player\n */\n readonly licenseUrl?: string;\n\n /**\n * Sets whether the native player is chromeless (without UI).\n */\n readonly chromeless?: boolean;\n}\n\n/**\n * The muted autoplay policy of a player for web.\n * <br/> - `'none'`: Disallow muted autoplay. If the player is requested to autoplay while unmuted, and the platform does not support unmuted autoplay, the player will not start playback.\n * <br/> - `'all'`: Allow muted autoplay. If the player is requested to autoplay while unmuted, and the platform supports muted autoplay, the player will start muted playback.\n * <br/> - `'content'`: Allow muted autoplay only for the main content. Disallow muted autoplay for e.g. advertisements. (Not yet supported.)\n *\n * @public\n */\nexport type MutedAutoplayConfiguration = 'none' | 'all' | 'content';\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["PlayerConfiguration.ts"],"sourcesContent":["import type { AdsConfiguration } from '../ads/AdsConfiguration';\nimport type { CastConfiguration } from '../cast/CastConfiguration';\nimport type { MediaControlConfiguration } from '../media/MediaControlConfiguration';\nimport type { RetryConfiguration } from '../utils/RetryConfiguration';\n\nexport interface PlayerConfiguration {\n /**\n * The directory in which the THEOplayer library worker files are located.\n * These worker files are THEOplayer.transmux.*\n *\n * @remarks\n * <br/> - This parameter is required when using a HLS source and has no default.\n *\n * @example\n * `'/lib/theoplayer/'`\n */\n libraryLocation?: string;\n\n /**\n * The muted autoplay policy for web.\n *\n * @remarks\n * <br/> - The muted autoplay policy is impacted by this property and {@link SourceConfiguration.mutedAutoplay}.\n *\n * @defaultValue `'none'`.\n */\n mutedAutoplay?: MutedAutoplayConfiguration;\n\n /**\n * The ads configuration for the player.\n */\n ads?: AdsConfiguration;\n\n /**\n * The cast configuration for the player.\n */\n cast?: CastConfiguration;\n\n /**\n * The configuration of media controls and media sessions across platforms.\n */\n mediaControl?: MediaControlConfiguration;\n\n /**\n * The license for the player\n */\n readonly license?: string;\n\n /**\n * The url to fetch the license for the player\n */\n readonly licenseUrl?: string;\n\n /**\n * Sets whether the native player is chromeless (without UI).\n */\n readonly chromeless?: boolean;\n\n /**\n * The retry configuration for the player.\n *\n * @remarks\n * <br/> - This parameter only applies to Web and Android platforms.\n */\n readonly retryConfiguration?: RetryConfiguration;\n}\n\n/**\n * The muted autoplay policy of a player for web.\n * <br/> - `'none'`: Disallow muted autoplay. If the player is requested to autoplay while unmuted, and the platform does not support unmuted autoplay, the player will not start playback.\n * <br/> - `'all'`: Allow muted autoplay. If the player is requested to autoplay while unmuted, and the platform supports muted autoplay, the player will start muted playback.\n * <br/> - `'content'`: Allow muted autoplay only for the main content. Disallow muted autoplay for e.g. advertisements. (Not yet supported.)\n *\n * @public\n */\nexport type MutedAutoplayConfiguration = 'none' | 'all' | 'content';\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=RetryConfiguration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["RetryConfiguration.ts"],"sourcesContent":["/**\n * Object containing values used for the player's retry mechanisms.\n */\nexport interface RetryConfiguration {\n /**\n * The maximum amount of retries before the player throws a fatal error.\n * Defaults to `Infinity`.\n */\n readonly maxRetries?: number;\n\n /**\n * The initial delay in milliseconds before a retry request occurs.\n * Exponential backoff will be applied on this value.\n * Defaults to `200`.\n */\n readonly minimumBackoff?: number;\n\n /**\n * The maximum amount of delay in milliseconds between retry requests.\n * Defaults to `30000`.\n */\n readonly maximumBackoff?: number;\n}\n"],"mappings":""}
@@ -10,13 +10,4 @@ export interface BackgroundAudioConfiguration {
10
10
  * @defaultValue `false`
11
11
  */
12
12
  readonly enabled?: boolean;
13
- /**
14
- * Whether Android's mediaPlaybackService is enabled.
15
- *
16
- * The mediaPlaybackService is a MediaBrowserService that provides notifications and background playback.
17
- * It can be dynamically disabled if the host app already registers a MediaBrowserService that conflicts with this one.
18
- *
19
- * @defaultValue `true`
20
- */
21
- readonly mediaPlaybackServiceEnabled?: boolean;
22
13
  }
@@ -1,6 +1,7 @@
1
1
  import type { AdsConfiguration } from '../ads/AdsConfiguration';
2
2
  import type { CastConfiguration } from '../cast/CastConfiguration';
3
3
  import type { MediaControlConfiguration } from '../media/MediaControlConfiguration';
4
+ import type { RetryConfiguration } from '../utils/RetryConfiguration';
4
5
  export interface PlayerConfiguration {
5
6
  /**
6
7
  * The directory in which the THEOplayer library worker files are located.
@@ -46,6 +47,13 @@ export interface PlayerConfiguration {
46
47
  * Sets whether the native player is chromeless (without UI).
47
48
  */
48
49
  readonly chromeless?: boolean;
50
+ /**
51
+ * The retry configuration for the player.
52
+ *
53
+ * @remarks
54
+ * <br/> - This parameter only applies to Web and Android platforms.
55
+ */
56
+ readonly retryConfiguration?: RetryConfiguration;
49
57
  }
50
58
  /**
51
59
  * The muted autoplay policy of a player for web.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Object containing values used for the player's retry mechanisms.
3
+ */
4
+ export interface RetryConfiguration {
5
+ /**
6
+ * The maximum amount of retries before the player throws a fatal error.
7
+ * Defaults to `Infinity`.
8
+ */
9
+ readonly maxRetries?: number;
10
+ /**
11
+ * The initial delay in milliseconds before a retry request occurs.
12
+ * Exponential backoff will be applied on this value.
13
+ * Defaults to `200`.
14
+ */
15
+ readonly minimumBackoff?: number;
16
+ /**
17
+ * The maximum amount of delay in milliseconds between retry requests.
18
+ * Defaults to `30000`.
19
+ */
20
+ readonly maximumBackoff?: number;
21
+ }
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "react-native-theoplayer",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "A THEOplayer video component for react-native.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
7
- "types": "lib/typescript/src/index.d.ts",
7
+ "types": "lib/typescript/index.d.ts",
8
8
  "react-native": "src/index",
9
9
  "source": "src/index",
10
10
  "files": [
@@ -116,7 +116,7 @@
116
116
  "react-native-svg": "^13.8.0",
117
117
  "react-native-svg-web": "^1.0.0",
118
118
  "react-native-url-polyfill": "^1.3.0",
119
- "theoplayer": "^4.6.0",
119
+ "theoplayer": ">=5.0.1",
120
120
  "url-polyfill": "^1.1.12"
121
121
  }
122
122
  }
@@ -2,11 +2,11 @@ require "json"
2
2
 
3
3
  package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
4
  theoconfigpath = File.join(__dir__ + "/../../", "react-native-theoplayer.json")
5
- if File.exists?(theoconfigpath)
5
+ if File.exist?(theoconfigpath)
6
6
  theoconfig = JSON.parse(File.read(theoconfigpath))
7
7
  theofeatures = theoconfig["ios"]["features"]
8
8
  else
9
- theofeatures = []
9
+ theofeatures = ["NONE"]
10
10
  end
11
11
 
12
12
  Pod::Spec.new do |s|
@@ -28,17 +28,21 @@ Pod::Spec.new do |s|
28
28
 
29
29
  # THEOplayer Dependencies
30
30
  if theofeatures.include?("WEB")
31
+ puts "Using THEOplayer-basic SDK, marked features: #{theofeatures.join(' ')}"
31
32
  s.dependency "THEOplayerSDK-basic"
32
33
  s.pod_target_xcconfig = {
33
34
  'SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Release]' => theofeatures.join(' '),
34
35
  'SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug]' => theofeatures.join(' ')
35
36
  }
36
37
  else
37
- s.dependency "THEOplayerSDK-core"
38
+ puts "Using THEOplayer-core SDK"
39
+ s.dependency "THEOplayerSDK-core", "~> 5.0.1"
38
40
  if theofeatures.include?("GOOGLE_IMA")
41
+ puts "Adding THEOplayer-Integration-GoogleIMA"
39
42
  s.dependency "THEOplayer-Integration-GoogleIMA"
40
43
  end
41
44
  if theofeatures.include?("CHROMECAST")
45
+ puts "Adding THEOplayer-Integration-GoogleCast"
42
46
  s.ios.dependency "THEOplayer-Integration-GoogleCast"
43
47
  s.ios.dependency "google-cast-sdk-dynamic-xcframework-no-bluetooth"
44
48
  end
@@ -10,14 +10,4 @@ export interface BackgroundAudioConfiguration {
10
10
  * @defaultValue `false`
11
11
  */
12
12
  readonly enabled?: boolean;
13
-
14
- /**
15
- * Whether Android's mediaPlaybackService is enabled.
16
- *
17
- * The mediaPlaybackService is a MediaBrowserService that provides notifications and background playback.
18
- * It can be dynamically disabled if the host app already registers a MediaBrowserService that conflicts with this one.
19
- *
20
- * @defaultValue `true`
21
- */
22
- readonly mediaPlaybackServiceEnabled?: boolean;
23
13
  }
@@ -1,6 +1,7 @@
1
1
  import type { AdsConfiguration } from '../ads/AdsConfiguration';
2
2
  import type { CastConfiguration } from '../cast/CastConfiguration';
3
3
  import type { MediaControlConfiguration } from '../media/MediaControlConfiguration';
4
+ import type { RetryConfiguration } from '../utils/RetryConfiguration';
4
5
 
5
6
  export interface PlayerConfiguration {
6
7
  /**
@@ -54,6 +55,14 @@ export interface PlayerConfiguration {
54
55
  * Sets whether the native player is chromeless (without UI).
55
56
  */
56
57
  readonly chromeless?: boolean;
58
+
59
+ /**
60
+ * The retry configuration for the player.
61
+ *
62
+ * @remarks
63
+ * <br/> - This parameter only applies to Web and Android platforms.
64
+ */
65
+ readonly retryConfiguration?: RetryConfiguration;
57
66
  }
58
67
 
59
68
  /**
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Object containing values used for the player's retry mechanisms.
3
+ */
4
+ export interface RetryConfiguration {
5
+ /**
6
+ * The maximum amount of retries before the player throws a fatal error.
7
+ * Defaults to `Infinity`.
8
+ */
9
+ readonly maxRetries?: number;
10
+
11
+ /**
12
+ * The initial delay in milliseconds before a retry request occurs.
13
+ * Exponential backoff will be applied on this value.
14
+ * Defaults to `200`.
15
+ */
16
+ readonly minimumBackoff?: number;
17
+
18
+ /**
19
+ * The maximum amount of delay in milliseconds between retry requests.
20
+ * Defaults to `30000`.
21
+ */
22
+ readonly maximumBackoff?: number;
23
+ }