react-native-theoplayer 9.10.0 → 10.1.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 (236) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +2 -1
  3. package/android/build.gradle +11 -12
  4. package/android/local/com/theoplayer/theoplayer-sdk-android/ads-wrapper/10.0.0/ads-wrapper-10.0.0.aar +0 -0
  5. package/android/local/com/theoplayer/theoplayer-sdk-android/ads-wrapper/{9.0.0/ads-wrapper-9.0.0.pom → 10.0.0/ads-wrapper-10.0.0.pom} +3 -3
  6. package/android/local/com/theoplayer/theoplayer-sdk-android/ads-wrapper/maven-metadata-local.xml +4 -4
  7. package/android/src/main/AndroidManifest.xml +1 -1
  8. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +39 -10
  9. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +32 -14
  10. package/android/src/main/java/com/theoplayer/ads/AdsModule.kt +18 -6
  11. package/android/src/main/java/com/theoplayer/broadcast/EventBroadcastModule.kt +15 -5
  12. package/android/src/main/java/com/theoplayer/cache/CacheAdapter.kt +0 -12
  13. package/android/src/main/java/com/theoplayer/cache/CacheModule.kt +20 -7
  14. package/android/src/main/java/com/theoplayer/cast/CastEventAdapter.kt +11 -7
  15. package/android/src/main/java/com/theoplayer/cast/CastModule.kt +17 -3
  16. package/android/src/main/java/com/theoplayer/drm/ContentProtectionAdapter.kt +1 -1
  17. package/android/src/main/java/com/theoplayer/drm/ContentProtectionModule.kt +28 -11
  18. package/android/src/main/java/com/theoplayer/media/ConditionalMediaButtonReceiver.kt +38 -0
  19. package/android/src/main/java/com/theoplayer/player/PlayerModule.kt +17 -4
  20. package/android/src/main/java/com/theoplayer/presentation/PresentationManager.kt +12 -3
  21. package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +16 -37
  22. package/android/src/main/java/com/theoplayer/theoads/THEOadsAdapter.kt +83 -0
  23. package/android/src/main/java/com/theoplayer/theoads/THEOadsEventAdapter.kt +55 -0
  24. package/android/src/main/java/com/theoplayer/theoads/THEOadsModule.kt +63 -0
  25. package/android/src/main/java/com/theoplayer/theolive/THEOliveEventAdapter.kt +21 -8
  26. package/android/src/main/java/com/theoplayer/theolive/THEOliveModule.kt +16 -3
  27. package/android/src/main/java/com/theoplayer/track/TextTrackStyleAdapter.kt +8 -1
  28. package/android/src/main/java/com/theoplayer/util/PayloadBuilder.kt +8 -0
  29. package/ios/THEOplayerRCTBridge.m +21 -1
  30. package/ios/THEOplayerRCTDebug.swift +4 -1
  31. package/ios/THEOplayerRCTMainEventHandler.swift +24 -21
  32. package/ios/THEOplayerRCTPlayerAPI.swift +3 -3
  33. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +2 -1
  34. package/ios/THEOplayerRCTView.swift +22 -4
  35. package/ios/backgroundAudio/THEOplayerRCTNowPlayingManager.swift +96 -50
  36. package/ios/backgroundAudio/THEOplayerRCTRemoteCommandsManager.swift +0 -1
  37. package/ios/casting/THEOplayerRCTCastEventHandler.swift +1 -1
  38. package/ios/presentationMode/THEOplayerRCTPresentationModeManager.swift +24 -6
  39. package/ios/theoAds/THEOplayerRCTTHEOAdsAPI.swift +101 -0
  40. package/ios/theoAds/THEOplayerRCTTHEOAdsEventAdapter.swift +118 -0
  41. package/ios/theoAds/THEOplayerRCTTHEOAdsEventHandler.swift +174 -0
  42. package/ios/theolive/THEOplayerRCTSourceDescriptionBuilder+Theolive.swift +0 -1
  43. package/ios/theolive/THEOplayerRCTTHEOliveEventHandler.swift +1 -1
  44. package/ios/theolive/THEOplayerRCTView+THEOlive.swift +1 -5
  45. package/ios/theolive/THEOplayerRCTView+THEOliveConfig.swift +0 -2
  46. package/lib/commonjs/api/barrel.js +45 -56
  47. package/lib/commonjs/api/barrel.js.map +1 -1
  48. package/lib/commonjs/api/cache/CachingTaskParameters.js +0 -19
  49. package/lib/commonjs/api/cache/CachingTaskParameters.js.map +1 -1
  50. package/lib/commonjs/api/event/PlayerEvent.js +16 -0
  51. package/lib/commonjs/api/event/PlayerEvent.js.map +1 -1
  52. package/lib/commonjs/api/event/TheoAdsEvent.js +7 -0
  53. package/lib/commonjs/api/event/TheoAdsEvent.js.map +1 -1
  54. package/lib/commonjs/api/player/PlayerEventMap.js +2 -0
  55. package/lib/commonjs/api/player/PlayerEventMap.js.map +1 -1
  56. package/lib/commonjs/api/source/SourceDescription.js +1 -13
  57. package/lib/commonjs/api/source/SourceDescription.js.map +1 -1
  58. package/lib/commonjs/api/source/ads/{THEOplayerAdDescription.js → CsaiAdDescription.js} +1 -1
  59. package/lib/commonjs/api/source/ads/CsaiAdDescription.js.map +1 -0
  60. package/lib/commonjs/api/source/ads/barrel.js +4 -4
  61. package/lib/commonjs/api/source/ads/barrel.js.map +1 -1
  62. package/lib/commonjs/api/track/Quality.js +37 -0
  63. package/lib/commonjs/api/track/Quality.js.map +1 -1
  64. package/lib/commonjs/api/track/TextTrackStyle.js.map +1 -1
  65. package/lib/commonjs/index.js +0 -8
  66. package/lib/commonjs/index.js.map +1 -1
  67. package/lib/commonjs/internal/THEOplayerView.js +15 -3
  68. package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
  69. package/lib/commonjs/internal/THEOplayerView.web.js +1 -1
  70. package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
  71. package/lib/commonjs/internal/adapter/DefaultNativePlayerState.js +2 -0
  72. package/lib/commonjs/internal/adapter/DefaultNativePlayerState.js.map +1 -1
  73. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js +27 -9
  74. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
  75. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js +18 -1
  76. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  77. package/lib/commonjs/internal/adapter/WebEventForwarder.js +15 -1
  78. package/lib/commonjs/internal/adapter/WebEventForwarder.js.map +1 -1
  79. package/lib/commonjs/internal/adapter/event/PlayerEvents.js +30 -1
  80. package/lib/commonjs/internal/adapter/event/PlayerEvents.js.map +1 -1
  81. package/lib/commonjs/internal/adapter/event/native/NativeTheoAdsEvent.js +20 -0
  82. package/lib/commonjs/internal/adapter/event/native/NativeTheoAdsEvent.js.map +1 -0
  83. package/lib/commonjs/internal/adapter/theoads/THEOAdsNativeAdapter.js +6 -12
  84. package/lib/commonjs/internal/adapter/theoads/THEOAdsNativeAdapter.js.map +1 -1
  85. package/lib/commonjs/internal/adapter/track/TextTrackStyleAdapter.js +10 -0
  86. package/lib/commonjs/internal/adapter/track/TextTrackStyleAdapter.js.map +1 -1
  87. package/lib/commonjs/internal/utils/TypeUtils.js +4 -1
  88. package/lib/commonjs/internal/utils/TypeUtils.js.map +1 -1
  89. package/lib/commonjs/manifest.json +1 -1
  90. package/lib/module/api/barrel.js +0 -1
  91. package/lib/module/api/barrel.js.map +1 -1
  92. package/lib/module/api/cache/CachingTaskParameters.js +1 -19
  93. package/lib/module/api/cache/CachingTaskParameters.js.map +1 -1
  94. package/lib/module/api/event/PlayerEvent.js +18 -0
  95. package/lib/module/api/event/PlayerEvent.js.map +1 -1
  96. package/lib/module/api/event/TheoAdsEvent.js +8 -0
  97. package/lib/module/api/event/TheoAdsEvent.js.map +1 -1
  98. package/lib/module/api/player/PlayerEventMap.js +2 -0
  99. package/lib/module/api/player/PlayerEventMap.js.map +1 -1
  100. package/lib/module/api/source/SourceDescription.js +0 -13
  101. package/lib/module/api/source/SourceDescription.js.map +1 -1
  102. package/lib/module/api/source/ads/CsaiAdDescription.js +4 -0
  103. package/lib/module/api/source/ads/CsaiAdDescription.js.map +1 -0
  104. package/lib/module/api/source/ads/barrel.js +1 -1
  105. package/lib/module/api/source/ads/barrel.js.map +1 -1
  106. package/lib/module/api/track/Quality.js +34 -0
  107. package/lib/module/api/track/Quality.js.map +1 -1
  108. package/lib/module/api/track/TextTrackStyle.js.map +1 -1
  109. package/lib/module/index.js +0 -1
  110. package/lib/module/index.js.map +1 -1
  111. package/lib/module/internal/THEOplayerView.js +16 -4
  112. package/lib/module/internal/THEOplayerView.js.map +1 -1
  113. package/lib/module/internal/THEOplayerView.web.js +1 -1
  114. package/lib/module/internal/THEOplayerView.web.js.map +1 -1
  115. package/lib/module/internal/adapter/DefaultNativePlayerState.js +2 -0
  116. package/lib/module/internal/adapter/DefaultNativePlayerState.js.map +1 -1
  117. package/lib/module/internal/adapter/THEOplayerAdapter.js +28 -10
  118. package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
  119. package/lib/module/internal/adapter/THEOplayerWebAdapter.js +18 -1
  120. package/lib/module/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  121. package/lib/module/internal/adapter/WebEventForwarder.js +16 -2
  122. package/lib/module/internal/adapter/WebEventForwarder.js.map +1 -1
  123. package/lib/module/internal/adapter/event/PlayerEvents.js +26 -0
  124. package/lib/module/internal/adapter/event/PlayerEvents.js.map +1 -1
  125. package/lib/module/internal/adapter/event/native/NativeTheoAdsEvent.js +16 -0
  126. package/lib/module/internal/adapter/event/native/NativeTheoAdsEvent.js.map +1 -0
  127. package/lib/module/internal/adapter/theoads/THEOAdsNativeAdapter.js +6 -12
  128. package/lib/module/internal/adapter/theoads/THEOAdsNativeAdapter.js.map +1 -1
  129. package/lib/module/internal/adapter/track/TextTrackStyleAdapter.js +10 -0
  130. package/lib/module/internal/adapter/track/TextTrackStyleAdapter.js.map +1 -1
  131. package/lib/module/internal/utils/TypeUtils.js +3 -0
  132. package/lib/module/internal/utils/TypeUtils.js.map +1 -1
  133. package/lib/module/manifest.json +1 -1
  134. package/lib/typescript/api/barrel.d.ts +0 -1
  135. package/lib/typescript/api/barrel.d.ts.map +1 -1
  136. package/lib/typescript/api/cache/CachingTaskParameters.d.ts +0 -34
  137. package/lib/typescript/api/cache/CachingTaskParameters.d.ts.map +1 -1
  138. package/lib/typescript/api/event/PlayerEvent.d.ts +36 -0
  139. package/lib/typescript/api/event/PlayerEvent.d.ts.map +1 -1
  140. package/lib/typescript/api/event/TheoAdsEvent.d.ts +13 -0
  141. package/lib/typescript/api/event/TheoAdsEvent.d.ts.map +1 -1
  142. package/lib/typescript/api/player/PlayerEventMap.d.ts +17 -2
  143. package/lib/typescript/api/player/PlayerEventMap.d.ts.map +1 -1
  144. package/lib/typescript/api/player/THEOplayer.d.ts +8 -0
  145. package/lib/typescript/api/player/THEOplayer.d.ts.map +1 -1
  146. package/lib/typescript/api/source/SourceDescription.d.ts +0 -20
  147. package/lib/typescript/api/source/SourceDescription.d.ts.map +1 -1
  148. package/lib/typescript/api/source/ads/{THEOplayerAdDescription.d.ts → CsaiAdDescription.d.ts} +2 -2
  149. package/lib/typescript/api/source/ads/CsaiAdDescription.d.ts.map +1 -0
  150. package/lib/typescript/api/source/ads/barrel.d.ts +1 -1
  151. package/lib/typescript/api/source/ads/barrel.d.ts.map +1 -1
  152. package/lib/typescript/api/track/Quality.d.ts +1 -0
  153. package/lib/typescript/api/track/Quality.d.ts.map +1 -1
  154. package/lib/typescript/api/track/TextTrackStyle.d.ts +7 -0
  155. package/lib/typescript/api/track/TextTrackStyle.d.ts.map +1 -1
  156. package/lib/typescript/index.d.ts +0 -1
  157. package/lib/typescript/index.d.ts.map +1 -1
  158. package/lib/typescript/internal/THEOplayerView.d.ts +3 -1
  159. package/lib/typescript/internal/THEOplayerView.d.ts.map +1 -1
  160. package/lib/typescript/internal/adapter/DefaultNativePlayerState.d.ts +2 -0
  161. package/lib/typescript/internal/adapter/DefaultNativePlayerState.d.ts.map +1 -1
  162. package/lib/typescript/internal/adapter/NativePlayerState.d.ts +2 -0
  163. package/lib/typescript/internal/adapter/NativePlayerState.d.ts.map +1 -1
  164. package/lib/typescript/internal/adapter/THEOplayerAdapter.d.ts +5 -3
  165. package/lib/typescript/internal/adapter/THEOplayerAdapter.d.ts.map +1 -1
  166. package/lib/typescript/internal/adapter/THEOplayerWebAdapter.d.ts +5 -0
  167. package/lib/typescript/internal/adapter/THEOplayerWebAdapter.d.ts.map +1 -1
  168. package/lib/typescript/internal/adapter/WebEventForwarder.d.ts +1 -0
  169. package/lib/typescript/internal/adapter/WebEventForwarder.d.ts.map +1 -1
  170. package/lib/typescript/internal/adapter/event/PlayerEvents.d.ts +20 -1
  171. package/lib/typescript/internal/adapter/event/PlayerEvents.d.ts.map +1 -1
  172. package/lib/typescript/internal/adapter/event/native/NativePlayerEvent.d.ts +11 -1
  173. package/lib/typescript/internal/adapter/event/native/NativePlayerEvent.d.ts.map +1 -1
  174. package/lib/typescript/internal/adapter/event/native/NativeTheoAdsEvent.d.ts +18 -0
  175. package/lib/typescript/internal/adapter/event/native/NativeTheoAdsEvent.d.ts.map +1 -0
  176. package/lib/typescript/internal/adapter/theoads/THEOAdsNativeAdapter.d.ts +1 -1
  177. package/lib/typescript/internal/adapter/theoads/THEOAdsNativeAdapter.d.ts.map +1 -1
  178. package/lib/typescript/internal/adapter/track/TextTrackStyleAdapter.d.ts +3 -0
  179. package/lib/typescript/internal/adapter/track/TextTrackStyleAdapter.d.ts.map +1 -1
  180. package/lib/typescript/internal/utils/TypeUtils.d.ts +1 -0
  181. package/lib/typescript/internal/utils/TypeUtils.d.ts.map +1 -1
  182. package/package.json +6 -6
  183. package/react-native-theoplayer.podspec +7 -7
  184. package/src/api/barrel.ts +0 -1
  185. package/src/api/cache/CachingTaskParameters.ts +0 -37
  186. package/src/api/event/PlayerEvent.ts +40 -0
  187. package/src/api/event/TheoAdsEvent.ts +14 -0
  188. package/src/api/player/PlayerEventMap.ts +19 -0
  189. package/src/api/player/THEOplayer.ts +10 -0
  190. package/src/api/source/SourceDescription.ts +0 -22
  191. package/src/api/source/ads/{THEOplayerAdDescription.ts → CsaiAdDescription.ts} +1 -1
  192. package/src/api/source/ads/barrel.ts +1 -1
  193. package/src/api/track/Quality.ts +15 -0
  194. package/src/api/track/TextTrackStyle.ts +8 -0
  195. package/src/index.tsx +0 -1
  196. package/src/internal/THEOplayerView.tsx +24 -5
  197. package/src/internal/THEOplayerView.web.tsx +1 -1
  198. package/src/internal/adapter/DefaultNativePlayerState.ts +2 -0
  199. package/src/internal/adapter/NativePlayerState.ts +2 -0
  200. package/src/internal/adapter/THEOplayerAdapter.ts +43 -21
  201. package/src/internal/adapter/THEOplayerWebAdapter.ts +22 -2
  202. package/src/internal/adapter/WebEventForwarder.ts +17 -1
  203. package/src/internal/adapter/event/PlayerEvents.ts +34 -0
  204. package/src/internal/adapter/event/native/NativePlayerEvent.ts +13 -1
  205. package/src/internal/adapter/event/native/NativeTheoAdsEvent.ts +30 -0
  206. package/src/internal/adapter/theoads/THEOAdsNativeAdapter.ts +7 -12
  207. package/src/internal/adapter/track/TextTrackStyleAdapter.ts +12 -0
  208. package/src/internal/utils/TypeUtils.ts +6 -0
  209. package/src/manifest.json +1 -1
  210. package/android/local/com/theoplayer/theoplayer-sdk-android/ads-wrapper/9.0.0/ads-wrapper-9.0.0.aar +0 -0
  211. package/android/src/main/java/com/theoplayer/playback/PlaybackSettingsModule.kt +0 -28
  212. package/lib/commonjs/api/playback/PlaybackSettingsAPI.js +0 -2
  213. package/lib/commonjs/api/playback/PlaybackSettingsAPI.js.map +0 -1
  214. package/lib/commonjs/api/playback/barrel.js +0 -17
  215. package/lib/commonjs/api/playback/barrel.js.map +0 -1
  216. package/lib/commonjs/api/source/ads/THEOplayerAdDescription.js.map +0 -1
  217. package/lib/commonjs/internal/playback/PlaybackSettings.js +0 -28
  218. package/lib/commonjs/internal/playback/PlaybackSettings.js.map +0 -1
  219. package/lib/module/api/playback/PlaybackSettingsAPI.js +0 -2
  220. package/lib/module/api/playback/PlaybackSettingsAPI.js.map +0 -1
  221. package/lib/module/api/playback/barrel.js +0 -4
  222. package/lib/module/api/playback/barrel.js.map +0 -1
  223. package/lib/module/api/source/ads/THEOplayerAdDescription.js +0 -4
  224. package/lib/module/api/source/ads/THEOplayerAdDescription.js.map +0 -1
  225. package/lib/module/internal/playback/PlaybackSettings.js +0 -23
  226. package/lib/module/internal/playback/PlaybackSettings.js.map +0 -1
  227. package/lib/typescript/api/playback/PlaybackSettingsAPI.d.ts +0 -35
  228. package/lib/typescript/api/playback/PlaybackSettingsAPI.d.ts.map +0 -1
  229. package/lib/typescript/api/playback/barrel.d.ts +0 -2
  230. package/lib/typescript/api/playback/barrel.d.ts.map +0 -1
  231. package/lib/typescript/api/source/ads/THEOplayerAdDescription.d.ts.map +0 -1
  232. package/lib/typescript/internal/playback/PlaybackSettings.d.ts +0 -7
  233. package/lib/typescript/internal/playback/PlaybackSettings.d.ts.map +0 -1
  234. package/src/api/playback/PlaybackSettingsAPI.ts +0 -36
  235. package/src/api/playback/barrel.ts +0 -1
  236. package/src/internal/playback/PlaybackSettings.ts +0 -25
@@ -16,6 +16,7 @@ class THEOplayerRCTNowPlayingManager {
16
16
  private var rateChangeListener: EventListener?
17
17
  private var seekedListener: EventListener?
18
18
  private var sourceChangeListener: EventListener?
19
+ private var appTerminationObserver: Any?
19
20
 
20
21
  // MARK: - destruction
21
22
  func destroy() {
@@ -31,6 +32,8 @@ class THEOplayerRCTNowPlayingManager {
31
32
  // clear nowPlayingInfo
32
33
  self.nowPlayingInfo = [:]
33
34
  self.clearNowPlayingOnInfoCenter()
35
+
36
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] Destroy, nowPlayingInfo cleared on infoCenter.") }
34
37
  }
35
38
 
36
39
  // MARK: - player setup / breakdown
@@ -41,6 +44,24 @@ class THEOplayerRCTNowPlayingManager {
41
44
  self.attachListeners()
42
45
  }
43
46
 
47
+ func printCurrentNowPlayingInfo() {
48
+ Task { @MainActor [weak self] in
49
+ if let info = MPNowPlayingInfoCenter.default().nowPlayingInfo {
50
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] MPNowPlayingInfoCenter.default().nowPlayingInfo = ")
51
+ info.forEach { (key: String, value: Any) in
52
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] -> \(key): \(value)")
53
+ }
54
+ if let player = self?.player {
55
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] playerInfo = ")
56
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] -> currentTime: \(player.currentTime)")
57
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] -> playbackRate: \(player.playbackRate)")
58
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] -> paused: \(player.paused)")
59
+ PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO CURRENT INFO] -> duration: \(player.duration ?? -1)")
60
+ }
61
+ }
62
+ }
63
+ }
64
+
44
65
  func updateNowPlaying() {
45
66
  // Reset any existing playing info
46
67
  self.nowPlayingInfo = [:]
@@ -50,7 +71,6 @@ class THEOplayerRCTNowPlayingManager {
50
71
  let sourceDescription = player.source,
51
72
  let metadata = sourceDescription.metadata {
52
73
  let artWorkUrlString = self.getArtWorkUrlStringFromSourceDescription(sourceDescription)
53
- self.updatePlaybackState()
54
74
  self.nowPlayingInfo = [String : Any]()
55
75
  self.updateTitle(metadata.title)
56
76
  self.updateArtist(metadata.metadataKeys?["artist"] as? String)
@@ -66,31 +86,33 @@ class THEOplayerRCTNowPlayingManager {
66
86
  self?.processNowPlayingToInfoCenter()
67
87
  }
68
88
  } else {
69
- self.clearNowPlayingOnInfoCenter()
89
+ self.clearNowPlayingOnInfoCenter()
70
90
  }
71
91
  }
72
92
 
73
93
  private func processNowPlayingToInfoCenter() {
74
94
  let nowPlayingInfo = self.nowPlayingInfo
75
- DispatchQueue.main.async {
76
- if !nowPlayingInfo.isEmpty {
95
+ if !nowPlayingInfo.isEmpty {
96
+ Task { @MainActor in
77
97
  MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
78
- } else {
79
- MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
98
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] nowPlayingInfo processed to infoCenter.") }
99
+
100
+ if DEBUG_NOWINFO {
101
+ self.printCurrentNowPlayingInfo()
102
+ }
80
103
  }
104
+ } else {
105
+ self.clearNowPlayingOnInfoCenter()
81
106
  }
82
107
  }
83
108
 
84
109
  private func clearNowPlayingOnInfoCenter() {
85
- DispatchQueue.main.async {
110
+ Task { @MainActor in
86
111
  MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
87
- }
88
- }
89
-
90
- private func processPlaybackStateToInfoCenter(paused: Bool) {
91
- if #available(iOS 13.0, tvOS 13.0, *) {
92
- DispatchQueue.main.async {
93
- MPNowPlayingInfoCenter.default().playbackState = paused ? MPNowPlayingPlaybackState.paused : MPNowPlayingPlaybackState.playing
112
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] clearing nowPlayingInfo (to nil) on infoCenter.") }
113
+
114
+ if DEBUG_NOWINFO {
115
+ self.printCurrentNowPlayingInfo()
94
116
  }
95
117
  }
96
118
  }
@@ -110,58 +132,48 @@ class THEOplayerRCTNowPlayingManager {
110
132
  private func updateTitle(_ metadataTitle: String?) {
111
133
  if let title = metadataTitle {
112
134
  self.nowPlayingInfo[MPMediaItemPropertyTitle] = title
135
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] title [\(title)] stored in nowPlayingInfo.") }
113
136
  }
114
137
  }
115
138
 
116
139
  private func updateArtist(_ metadataArtist: String?) {
117
140
  if let artist = metadataArtist {
118
141
  self.nowPlayingInfo[MPMediaItemPropertyArtist] = artist
142
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] artist [\(artist)] stored in nowPlayingInfo.") }
119
143
  }
120
144
  }
121
145
 
122
146
  private func updateAlbum(_ metadataAlbum: String?) {
123
147
  if let album = metadataAlbum {
124
148
  self.nowPlayingInfo[MPMediaItemPropertyAlbumTitle] = album
149
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] album [\(album)] stored in nowPlayingInfo.") }
125
150
  }
126
151
  }
127
152
 
128
153
  private func updateSubtitle(_ metadataSubtitle: String?) {
129
154
  if let subtitle = metadataSubtitle {
130
155
  self.nowPlayingInfo[MPMediaItemPropertyArtist] = subtitle
131
- }
132
- }
133
-
134
- private func updateDuration(_ playerDuration: Double?) {
135
- if let duration = playerDuration {
136
- self.nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = duration.isInfinite
137
- if (!duration.isInfinite) {
138
- self.nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = duration
139
- }
156
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] subtitle [\(subtitle)] stored in nowPlayingInfo.") }
140
157
  }
141
158
  }
142
159
 
143
160
  private func updateServiceIdentifier(_ serviceId: String?) {
144
- if let id = serviceId {
145
- self.nowPlayingInfo[MPNowPlayingInfoPropertyServiceIdentifier] = id
161
+ if let serviceId = serviceId {
162
+ self.nowPlayingInfo[MPNowPlayingInfoPropertyServiceIdentifier] = serviceId
163
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] serviceId [\(serviceId)] stored in nowPlayingInfo.") }
146
164
  }
147
165
  }
148
166
 
149
167
  private func updateContentIdentifier(_ contentId: String?) {
150
- if let id = contentId {
151
- self.nowPlayingInfo[MPNowPlayingInfoPropertyExternalContentIdentifier] = id
168
+ if let contentId = contentId {
169
+ self.nowPlayingInfo[MPNowPlayingInfoPropertyExternalContentIdentifier] = contentId
170
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] contentId [\(contentId)] stored in nowPlayingInfo.") }
152
171
  }
153
172
  }
154
173
 
155
174
  private func updateMediaType() {
156
175
  self.nowPlayingInfo[MPNowPlayingInfoPropertyMediaType] = NSNumber(value: 2)
157
- }
158
-
159
- private func updatePlaybackState() {
160
- if #available(iOS 13.0, tvOS 13.0, *) {
161
- if let player = self.player {
162
- self.processPlaybackStateToInfoCenter(paused: player.paused)
163
- }
164
- }
176
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] mediaType [hardcoded 2, for video] stored in nowPlayingInfo.") }
165
177
  }
166
178
 
167
179
  private func updateArtWork(_ urlString: String?, completion: (() -> Void)?) {
@@ -173,9 +185,9 @@ class THEOplayerRCTNowPlayingManager {
173
185
  self?.nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: displayIcon.size) { size in
174
186
  return displayIcon
175
187
  }
176
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] Artwork updated in nowPlayingInfo.") }
188
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] Artwork stored in nowPlayingInfo.") }
177
189
  } else {
178
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] Failed to update artwork in nowPlayingInfo.") }
190
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] Failed to store artwork in nowPlayingInfo.") }
179
191
  }
180
192
  completion?()
181
193
  }
@@ -187,10 +199,31 @@ class THEOplayerRCTNowPlayingManager {
187
199
 
188
200
  private func updatePlaybackRate(_ playerPlaybackRate: Double) {
189
201
  self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = NSNumber(value: playerPlaybackRate)
202
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] playbackrate [\(playerPlaybackRate)] stored in nowPlayingInfo.") }
190
203
  }
191
204
 
192
205
  private func updateCurrentTime(_ currentTime: Double) {
193
206
  self.nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: currentTime)
207
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] currentTime [\(currentTime)] stored in nowPlayingInfo.") }
208
+ }
209
+
210
+ private func updateDuration(_ duration: Double?) {
211
+ if let duration = duration {
212
+ let isLiveStream = duration.isInfinite
213
+ self.nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = isLiveStream
214
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] isLiveStream [\(isLiveStream)] stored in nowPlayingInfo.") }
215
+ if !isLiveStream {
216
+ self.nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = NSNumber(value: duration)
217
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] duration [\(duration)] stored in nowPlayingInfo.") }
218
+ }
219
+ }
220
+ }
221
+
222
+ @objc
223
+ private func appWillTerminate() {
224
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] App will terminate notification received.") }
225
+ MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
226
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO] nowPlayingInfo cleared for app termination.") }
194
227
  }
195
228
 
196
229
  private func attachListeners() {
@@ -198,40 +231,43 @@ class THEOplayerRCTNowPlayingManager {
198
231
  return
199
232
  }
200
233
 
234
+ // When app terminates, clear the nowPlayingInfo.
235
+ self.appTerminationObserver = NotificationCenter.default.addObserver(
236
+ self,
237
+ selector: #selector(appWillTerminate),
238
+ name: UIApplication.willTerminateNotification,
239
+ object: nil
240
+ )
241
+
201
242
  // DURATION_CHANGE
202
243
  self.durationChangeListener = player.addEventListener(type: PlayerEventTypes.DURATION_CHANGE) { [weak self, weak player] event in
244
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO-EVENT] DURATION_CHANGE") }
203
245
  if let welf = self,
204
246
  let wplayer = player,
205
247
  let duration = wplayer.duration {
206
- welf.nowPlayingInfo[MPNowPlayingInfoPropertyIsLiveStream] = duration.isInfinite
207
- if (!duration.isInfinite) {
208
- welf.nowPlayingInfo[MPMediaItemPropertyPlaybackDuration] = duration
209
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] DURATION_CHANGE: Updating duration on NowPlayingInfoCenter...") }
210
- welf.processNowPlayingToInfoCenter()
211
- }
248
+ welf.updateDuration(duration)
249
+ welf.processNowPlayingToInfoCenter()
212
250
  }
213
251
  }
214
252
 
215
253
  // PLAYING
216
254
  self.playingListener = player.addEventListener(type: PlayerEventTypes.PLAYING) { [weak self, weak player] event in
255
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO-EVENT] PLAYING") }
217
256
  if let welf = self,
218
257
  let wplayer = player {
219
258
  welf.updatePlaybackRate(wplayer.playbackRate)
220
- welf.updatePlaybackState()
221
259
  welf.updateCurrentTime(wplayer.currentTime)
222
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] PLAYING: Updating playbackState and time on NowPlayingInfoCenter...") }
223
260
  welf.processNowPlayingToInfoCenter()
224
261
  }
225
262
  }
226
263
 
227
264
  // PAUSE
228
265
  self.pauseListener = player.addEventListener(type: PlayerEventTypes.PAUSE) { [weak self, weak player] event in
266
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO-EVENT] PAUSE") }
229
267
  if let welf = self,
230
268
  let wplayer = player {
231
269
  welf.updatePlaybackRate(0)
232
- welf.updatePlaybackState()
233
270
  welf.updateCurrentTime(wplayer.currentTime)
234
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] PAUSED: Updating PlaybackState and time on NowPlayingInfoCenter...") }
235
271
  welf.processNowPlayingToInfoCenter()
236
272
  }
237
273
  }
@@ -239,28 +275,29 @@ class THEOplayerRCTNowPlayingManager {
239
275
 
240
276
  // RATE_CHANGE
241
277
  self.rateChangeListener = player.addEventListener(type: PlayerEventTypes.RATE_CHANGE) { [weak self, weak player] event in
278
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO-EVENT] RATE_CHANGE") }
242
279
  if let welf = self,
243
280
  let wplayer = player {
244
281
  welf.updatePlaybackRate(wplayer.playbackRate)
245
282
  welf.updateCurrentTime(wplayer.currentTime)
246
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] RATE_CHANGE: Updating playbackRate on NowPlayingInfoCenter...") }
247
283
  welf.processNowPlayingToInfoCenter()
248
284
  }
249
285
  }
250
286
 
251
287
  // SEEKED
252
288
  self.seekedListener = player.addEventListener(type: PlayerEventTypes.SEEKED) { [weak self, weak player] event in
289
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO-EVENT] SEEKED") }
253
290
  if let welf = self,
254
291
  let wplayer = player {
292
+ welf.updatePlaybackRate(wplayer.playbackRate)
255
293
  welf.updateCurrentTime(wplayer.currentTime)
256
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] SEEKED: Time updated on NowPlayingInfoCenter.") }
257
294
  welf.processNowPlayingToInfoCenter()
258
295
  }
259
296
  }
260
297
 
261
298
  // SOURCE_CHANGE
262
299
  self.sourceChangeListener = player.addEventListener(type: PlayerEventTypes.SOURCE_CHANGE) { [weak self] event in
263
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] SOURCE_CHANGE: Full update on NowPlayingInfoCenter.") }
300
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE-NOWPLAYINGINFO-EVENT] SOURCE_CHANGE \(event.source == nil ? "to nil" : "")") }
264
301
  self?.updateNowPlaying()
265
302
  }
266
303
  }
@@ -270,6 +307,15 @@ class THEOplayerRCTNowPlayingManager {
270
307
  return
271
308
  }
272
309
 
310
+ // When app terminates, clear the nowPlayingInfo.
311
+ if let appTerminationObserver = self.appTerminationObserver {
312
+ NotificationCenter.default.removeObserver(
313
+ appTerminationObserver,
314
+ name: UIApplication.willTerminateNotification,
315
+ object: nil)
316
+ self.appTerminationObserver = nil
317
+ }
318
+
273
319
  // DURATION_CHANGE
274
320
  if let durationChangeListener = self.durationChangeListener {
275
321
  player.removeEventListener(type: PlayerEventTypes.DURATION_CHANGE, listener: durationChangeListener)
@@ -84,7 +84,6 @@ class THEOplayerRCTRemoteCommandsManager: NSObject {
84
84
  // update the enabled state to have correct visual representation in the lockscreen
85
85
  commandCenter.pauseCommand.isEnabled = self.hasSource && !self.inAd
86
86
  commandCenter.playCommand.isEnabled = self.hasSource && !self.inAd
87
- commandCenter.pauseCommand.isEnabled = self.hasSource && !self.inAd
88
87
  commandCenter.togglePlayPauseCommand.isEnabled = self.hasSource && !self.inAd
89
88
  commandCenter.stopCommand.isEnabled = self.hasSource && !self.inAd
90
89
  commandCenter.changePlaybackPositionCommand.isEnabled = self.hasSource && !self.isLive && !self.inAd
@@ -52,7 +52,7 @@ class THEOplayerRCTCastEventHandler {
52
52
  if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received Chromecast STATE_CHANGE event from THEOplayer cast.chromecast") }
53
53
  if let forwardedCastEvent = self?.onNativeCastEvent {
54
54
  let newCastState = event.state._rawValue
55
- if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] New Chromecast state: \(newCastState)") }
55
+ if DEBUG_THEOPLAYER_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received new Chromecast state: \(newCastState)") }
56
56
  forwardedCastEvent([
57
57
  CAST_EVENT_PROP_TYPE: EVENT_TYPE_CHROMECAST_STATE_CHANGE,
58
58
  CAST_EVENT_PROP_STATE: newCastState
@@ -15,6 +15,7 @@ public class THEOplayerRCTPresentationModeManager {
15
15
 
16
16
  private weak var containerView: UIView? // view containing the playerView and it's siblings (e.g. UI)
17
17
  private weak var inlineParentView: UIView? // target view for inline representation
18
+ private var inlineParentViewIndex: Int?
18
19
 
19
20
  // MARK: Events
20
21
  var onNativePresentationModeChange: RCTDirectEventBlock?
@@ -58,7 +59,11 @@ public class THEOplayerRCTPresentationModeManager {
58
59
  return viewControllers
59
60
  }
60
61
 
61
- private func moveView(_ movingView: UIView, to targetView: UIView) {
62
+ /**
63
+ * Moves a view to a new parent.
64
+ * The view is inserted at the provided targetViewIndex or else at the front.
65
+ */
66
+ private func moveView(_ movingView: UIView, to targetView: UIView, targetViewIndex: Int? = nil) {
62
67
  // detach the moving viewControllers from their parent
63
68
  let movingViewControllers = self.movingVCs(for: movingView)
64
69
  movingViewControllers.forEach { movedVC in
@@ -67,8 +72,13 @@ public class THEOplayerRCTPresentationModeManager {
67
72
 
68
73
  // move the actual view
69
74
  movingView.removeFromSuperview()
70
- targetView.addSubview(movingView)
71
- targetView.bringSubviewToFront(movingView)
75
+ if let viewIndex = targetViewIndex {
76
+ let safeIndex = min(viewIndex, targetView.subviews.count)
77
+ targetView.insertSubview(movingView, at: safeIndex)
78
+ } else {
79
+ targetView.addSubview(movingView)
80
+ targetView.bringSubviewToFront(movingView)
81
+ }
72
82
 
73
83
  // attach the moving viewControllers to their new parent
74
84
  if let targetViewController = targetView.findViewController() {
@@ -85,9 +95,11 @@ public class THEOplayerRCTPresentationModeManager {
85
95
 
86
96
  // move the player
87
97
  if let containerView = self.containerView,
98
+ let inlineParentView = self.inlineParentView,
88
99
  let fullscreenParentView = self.view?.findParentViewOfType(["RCTRootContentView", "RCTRootComponentView"]) {
89
- self.moveView(containerView, to: fullscreenParentView)
90
-
100
+ self.inlineParentViewIndex = inlineParentView.subviews.firstIndex(of: containerView)
101
+ self.moveView(containerView, to: fullscreenParentView, targetViewIndex: nil)
102
+
91
103
  // start hiding home indicator
92
104
  setHomeIndicatorHidden(true)
93
105
  }
@@ -101,10 +113,16 @@ public class THEOplayerRCTPresentationModeManager {
101
113
  // move the player
102
114
  if let containerView = self.containerView,
103
115
  let inlineParentView = self.inlineParentView {
104
- self.moveView(containerView, to: inlineParentView)
116
+ self.moveView(containerView, to: inlineParentView, targetViewIndex: self.inlineParentViewIndex)
105
117
  }
106
118
  self.rnInlineMode = .inline
107
119
  }
120
+
121
+ /*private func logSubviews(of parent: UIView) {
122
+ for (index, subview) in parent.subviews.enumerated() {
123
+ print("Index \(index): \(type(of: subview)) - \(subview)")
124
+ }
125
+ }*/
108
126
 
109
127
  private func setHomeIndicatorHidden(_ hidden: Bool) {
110
128
  #if os(iOS)
@@ -0,0 +1,101 @@
1
+ //
2
+ // THEOplayerRCTTHEOAdsAPI.swift
3
+ // Theoplayer
4
+ //
5
+ import Foundation
6
+
7
+ #if canImport(THEOplayerTHEOadsIntegration)
8
+ import THEOplayerTHEOadsIntegration
9
+ #endif
10
+
11
+ let ERROR_MESSAGE_THEOADS_UNSUPPORTED_FEATURE = "This functionality is not supported by the provided iOS SDKs"
12
+ let ERROR_CODE_THEOADS_ACCESS_FAILURE = "theoads_access_failure"
13
+ let ERROR_MESSAGE_THEOADS_ACCESS_FAILURE = "Could not access THEOplayer THEOAds Module"
14
+
15
+ @objc(THEOplayerRCTTHEOAdsAPI)
16
+ class THEOplayerRCTTHEOAdsAPI: NSObject, RCTBridgeModule {
17
+ @objc var bridge: RCTBridge!
18
+
19
+ static func moduleName() -> String! {
20
+ return "THEORCTTHEOAdsModule"
21
+ }
22
+
23
+ static func requiresMainQueueSetup() -> Bool {
24
+ return false
25
+ }
26
+
27
+ #if canImport(THEOplayerTHEOadsIntegration)
28
+ @objc(currentInterstitials:resolver:rejecter:)
29
+ func currentInterstitials(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
30
+ DispatchQueue.main.async {
31
+ if let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView,
32
+ let player = theView.player,
33
+ let theoAds = player.ads.theoAds {
34
+ var currentInterstitials: [[String:Any]] = []
35
+ for interstitial in theoAds.currentInterstitials {
36
+ currentInterstitials.append(THEOplayerRCTTHEOadsEventAdapter.fromInterstitial(interstitial))
37
+ }
38
+ resolve(currentInterstitials)
39
+ } else {
40
+ if DEBUG_THEOADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not get currentInterstitials (THEOAds module unavailable).") }
41
+ reject(ERROR_CODE_THEOADS_ACCESS_FAILURE, ERROR_MESSAGE_THEOADS_ACCESS_FAILURE, nil)
42
+ }
43
+ }
44
+ }
45
+
46
+ @objc(scheduledInterstitials:resolver:rejecter:)
47
+ func scheduledInterstitials(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
48
+ DispatchQueue.main.async {
49
+ if let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView,
50
+ let player = theView.player,
51
+ let theoAds = player.ads.theoAds {
52
+ var scheduledInterstitials: [[String:Any]] = []
53
+ for interstitial in theoAds.scheduledInterstitials {
54
+ scheduledInterstitials.append(THEOplayerRCTTHEOadsEventAdapter.fromInterstitial(interstitial))
55
+ }
56
+ resolve(scheduledInterstitials)
57
+ } else {
58
+ if DEBUG_THEOADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not get scheduledInterstitials (THEOAds module unavailable).") }
59
+ reject(ERROR_CODE_THEOADS_ACCESS_FAILURE, ERROR_MESSAGE_THEOADS_ACCESS_FAILURE, nil)
60
+ }
61
+ }
62
+ }
63
+
64
+ @objc(replaceAdTagParameters:adTagParameters:)
65
+ func replaceAdTagParameters(_ node: NSNumber, adTagParameters: [String:Any]?) -> Void {
66
+ DispatchQueue.main.async {
67
+ if let theView = self.bridge.uiManager.view(forReactTag: node) as? THEOplayerRCTView,
68
+ let player = theView.player,
69
+ let theoAds = player.ads.theoAds {
70
+ if let newParams = adTagParameters as? [String: String] {
71
+ theoAds.replaceAdTagParams(params: newParams)
72
+ if DEBUG_THEOADS_API { PrintUtils.printLog(logText: "[NATIVE] THEOAds adTagParameters replaced.") }
73
+ } else {
74
+ if DEBUG_THEOADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not replace THEOAds adTagParameters.") }
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ #else
81
+
82
+ @objc(currentInterstitials:resolver:rejecter:)
83
+ func currentInterstitials(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
84
+ if DEBUG_THEOADS_API { print(ERROR_MESSAGE_THEOADS_UNSUPPORTED_FEATURE) }
85
+ reject(ERROR_CODE_THEOADS_ACCESS_FAILURE, ERROR_MESSAGE_THEOADS_ACCESS_FAILURE, nil)
86
+ }
87
+
88
+ @objc(scheduledInterstitials:resolver:rejecter:)
89
+ func scheduledInterstitials(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
90
+ if DEBUG_THEOADS_API { print(ERROR_MESSAGE_THEOADS_UNSUPPORTED_FEATURE) }
91
+ reject(ERROR_CODE_THEOADS_ACCESS_FAILURE, ERROR_MESSAGE_THEOADS_ACCESS_FAILURE, nil)
92
+ }
93
+
94
+ @objc(replaceAdTagParameters:token:)
95
+ func replaceAdTagParameters(_ node: NSNumber, adTagParameters: [String:Any]?) -> Void {
96
+ if DEBUG_THEOADS_API { print(ERROR_MESSAGE_THEOADS_UNSUPPORTED_FEATURE) }
97
+ }
98
+
99
+ #endif
100
+
101
+ }
@@ -0,0 +1,118 @@
1
+ // THEOplayerRCTTHEOadsEventAdapter.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+
6
+ #if canImport(THEOplayerTHEOadsIntegration)
7
+ @_spi(Core) import THEOplayerTHEOadsIntegration
8
+ #endif
9
+
10
+ // general
11
+ let PROP_INTERSTITIAL_ID: String = "id"
12
+ let PROP_INTERSTITIAL_TYPE: String = "type"
13
+ let PROP_INTERSTITIAL_START_TIME: String = "startTime"
14
+ let PROP_INTERSTITIAL_DURATION: String = "duration"
15
+
16
+ // adbreak specific
17
+ let PROP_ADBREAK_INTERSTITIAL_LAYOUT: String = "layout"
18
+ let PROP_ADBREAK_INTERSTITIAL_BACKDROPURI: String = "backdropUri"
19
+ let PROP_ADBREAK_INTERSTITIAL_ADS: String = "ads"
20
+
21
+ // overlay specific
22
+ let PROP_OVERLAY_INTERSTITIAL_IMAGE_URL: String = "imageUrl"
23
+ let PROP_OVERLAY_INTERSTITIAL_CLICKTHROUGH: String = "clickThrough"
24
+ let PROP_OVERLAY_INTERSTITIAL_POSITION: String = "position"
25
+ let PROP_OVERLAY_INTERSTITIAL_SIZE: String = "size"
26
+
27
+ class THEOplayerRCTTHEOadsEventAdapter {
28
+
29
+ #if canImport(THEOplayerTHEOadsIntegration)
30
+ class func fromInterstitial(_ interstitial: THEOplayerTHEOadsIntegration.Interstitial?) -> [String:Any] {
31
+ guard let interstitial = interstitial else {
32
+ return [:]
33
+ }
34
+
35
+ var interstitialData: [String:Any] = [:]
36
+ interstitialData[PROP_INTERSTITIAL_ID] = interstitial.id
37
+ interstitialData[PROP_INTERSTITIAL_TYPE] = THEOplayerRCTTHEOadsEventAdapter.fromInterstitialType(interstitial.type)
38
+ interstitialData[PROP_INTERSTITIAL_START_TIME] = interstitial.startTime
39
+ if let duration = interstitial.duration {
40
+ interstitialData[PROP_INTERSTITIAL_DURATION] = duration
41
+ }
42
+
43
+ // ADBREAK-INTERSTITIAL SPECIFIC:
44
+ if let adBreakInterstitial = interstitial as? THEOplayerTHEOadsIntegration.AdBreakInterstitial {
45
+ interstitialData[PROP_ADBREAK_INTERSTITIAL_LAYOUT] = THEOplayerRCTTHEOadsEventAdapter.fromInterstitialLayout(adBreakInterstitial.layout)
46
+ if let backdropUri = adBreakInterstitial.backdropUri {
47
+ interstitialData[PROP_ADBREAK_INTERSTITIAL_BACKDROPURI] = backdropUri
48
+ }
49
+ let interstitialAds = adBreakInterstitial.ads
50
+ var ads: [[String:Any]] = []
51
+ for ad in interstitialAds {
52
+ ads.append(THEOplayerRCTAdAdapter.fromAd(ad: ad))
53
+ }
54
+ interstitialData[PROP_ADBREAK_INTERSTITIAL_ADS] = ads
55
+ }
56
+
57
+ // OVERLAY-INTERSTITIAL SPECIFIC
58
+ if let overlayInterstitial = interstitial as? THEOplayerTHEOadsIntegration.OverlayInterstitial {
59
+ if let imageUrl = overlayInterstitial.imageUrl {
60
+ interstitialData[PROP_OVERLAY_INTERSTITIAL_IMAGE_URL] = imageUrl
61
+ }
62
+ if let clickThrough = overlayInterstitial.clickThrough {
63
+ interstitialData[PROP_OVERLAY_INTERSTITIAL_CLICKTHROUGH] = clickThrough
64
+ }
65
+ interstitialData[PROP_OVERLAY_INTERSTITIAL_POSITION] = THEOplayerRCTTHEOadsEventAdapter.fromOverlayPosition(overlayInterstitial.position)
66
+ interstitialData[PROP_OVERLAY_INTERSTITIAL_SIZE] = THEOplayerRCTTHEOadsEventAdapter.fromOverlaySize(overlayInterstitial.size)
67
+ }
68
+
69
+ return interstitialData
70
+ }
71
+
72
+ class func fromInterstitialType(_ interstitialType: THEOplayerTHEOadsIntegration.InterstitialType) -> String {
73
+ switch interstitialType {
74
+ case InterstitialType.adbreak:
75
+ return "adbreak"
76
+ default:
77
+ return "overlay"
78
+ }
79
+ }
80
+
81
+ class func fromInterstitialLayout(_ interstitialLayout: THEOplayerTHEOadsIntegration.THEOadsLayout) -> String {
82
+ switch interstitialLayout {
83
+ case THEOadsLayout.single:
84
+ return "single"
85
+ case THEOadsLayout.double:
86
+ return "double"
87
+ default:
88
+ return "l-shape"
89
+ }
90
+ }
91
+
92
+ class func fromOverlayPosition(_ overlayPosition: THEOplayerTHEOadsIntegration.OverlayPosition) -> [String:Any] {
93
+ var overlayPositionData: [String:Any] = [:]
94
+ if let left = overlayPosition.left {
95
+ overlayPositionData["left"] = left
96
+ }
97
+ if let right = overlayPosition.right {
98
+ overlayPositionData["right"] = right
99
+ }
100
+ if let top = overlayPosition.top {
101
+ overlayPositionData["top"] = top
102
+ }
103
+ if let bottom = overlayPosition.bottom {
104
+ overlayPositionData["bottom"] = bottom
105
+ }
106
+ return overlayPositionData
107
+ }
108
+
109
+ class func fromOverlaySize(_ overlaySize: THEOplayerTHEOadsIntegration.OverlaySize) -> [String:Any] {
110
+ var overlaySizeData: [String:Any] = [:]
111
+ overlaySizeData["width"] = overlaySize.width
112
+ overlaySizeData["height"] = overlaySize.height
113
+ return overlaySizeData
114
+ }
115
+
116
+ #endif
117
+
118
+ }