react-native-theoplayer 2.16.1 → 3.0.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 (316) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +1 -0
  3. package/android/build.gradle +19 -22
  4. package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +87 -101
  5. package/android/src/main/java/com/theoplayer/ReactTHEOplayerContext.kt +30 -30
  6. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +3 -1
  7. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +1 -1
  8. package/android/src/main/java/com/theoplayer/cache/CacheAdapter.kt +127 -0
  9. package/android/src/main/java/com/theoplayer/cache/CacheModule.kt +238 -0
  10. package/android/src/main/java/com/theoplayer/player/PlayerModule.kt +27 -12
  11. package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +16 -37
  12. package/android/src/main/java/com/theoplayer/util/BridgeUtils.kt +60 -0
  13. package/android/src/main/java/com/theoplayer/util/PayloadBuilder.kt +10 -10
  14. package/ios/THEOplayerRCTBridge.m +22 -0
  15. package/ios/THEOplayerRCTDebug.swift +7 -1
  16. package/ios/THEOplayerRCTMainEventHandler.swift +25 -27
  17. package/ios/THEOplayerRCTSourceDescriptionAggregator.swift +41 -0
  18. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +3 -2
  19. package/ios/THEOplayerRCTTypeUtils.swift +37 -0
  20. package/ios/THEOplayerRCTView.swift +1 -2
  21. package/ios/ads/THEOplayerRCTAdsAPI+DAI.swift +3 -13
  22. package/ios/ads/THEOplayerRCTAdsAPI.swift +14 -48
  23. package/ios/ads/THEOplayerRCTView+AdsConfig.swift +0 -13
  24. package/ios/backgroundAudio/THEOplayerRCTNowPlayingManager.swift +24 -36
  25. package/ios/backgroundAudio/THEOplayerRCTRemoteCommandsManager.swift +2 -10
  26. package/ios/cache/THEOplayerRCTCacheAPI.swift +203 -0
  27. package/ios/cache/THEOplayerRCTCacheAggregator.swift +87 -0
  28. package/ios/cache/THEOplayerRCTCachingParametersBuilder.swift +27 -0
  29. package/ios/pip/THEOplayerRCTPipControlsManager.swift +2 -4
  30. package/lib/commonjs/api/abr/ABRConfiguration.js +21 -7
  31. package/lib/commonjs/api/abr/ABRConfiguration.js.map +1 -1
  32. package/lib/commonjs/api/ads/GoogleImaConfiguration.js.map +1 -1
  33. package/lib/commonjs/api/barrel.js +30 -19
  34. package/lib/commonjs/api/barrel.js.map +1 -1
  35. package/lib/commonjs/api/cache/CachingPreferredTrackSelection.js +2 -0
  36. package/lib/commonjs/api/cache/CachingPreferredTrackSelection.js.map +1 -0
  37. package/lib/commonjs/api/cache/CachingTask.js +30 -0
  38. package/lib/commonjs/api/cache/CachingTask.js.map +1 -0
  39. package/lib/commonjs/api/cache/CachingTaskLicense.js +6 -0
  40. package/lib/commonjs/api/cache/CachingTaskLicense.js.map +1 -0
  41. package/lib/commonjs/api/cache/CachingTaskList.js +6 -0
  42. package/lib/commonjs/api/cache/CachingTaskList.js.map +1 -0
  43. package/lib/commonjs/api/cache/CachingTaskParameters.js +6 -0
  44. package/lib/commonjs/api/cache/CachingTaskParameters.js.map +1 -0
  45. package/lib/commonjs/api/cache/MediaCacheAPI.js +24 -0
  46. package/lib/commonjs/api/cache/MediaCacheAPI.js.map +1 -0
  47. package/lib/commonjs/api/cache/barrel.js +83 -0
  48. package/lib/commonjs/api/cache/barrel.js.map +1 -0
  49. package/lib/commonjs/api/cache/events/CacheEvent.js +28 -0
  50. package/lib/commonjs/api/cache/events/CacheEvent.js.map +1 -0
  51. package/lib/commonjs/api/cache/events/CachingTaskEvent.js +17 -0
  52. package/lib/commonjs/api/cache/events/CachingTaskEvent.js.map +1 -0
  53. package/lib/commonjs/api/cache/events/barrel.js +28 -0
  54. package/lib/commonjs/api/cache/events/barrel.js.map +1 -0
  55. package/lib/commonjs/api/cache/hooks/barrel.js +39 -0
  56. package/lib/commonjs/api/cache/hooks/barrel.js.map +1 -0
  57. package/lib/commonjs/api/cache/hooks/useCachingTaskList.js +31 -0
  58. package/lib/commonjs/api/cache/hooks/useCachingTaskList.js.map +1 -0
  59. package/lib/commonjs/api/cache/hooks/useCachingTaskProgress.js +28 -0
  60. package/lib/commonjs/api/cache/hooks/useCachingTaskProgress.js.map +1 -0
  61. package/lib/commonjs/api/cache/hooks/useCachingTaskStatus.js +28 -0
  62. package/lib/commonjs/api/cache/hooks/useCachingTaskStatus.js.map +1 -0
  63. package/lib/commonjs/api/cast/CastState.js +3 -4
  64. package/lib/commonjs/api/cast/CastState.js.map +1 -1
  65. package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
  66. package/lib/commonjs/api/event/AdEvent.js +3 -4
  67. package/lib/commonjs/api/event/AdEvent.js.map +1 -1
  68. package/lib/commonjs/api/event/CastEvent.js +3 -4
  69. package/lib/commonjs/api/event/CastEvent.js.map +1 -1
  70. package/lib/commonjs/api/event/PlayerEvent.js +3 -4
  71. package/lib/commonjs/api/event/PlayerEvent.js.map +1 -1
  72. package/lib/commonjs/api/event/TrackEvent.js +12 -16
  73. package/lib/commonjs/api/event/TrackEvent.js.map +1 -1
  74. package/lib/commonjs/api/player/PlayerEventMap.js +7 -8
  75. package/lib/commonjs/api/player/PlayerEventMap.js.map +1 -1
  76. package/lib/commonjs/api/player/THEOplayer.js +6 -4
  77. package/lib/commonjs/api/player/THEOplayer.js.map +1 -1
  78. package/lib/commonjs/api/presentation/PresentationMode.js +3 -4
  79. package/lib/commonjs/api/presentation/PresentationMode.js.map +1 -1
  80. package/lib/commonjs/api/source/ads/Ads.js +3 -4
  81. package/lib/commonjs/api/source/ads/Ads.js.map +1 -1
  82. package/lib/commonjs/api/track/TextTrack.js +9 -12
  83. package/lib/commonjs/api/track/TextTrack.js.map +1 -1
  84. package/lib/commonjs/api/track/TextTrackStyle.js +3 -4
  85. package/lib/commonjs/api/track/TextTrackStyle.js.map +1 -1
  86. package/lib/commonjs/index.js +9 -1
  87. package/lib/commonjs/index.js.map +1 -1
  88. package/lib/commonjs/internal/THEOplayerView.js +1 -1
  89. package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
  90. package/lib/commonjs/internal/THEOplayerView.style.js +1 -2
  91. package/lib/commonjs/internal/THEOplayerView.style.js.map +1 -1
  92. package/lib/commonjs/internal/THEOplayerView.web.js +5 -5
  93. package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
  94. package/lib/commonjs/internal/adapter/THEOplayerAdapter.js.map +1 -1
  95. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js +12 -13
  96. package/lib/commonjs/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  97. package/lib/commonjs/internal/adapter/WebEventForwarder.js +10 -10
  98. package/lib/commonjs/internal/adapter/WebEventForwarder.js.map +1 -1
  99. package/lib/commonjs/internal/adapter/abr/AbrAdapter.js.map +1 -1
  100. package/lib/commonjs/internal/adapter/ads/THEOplayerWebAdsAdapter.js +2 -2
  101. package/lib/commonjs/internal/adapter/ads/THEOplayerWebAdsAdapter.js.map +1 -1
  102. package/lib/commonjs/internal/adapter/cast/THEOplayerNativeCastAdapter.js +1 -1
  103. package/lib/commonjs/internal/adapter/cast/THEOplayerNativeCastAdapter.js.map +1 -1
  104. package/lib/commonjs/internal/adapter/cast/THEOplayerWebCastAdapter.js.map +1 -1
  105. package/lib/commonjs/internal/adapter/event/BaseEvent.js.map +1 -1
  106. package/lib/commonjs/internal/adapter/event/DefaultEventDispatcher.js +1 -1
  107. package/lib/commonjs/internal/adapter/event/DefaultEventDispatcher.js.map +1 -1
  108. package/lib/commonjs/internal/adapter/event/native/NativeTrackEvent.js +12 -16
  109. package/lib/commonjs/internal/adapter/event/native/NativeTrackEvent.js.map +1 -1
  110. package/lib/commonjs/internal/adapter/track/TextTrackStyleAdapter.js.map +1 -1
  111. package/lib/commonjs/internal/adapter/web/FullscreenAPI.js +1 -2
  112. package/lib/commonjs/internal/adapter/web/FullscreenAPI.js.map +1 -1
  113. package/lib/commonjs/internal/adapter/web/WebMediaSession.js +9 -11
  114. package/lib/commonjs/internal/adapter/web/WebMediaSession.js.map +1 -1
  115. package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js +4 -4
  116. package/lib/commonjs/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
  117. package/lib/commonjs/internal/cache/MediaCache.js +117 -0
  118. package/lib/commonjs/internal/cache/MediaCache.js.map +1 -0
  119. package/lib/commonjs/internal/cache/MediaCache.web.js +54 -0
  120. package/lib/commonjs/internal/cache/MediaCache.web.js.map +1 -0
  121. package/lib/commonjs/internal/cache/NativeCachingTaskAdapter.js +59 -0
  122. package/lib/commonjs/internal/cache/NativeCachingTaskAdapter.js.map +1 -0
  123. package/lib/commonjs/internal/cache/NativeCachingTaskParametersAdapter.js +27 -0
  124. package/lib/commonjs/internal/cache/NativeCachingTaskParametersAdapter.js.map +1 -0
  125. package/lib/commonjs/internal/cache/WebCachingTaskAdapter.js +71 -0
  126. package/lib/commonjs/internal/cache/WebCachingTaskAdapter.js.map +1 -0
  127. package/lib/commonjs/internal/drm/ContentProtectionRegistry.js +1 -2
  128. package/lib/commonjs/internal/drm/ContentProtectionRegistry.js.map +1 -1
  129. package/lib/commonjs/internal/drm/ContentProtectionRegistry.web.js +1 -2
  130. package/lib/commonjs/internal/drm/ContentProtectionRegistry.web.js.map +1 -1
  131. package/lib/commonjs/internal/drm/NativeCertificateResponse.js.map +1 -1
  132. package/lib/commonjs/internal/drm/NativeLicenseResponse.js.map +1 -1
  133. package/lib/commonjs/internal/utils/TypeUtils.js +2 -4
  134. package/lib/commonjs/internal/utils/TypeUtils.js.map +1 -1
  135. package/lib/module/api/abr/ABRConfiguration.js +24 -6
  136. package/lib/module/api/abr/ABRConfiguration.js.map +1 -1
  137. package/lib/module/api/ads/GoogleImaConfiguration.js.map +1 -1
  138. package/lib/module/api/barrel.js +1 -0
  139. package/lib/module/api/barrel.js.map +1 -1
  140. package/lib/module/api/cache/CachingPreferredTrackSelection.js +2 -0
  141. package/lib/module/api/cache/CachingPreferredTrackSelection.js.map +1 -0
  142. package/lib/module/api/cache/CachingTask.js +25 -0
  143. package/lib/module/api/cache/CachingTask.js.map +1 -0
  144. package/lib/module/api/cache/CachingTaskLicense.js +2 -0
  145. package/lib/module/api/cache/CachingTaskLicense.js.map +1 -0
  146. package/lib/module/api/cache/CachingTaskList.js +2 -0
  147. package/lib/module/api/cache/CachingTaskList.js.map +1 -0
  148. package/lib/module/api/cache/CachingTaskParameters.js +2 -0
  149. package/lib/module/api/cache/CachingTaskParameters.js.map +1 -0
  150. package/lib/module/api/cache/MediaCacheAPI.js +19 -0
  151. package/lib/module/api/cache/MediaCacheAPI.js.map +1 -0
  152. package/lib/module/api/cache/barrel.js +8 -0
  153. package/lib/module/api/cache/barrel.js.map +1 -0
  154. package/lib/module/api/cache/events/CacheEvent.js +25 -0
  155. package/lib/module/api/cache/events/CacheEvent.js.map +1 -0
  156. package/lib/module/api/cache/events/CachingTaskEvent.js +12 -0
  157. package/lib/module/api/cache/events/CachingTaskEvent.js.map +1 -0
  158. package/lib/module/api/cache/events/barrel.js +3 -0
  159. package/lib/module/api/cache/events/barrel.js.map +1 -0
  160. package/lib/module/api/cache/hooks/barrel.js +4 -0
  161. package/lib/module/api/cache/hooks/barrel.js.map +1 -0
  162. package/lib/module/api/cache/hooks/useCachingTaskList.js +24 -0
  163. package/lib/module/api/cache/hooks/useCachingTaskList.js.map +1 -0
  164. package/lib/module/api/cache/hooks/useCachingTaskProgress.js +21 -0
  165. package/lib/module/api/cache/hooks/useCachingTaskProgress.js.map +1 -0
  166. package/lib/module/api/cache/hooks/useCachingTaskStatus.js +21 -0
  167. package/lib/module/api/cache/hooks/useCachingTaskStatus.js.map +1 -0
  168. package/lib/module/api/cast/CastState.js +3 -3
  169. package/lib/module/api/cast/CastState.js.map +1 -1
  170. package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
  171. package/lib/module/api/event/AdEvent.js +3 -3
  172. package/lib/module/api/event/AdEvent.js.map +1 -1
  173. package/lib/module/api/event/CastEvent.js +3 -3
  174. package/lib/module/api/event/CastEvent.js.map +1 -1
  175. package/lib/module/api/event/PlayerEvent.js +3 -3
  176. package/lib/module/api/event/PlayerEvent.js.map +1 -1
  177. package/lib/module/api/event/TrackEvent.js +12 -12
  178. package/lib/module/api/event/TrackEvent.js.map +1 -1
  179. package/lib/module/api/player/PlayerEventMap.js +8 -8
  180. package/lib/module/api/player/PlayerEventMap.js.map +1 -1
  181. package/lib/module/api/player/THEOplayer.js +7 -3
  182. package/lib/module/api/player/THEOplayer.js.map +1 -1
  183. package/lib/module/api/presentation/PresentationMode.js +3 -3
  184. package/lib/module/api/presentation/PresentationMode.js.map +1 -1
  185. package/lib/module/api/source/ads/Ads.js +3 -3
  186. package/lib/module/api/source/ads/Ads.js.map +1 -1
  187. package/lib/module/api/track/TextTrack.js +9 -9
  188. package/lib/module/api/track/TextTrack.js.map +1 -1
  189. package/lib/module/api/track/TextTrackStyle.js +3 -3
  190. package/lib/module/api/track/TextTrackStyle.js.map +1 -1
  191. package/lib/module/index.js +1 -0
  192. package/lib/module/index.js.map +1 -1
  193. package/lib/module/internal/THEOplayerView.js +1 -1
  194. package/lib/module/internal/THEOplayerView.js.map +1 -1
  195. package/lib/module/internal/THEOplayerView.web.js +5 -5
  196. package/lib/module/internal/THEOplayerView.web.js.map +1 -1
  197. package/lib/module/internal/adapter/THEOplayerAdapter.js.map +1 -1
  198. package/lib/module/internal/adapter/THEOplayerWebAdapter.js +12 -11
  199. package/lib/module/internal/adapter/THEOplayerWebAdapter.js.map +1 -1
  200. package/lib/module/internal/adapter/WebEventForwarder.js +10 -10
  201. package/lib/module/internal/adapter/WebEventForwarder.js.map +1 -1
  202. package/lib/module/internal/adapter/abr/AbrAdapter.js.map +1 -1
  203. package/lib/module/internal/adapter/ads/THEOplayerWebAdsAdapter.js +2 -2
  204. package/lib/module/internal/adapter/ads/THEOplayerWebAdsAdapter.js.map +1 -1
  205. package/lib/module/internal/adapter/cast/THEOplayerNativeCastAdapter.js +1 -1
  206. package/lib/module/internal/adapter/cast/THEOplayerNativeCastAdapter.js.map +1 -1
  207. package/lib/module/internal/adapter/cast/THEOplayerWebCastAdapter.js.map +1 -1
  208. package/lib/module/internal/adapter/event/BaseEvent.js.map +1 -1
  209. package/lib/module/internal/adapter/event/DefaultEventDispatcher.js +1 -1
  210. package/lib/module/internal/adapter/event/DefaultEventDispatcher.js.map +1 -1
  211. package/lib/module/internal/adapter/event/native/NativeTrackEvent.js +12 -12
  212. package/lib/module/internal/adapter/event/native/NativeTrackEvent.js.map +1 -1
  213. package/lib/module/internal/adapter/track/TextTrackStyleAdapter.js.map +1 -1
  214. package/lib/module/internal/adapter/web/FullscreenAPI.js.map +1 -1
  215. package/lib/module/internal/adapter/web/WebMediaSession.js +8 -9
  216. package/lib/module/internal/adapter/web/WebMediaSession.js.map +1 -1
  217. package/lib/module/internal/adapter/web/WebPresentationModeManager.js +4 -4
  218. package/lib/module/internal/adapter/web/WebPresentationModeManager.js.map +1 -1
  219. package/lib/module/internal/cache/MediaCache.js +110 -0
  220. package/lib/module/internal/cache/MediaCache.js.map +1 -0
  221. package/lib/module/internal/cache/MediaCache.web.js +45 -0
  222. package/lib/module/internal/cache/MediaCache.web.js.map +1 -0
  223. package/lib/module/internal/cache/NativeCachingTaskAdapter.js +52 -0
  224. package/lib/module/internal/cache/NativeCachingTaskAdapter.js.map +1 -0
  225. package/lib/module/internal/cache/NativeCachingTaskParametersAdapter.js +20 -0
  226. package/lib/module/internal/cache/NativeCachingTaskParametersAdapter.js.map +1 -0
  227. package/lib/module/internal/cache/WebCachingTaskAdapter.js +64 -0
  228. package/lib/module/internal/cache/WebCachingTaskAdapter.js.map +1 -0
  229. package/lib/module/internal/drm/ContentProtectionRegistry.js.map +1 -1
  230. package/lib/module/internal/drm/ContentProtectionRegistry.web.js.map +1 -1
  231. package/lib/module/internal/drm/NativeCertificateResponse.js.map +1 -1
  232. package/lib/module/internal/drm/NativeLicenseResponse.js.map +1 -1
  233. package/lib/typescript/api/abr/ABRConfiguration.d.ts +1 -1
  234. package/lib/typescript/api/ads/Ad.d.ts +2 -2
  235. package/lib/typescript/api/ads/AdsConfiguration.d.ts +2 -2
  236. package/lib/typescript/api/ads/GoogleImaConfiguration.d.ts +1 -0
  237. package/lib/typescript/api/barrel.d.ts +1 -0
  238. package/lib/typescript/api/cache/CachingPreferredTrackSelection.d.ts +23 -0
  239. package/lib/typescript/api/cache/CachingTask.d.ts +93 -0
  240. package/lib/typescript/api/cache/CachingTaskLicense.d.ts +14 -0
  241. package/lib/typescript/api/cache/CachingTaskList.d.ts +7 -0
  242. package/lib/typescript/api/cache/CachingTaskParameters.d.ts +57 -0
  243. package/lib/typescript/api/cache/MediaCacheAPI.d.ts +39 -0
  244. package/lib/typescript/api/cache/barrel.d.ts +7 -0
  245. package/lib/typescript/api/cache/events/CacheEvent.d.ts +55 -0
  246. package/lib/typescript/api/cache/events/CachingTaskEvent.d.ts +22 -0
  247. package/lib/typescript/api/cache/events/barrel.d.ts +2 -0
  248. package/lib/typescript/api/cache/hooks/barrel.d.ts +3 -0
  249. package/lib/typescript/api/cache/hooks/useCachingTaskList.d.ts +1 -0
  250. package/lib/typescript/api/cache/hooks/useCachingTaskProgress.d.ts +2 -0
  251. package/lib/typescript/api/cache/hooks/useCachingTaskStatus.d.ts +2 -0
  252. package/lib/typescript/api/cast/CastConfiguration.d.ts +1 -1
  253. package/lib/typescript/api/config/PlayerConfiguration.d.ts +4 -1
  254. package/lib/typescript/api/drm/ContentProtectionIntegration.d.ts +2 -2
  255. package/lib/typescript/api/drm/ContentProtectionRequest.d.ts +1 -1
  256. package/lib/typescript/api/error/ChromecastError.d.ts +1 -1
  257. package/lib/typescript/api/event/CastEvent.d.ts +1 -1
  258. package/lib/typescript/api/event/EventDispatcher.d.ts +2 -2
  259. package/lib/typescript/api/event/EventListener.d.ts +1 -1
  260. package/lib/typescript/api/player/THEOplayer.d.ts +2 -2
  261. package/lib/typescript/api/source/SourceDescription.d.ts +3 -3
  262. package/lib/typescript/api/source/ads/Ads.d.ts +1 -1
  263. package/lib/typescript/api/source/ads/FreeWheelAdDescription.d.ts +1 -1
  264. package/lib/typescript/api/source/ads/ssai/GoogleDAIConfiguration.d.ts +2 -2
  265. package/lib/typescript/api/source/ads/ssai/ImagineServerSideAdInsertionConfiguration.d.ts +1 -1
  266. package/lib/typescript/api/source/ads/ssai/ServerSideAdInsertionConfiguration.d.ts +1 -1
  267. package/lib/typescript/api/source/ads/ssai/YospaceServerSideAdInsertionConfiguration.d.ts +2 -2
  268. package/lib/typescript/api/source/dash/DashPlaybackConfiguration.d.ts +1 -1
  269. package/lib/typescript/api/source/drm/DRMConfiguration.d.ts +3 -3
  270. package/lib/typescript/api/source/hls/HlsPlaybackConfiguration.d.ts +1 -1
  271. package/lib/typescript/api/track/MediaTrack.d.ts +1 -1
  272. package/lib/typescript/index.d.ts +1 -0
  273. package/lib/typescript/internal/THEOplayerView.web.d.ts +1 -1
  274. package/lib/typescript/internal/adapter/THEOplayerWebAdapter.d.ts +2 -2
  275. package/lib/typescript/internal/adapter/WebEventForwarder.d.ts +2 -2
  276. package/lib/typescript/internal/adapter/ads/THEOplayerWebAdsAdapter.d.ts +2 -2
  277. package/lib/typescript/internal/adapter/cast/THEOplayerWebCastAdapter.d.ts +2 -2
  278. package/lib/typescript/internal/adapter/event/native/NativeCastEvent.d.ts +1 -1
  279. package/lib/typescript/internal/adapter/web/WebPresentationModeManager.d.ts +2 -2
  280. package/lib/typescript/internal/cache/MediaCache.d.ts +25 -0
  281. package/lib/typescript/internal/cache/MediaCache.web.d.ts +16 -0
  282. package/lib/typescript/internal/cache/NativeCachingTaskAdapter.d.ts +33 -0
  283. package/lib/typescript/internal/cache/NativeCachingTaskParametersAdapter.d.ts +11 -0
  284. package/lib/typescript/internal/cache/WebCachingTaskAdapter.d.ts +25 -0
  285. package/package.json +16 -15
  286. package/react-native-theoplayer.podspec +5 -5
  287. package/src/api/ads/GoogleImaConfiguration.ts +1 -0
  288. package/src/api/barrel.ts +1 -0
  289. package/src/api/cache/CachingPreferredTrackSelection.ts +24 -0
  290. package/src/api/cache/CachingTask.ts +107 -0
  291. package/src/api/cache/CachingTaskLicense.ts +15 -0
  292. package/src/api/cache/CachingTaskList.ts +8 -0
  293. package/src/api/cache/CachingTaskParameters.ts +62 -0
  294. package/src/api/cache/MediaCacheAPI.ts +43 -0
  295. package/src/api/cache/barrel.ts +7 -0
  296. package/src/api/cache/events/CacheEvent.ts +62 -0
  297. package/src/api/cache/events/CachingTaskEvent.ts +27 -0
  298. package/src/api/cache/events/barrel.ts +2 -0
  299. package/src/api/cache/hooks/barrel.ts +3 -0
  300. package/src/api/cache/hooks/useCachingTaskList.ts +23 -0
  301. package/src/api/cache/hooks/useCachingTaskProgress.ts +20 -0
  302. package/src/api/cache/hooks/useCachingTaskStatus.ts +20 -0
  303. package/src/api/config/PlayerConfiguration.ts +3 -0
  304. package/src/index.tsx +1 -0
  305. package/src/internal/THEOplayerView.web.tsx +5 -5
  306. package/src/internal/adapter/THEOplayerWebAdapter.ts +6 -6
  307. package/src/internal/adapter/WebEventForwarder.ts +3 -3
  308. package/src/internal/adapter/ads/THEOplayerWebAdsAdapter.ts +3 -3
  309. package/src/internal/adapter/cast/THEOplayerWebCastAdapter.ts +3 -3
  310. package/src/internal/adapter/web/WebPresentationModeManager.ts +3 -3
  311. package/src/internal/cache/MediaCache.ts +151 -0
  312. package/src/internal/cache/MediaCache.web.ts +54 -0
  313. package/src/internal/cache/NativeCachingTaskAdapter.ts +81 -0
  314. package/src/internal/cache/NativeCachingTaskParametersAdapter.ts +32 -0
  315. package/src/internal/cache/WebCachingTaskAdapter.ts +95 -0
  316. package/android/src/main/java/com/theoplayer/track/QualityListFilter.kt +0 -28
@@ -12,6 +12,7 @@ let SD_PROP_SOURCES: String = "sources"
12
12
  let SD_PROP_POSTER: String = "poster"
13
13
  let SD_PROP_TEXTTRACKS: String = "textTracks"
14
14
  let SD_PROP_METADATA: String = "metadata"
15
+ let SD_PROP_METADATAKEYS: String = "metadataKeys"
15
16
  let SD_PROP_SRC: String = "src"
16
17
  let SD_PROP_TYPE: String = "type"
17
18
  let SD_PROP_SSAI: String = "ssai"
@@ -289,7 +290,7 @@ class THEOplayerRCTSourceDescriptionBuilder {
289
290
  Updates the contentProtectionData to a valid iOS SDK contentProtectionData, flattening out cross SDK differences
290
291
  - returns: a THEOplayer valid contentProtection data map
291
292
  */
292
- private static func sanitiseContentProtectionData(_ contentProtectionData: [String:Any]) -> [String:Any] {
293
+ static func sanitiseContentProtectionData(_ contentProtectionData: [String:Any]) -> [String:Any] {
293
294
  var sanitisedContentProtectionData: [String:Any] = contentProtectionData
294
295
  // fairplay update
295
296
  if let fairplayData = contentProtectionData[SD_PROP_FAIRPLAY] as? [String:Any] {
@@ -348,7 +349,7 @@ class THEOplayerRCTSourceDescriptionBuilder {
348
349
  Creates a THEOplayer DRMConfiguration. This requires a contentProtection property in the RN source description.
349
350
  - returns: a THEOplayer DRMConfiguration
350
351
  */
351
- private static func buildContentProtection(_ contentProtectionData: [String:Any]) -> MultiplatformDRMConfiguration? {
352
+ static func buildContentProtection(_ contentProtectionData: [String:Any]) -> MultiplatformDRMConfiguration? {
352
353
  do {
353
354
  let data = try JSONSerialization.data(withJSONObject: contentProtectionData)
354
355
  if let integration = contentProtectionData[SD_PROP_INTEGRATION] as? String {
@@ -97,5 +97,42 @@ class THEOplayerRCTTypeUtils {
97
97
  default:
98
98
  return TextTrackStyleEdgeStyle.none
99
99
  }
100
+ }
101
+
102
+ class func cacheStatusToString(_ status: CacheStatus) -> String {
103
+ switch status {
104
+ case CacheStatus.initialised:
105
+ return "initialised"
106
+ default:
107
+ return "uninitialised"
108
+ }
109
+ }
110
+
111
+ class func cachingTaskStatusToString(_ status: CachingTaskStatus) -> String {
112
+ switch status {
113
+ case CachingTaskStatus.error:
114
+ return "error"
115
+ case CachingTaskStatus.done:
116
+ return "done"
117
+ case CachingTaskStatus.evicted:
118
+ return "evicted"
119
+ case CachingTaskStatus.loading:
120
+ return "loading"
121
+ default:
122
+ return "idle"
123
+ }
124
+ }
125
+
126
+ class func cacheStatusIdleReasonToString(_ status: CacheStatusIdleReason) -> String {
127
+ switch status {
128
+ case CacheStatusIdleReason.notStarted:
129
+ return "notStarted"
130
+ case CacheStatusIdleReason.paused:
131
+ return "paused"
132
+ case CacheStatusIdleReason.lostNetwork:
133
+ return "lostNetwork"
134
+ default:
135
+ return "notStarted"
136
+ }
100
137
  }
101
138
  }
@@ -88,12 +88,11 @@ public class THEOplayerRCTView: UIView {
88
88
  private func notifyNativePlayerReady() {
89
89
  DispatchQueue.main.async {
90
90
  let versionString = THEOplayer.version
91
- let suiteVersionString = THEOplayer.playerSuiteVersion
92
91
  if let forwardedNativeReady = self.onNativePlayerReady {
93
92
  forwardedNativeReady([
94
93
  "version": [
95
94
  "version" : versionString,
96
- "playerSuiteVersion": suiteVersionString
95
+ "playerSuiteVersion": versionString
97
96
  ],
98
97
  ])
99
98
  }
@@ -18,17 +18,7 @@ extension THEOplayerRCTAdsAPI {
18
18
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
19
19
  if let ads = theView.ads(),
20
20
  let dai = ads.dai {
21
- dai.requestSnapBack { enabled, error in
22
- if let err = error {
23
- reject(ERROR_CODE_DAI_GET_SNAPBACK_FAILED, err.localizedDescription, error)
24
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving dai snapback status failed: \(err.localizedDescription)") }
25
- } else if let snapBack = enabled {
26
- resolve(snapBack)
27
- } else {
28
- reject(ERROR_CODE_DAI_GET_SNAPBACK_UNDEFINED, ERROR_MESSAGE_DAI_GET_SNAPBACK_UNDEFINED, nil)
29
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving dai snapback status failed.") }
30
- }
31
- }
21
+ resolve(dai.snapback)
32
22
  } else {
33
23
  reject(ERROR_CODE_DAI_ACCESS_FAILURE, ERROR_MESSAGE_DAI_ACCESS_FAILURE, nil)
34
24
  if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not retrieve dai snapback status (ads DAI module unavailable).") }
@@ -41,8 +31,8 @@ extension THEOplayerRCTAdsAPI {
41
31
  DispatchQueue.main.async {
42
32
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
43
33
  if let ads = theView.ads(),
44
- let dai = ads.dai {
45
- dai.setSnapBack(enabled, completionHandler: nil)
34
+ var dai = ads.dai {
35
+ dai.snapback = enabled
46
36
  } else {
47
37
  if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not update dai snapback status (ads DAI module unavailable).") }
48
38
  }
@@ -53,14 +53,7 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
53
53
  DispatchQueue.main.async {
54
54
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
55
55
  if let ads = theView.ads() {
56
- ads.requestPlaying { playing, error in
57
- if let err = error {
58
- reject(ERROR_CODE_ADS_GET_PLAYING_STATE_FAILED, err.localizedDescription, error)
59
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving ad playing state failed: \(err.localizedDescription)") }
60
- } else {
61
- resolve(playing)
62
- }
63
- }
56
+ resolve(ads.playing)
64
57
  } else {
65
58
  reject(ERROR_CODE_ADS_ACCESS_FAILURE, ERROR_MESSAGE_ADS_ACCESS_FAILURE, nil)
66
59
  if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not skip ad (ads module unavailable).") }
@@ -72,18 +65,9 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
72
65
  func currentAdBreak(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
73
66
  DispatchQueue.main.async {
74
67
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
75
- if let ads = theView.ads() {
76
- ads.requestCurrentAdBreak { adBreak, error in
77
- if let err = error {
78
- reject(ERROR_CODE_ADS_GET_CURRENT_ADBREAK_FAILED, err.localizedDescription, error)
79
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving current adbreak failed: \(err.localizedDescription)") }
80
- } else if let currentAdBreak = adBreak {
81
- resolve(THEOplayerRCTAdAggregator.aggregateAdBreak(adBreak:currentAdBreak))
82
- } else {
83
- reject(ERROR_CODE_ADS_GET_CURRENT_ADBREAK_UNDEFINED, ERROR_MESSAGE_ADS_GET_CURRENT_ADBREAK_UNDEFINED, nil)
84
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving current adbreak failed: could not load adbreak.") }
85
- }
86
- }
68
+ if let ads = theView.ads(),
69
+ let currentAdBreak = ads.currentAdBreak {
70
+ resolve(THEOplayerRCTAdAggregator.aggregateAdBreak(adBreak:currentAdBreak))
87
71
  } else {
88
72
  reject(ERROR_CODE_ADS_ACCESS_FAILURE, ERROR_MESSAGE_ADS_ACCESS_FAILURE, nil)
89
73
  if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not retrieve current adbreak (ads module unavailable).") }
@@ -96,21 +80,12 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
96
80
  DispatchQueue.main.async {
97
81
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
98
82
  if let ads = theView.ads() {
99
- ads.requestCurrentAds { adsArray, error in
100
- if let err = error {
101
- reject(ERROR_CODE_ADS_GET_CURRENT_ADS_FAILED, err.localizedDescription, error)
102
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving current ads failed: \(err.localizedDescription)") }
103
- } else if let currentAdsArray = adsArray {
104
- var currentAds: [[String:Any]] = []
105
- for ad in currentAdsArray {
106
- currentAds.append(THEOplayerRCTAdAggregator.aggregateAd(ad: ad))
107
- }
108
- resolve(currentAds)
109
- } else {
110
- reject(ERROR_CODE_ADS_GET_CURRENT_ADS_UNDEFINED, ERROR_MESSAGE_ADS_GET_CURRENT_ADS_UNDEFINED, nil)
111
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving current ads failed: could not load ads.") }
112
- }
83
+ let currentAdsArray = ads.currentAds
84
+ var currentAds: [[String:Any]] = []
85
+ for ad in currentAdsArray {
86
+ currentAds.append(THEOplayerRCTAdAggregator.aggregateAd(ad: ad))
113
87
  }
88
+ resolve(currentAds)
114
89
  } else {
115
90
  reject(ERROR_CODE_ADS_ACCESS_FAILURE, ERROR_MESSAGE_ADS_ACCESS_FAILURE, nil)
116
91
  if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not retrieve current ad (ads module unavailable).") }
@@ -123,21 +98,12 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
123
98
  DispatchQueue.main.async {
124
99
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
125
100
  if let ads = theView.ads() {
126
- ads.requestScheduledAdBreaks { adBreaksArray, error in
127
- if let err = error {
128
- reject(ERROR_CODE_ADS_GET_SCHEDULED_ADBREAKS_FAILED, err.localizedDescription, error)
129
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving scheduled adbreaks failed: \(err.localizedDescription)") }
130
- } else if let currentAdBreaksArray = adBreaksArray {
131
- var currentAdBreaks: [[String:Any]] = []
132
- for adbreak in currentAdBreaksArray {
133
- currentAdBreaks.append(THEOplayerRCTAdAggregator.aggregateAdBreak(adBreak: adbreak))
134
- }
135
- resolve(currentAdBreaks)
136
- } else {
137
- reject(ERROR_CODE_ADS_GET_SCHEDULED_ADBREAKS_UNDEFINED, ERROR_MESSAGE_ADS_GET_SCHEDULED_ADBREAKS_UNDEFINED, nil)
138
- if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Retrieving current adbreaks failed: could not load adbreaks.") }
139
- }
101
+ let currentAdBreaksArray = ads.scheduledAdBreaks
102
+ var currentAdBreaks: [[String:Any]] = []
103
+ for adbreak in currentAdBreaksArray {
104
+ currentAdBreaks.append(THEOplayerRCTAdAggregator.aggregateAdBreak(adBreak: adbreak))
140
105
  }
106
+ resolve(currentAdBreaks)
141
107
  } else {
142
108
  reject(ERROR_CODE_ADS_ACCESS_FAILURE, ERROR_MESSAGE_ADS_ACCESS_FAILURE, nil)
143
109
  if DEBUG_ADS_API { PrintUtils.printLog(logText: "[NATIVE] Could not retrieve current ad (ads module unavailable).") }
@@ -5,7 +5,6 @@ import THEOplayerSDK
5
5
 
6
6
  struct AdsConfig {
7
7
  var adSUIEnabled: Bool = true
8
- var googleImaUsesNativeIma: Bool = true
9
8
  var adPreloadTypeString: String = "none"
10
9
  }
11
10
 
@@ -19,16 +18,12 @@ extension THEOplayerRCTView {
19
18
  if let adPreloadType = adsConfig["preload"] as? String {
20
19
  self.adsConfig.adPreloadTypeString = adPreloadType
21
20
  }
22
- if let googleImaConfiguration = adsConfig["googleImaConfiguration"] as? NSDictionary {
23
- self.adsConfig.googleImaUsesNativeIma = googleImaConfiguration["useNativeIma"] as? Bool ?? true
24
- }
25
21
  }
26
22
  }
27
23
 
28
24
  #if (GOOGLE_IMA || GOOGLE_DAI) || canImport(THEOplayerGoogleIMAIntegration)
29
25
  func playerAdsConfiguration() -> AdsConfiguration? {
30
26
  let googleBuilder = GoogleIMAConfigurationBuilder()
31
- googleBuilder.useNativeIMA = self.adsConfig.googleImaUsesNativeIma
32
27
  googleBuilder.disableUI = !self.adsConfig.adSUIEnabled
33
28
  googleBuilder.enableBackgroundPlayback = true
34
29
  let googleIMAAdsConfiguration = googleBuilder.build()
@@ -40,14 +35,6 @@ extension THEOplayerRCTView {
40
35
  preload: self.adPreloadType(),
41
36
  googleIma: googleIMAAdsConfiguration,
42
37
  googleDai: googleDaiAdsConfiguration)
43
-
44
- // For older iOS SDK versions replace the above with:
45
- /*let googleIMAConfiguration = GoogleIMAConfiguration()
46
- googleIMAConfiguration.useNativeIma = self.googleImaUsesNativeIma
47
- googleIMAConfiguration.disableUI = !self.adSUIEnabled
48
- return AdsConfiguration(showCountdown: self.adSUIEnabled,
49
- preload: self.adPreloadType,
50
- googleImaConfiguration: googleIMAConfiguration)*/
51
38
  }
52
39
 
53
40
  private func adPreloadType() -> THEOplayerSDK.AdPreloadType {
@@ -50,10 +50,9 @@ class THEOplayerRCTNowPlayingManager {
50
50
  self.updatePlaybackRate(player.playbackRate)
51
51
  self.updateServiceIdentifier(metadata.metadataKeys?["nowPlayingServiceIdentifier"] as? String)
52
52
  self.updateContentIdentifier(metadata.metadataKeys?["nowPlayingContentIdentifier"] as? String)
53
+ self.updateCurrentTime(player.currentTime)
53
54
  self.updateArtWork(artWorkUrlString) { [weak self] in
54
- self?.updateCurrentTime { [weak self] in
55
- self?.processNowPlayingToInfoCenter()
56
- }
55
+ self?.processNowPlayingToInfoCenter()
57
56
  }
58
57
  }
59
58
  }
@@ -160,19 +159,8 @@ class THEOplayerRCTNowPlayingManager {
160
159
  self.nowPlayingInfo[MPNowPlayingInfoPropertyPlaybackRate] = NSNumber(value: playerPlaybackRate)
161
160
  }
162
161
 
163
- private func updateCurrentTime(completion: (() -> Void)?) {
164
- if let player = self.player {
165
- player.requestCurrentTime(completionHandler: { [weak self] time, error in
166
- if let welf = self,
167
- let currentTime = time {
168
- welf.nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: currentTime)
169
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] CurrentTime updated in nowPlayingInfo.") }
170
- DispatchQueue.main.async {
171
- completion?()
172
- }
173
- }
174
- })
175
- }
162
+ private func updateCurrentTime(_ currentTime: Double) {
163
+ self.nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = NSNumber(value: currentTime)
176
164
  }
177
165
 
178
166
  private func attachListeners() {
@@ -195,24 +183,24 @@ class THEOplayerRCTNowPlayingManager {
195
183
  }
196
184
 
197
185
  // PLAYING
198
- self.playingListener = player.addEventListener(type: PlayerEventTypes.PLAYING) { [weak self] event in
199
- self?.updatePlaybackState()
200
- self?.updateCurrentTime { [weak self] in
201
- if let welf = self {
202
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] PLAYING: Updating playbackState and time on NowPlayingInfoCenter...") }
203
- welf.processNowPlayingToInfoCenter()
204
- }
186
+ self.playingListener = player.addEventListener(type: PlayerEventTypes.PLAYING) { [weak self, weak player] event in
187
+ if let welf = self,
188
+ let wplayer = player {
189
+ welf.updatePlaybackState()
190
+ welf.updateCurrentTime(wplayer.currentTime)
191
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] PLAYING: Updating playbackState and time on NowPlayingInfoCenter...") }
192
+ welf.processNowPlayingToInfoCenter()
205
193
  }
206
194
  }
207
195
 
208
196
  // PAUSE
209
- self.pauseListener = player.addEventListener(type: PlayerEventTypes.PAUSE) { [weak self] event in
210
- self?.updatePlaybackState()
211
- self?.updateCurrentTime { [weak self] in
212
- if let welf = self {
213
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] PAUSED: Updating PlaybackState and time on NowPlayingInfoCenter...") }
214
- welf.processNowPlayingToInfoCenter()
215
- }
197
+ self.pauseListener = player.addEventListener(type: PlayerEventTypes.PAUSE) { [weak self, weak player] event in
198
+ if let welf = self,
199
+ let wplayer = player {
200
+ welf.updatePlaybackState()
201
+ welf.updateCurrentTime(wplayer.currentTime)
202
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] PAUSED: Updating PlaybackState and time on NowPlayingInfoCenter...") }
203
+ welf.processNowPlayingToInfoCenter()
216
204
  }
217
205
  }
218
206
 
@@ -228,12 +216,12 @@ class THEOplayerRCTNowPlayingManager {
228
216
  }
229
217
 
230
218
  // SEEKED
231
- self.seekedListener = player.addEventListener(type: PlayerEventTypes.SEEKED) { [weak self] event in
232
- self?.updateCurrentTime { [weak self] in
233
- if let welf = self {
234
- if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] SEEKED: Time updated on NowPlayingInfoCenter.") }
235
- welf.processNowPlayingToInfoCenter()
236
- }
219
+ self.seekedListener = player.addEventListener(type: PlayerEventTypes.SEEKED) { [weak self, weak player] event in
220
+ if let welf = self,
221
+ let wplayer = player {
222
+ welf.updateCurrentTime(wplayer.currentTime)
223
+ if DEBUG_NOWINFO { PrintUtils.printLog(logText: "[NATIVE] SEEKED: Time updated on NowPlayingInfoCenter.") }
224
+ welf.processNowPlayingToInfoCenter()
237
225
  }
238
226
  }
239
227
 
@@ -153,11 +153,7 @@ class THEOplayerRCTRemoteCommandsManager: NSObject {
153
153
  if let player = self.player,
154
154
  !self.isLive,
155
155
  !self.inAd {
156
- player.requestCurrentTime(completionHandler: { time, error in
157
- if let currentTime = time {
158
- player.setCurrentTime(currentTime + event.interval)
159
- }
160
- })
156
+ player.currentTime = player.currentTime + event.interval
161
157
  if DEBUG_REMOTECOMMANDS { PrintUtils.printLog(logText: "[NATIVE] Skip forward command handled.") }
162
158
  } else {
163
159
  if DEBUG_REMOTECOMMANDS { PrintUtils.printLog(logText: "[NATIVE] Skip forward command not handled.") }
@@ -169,11 +165,7 @@ class THEOplayerRCTRemoteCommandsManager: NSObject {
169
165
  if let player = self.player ,
170
166
  !self.isLive,
171
167
  !self.inAd {
172
- player.requestCurrentTime(completionHandler: { time, error in
173
- if let currentTime = time {
174
- player.setCurrentTime(currentTime - event.interval)
175
- }
176
- })
168
+ player.currentTime = player.currentTime - event.interval
177
169
  if DEBUG_REMOTECOMMANDS { PrintUtils.printLog(logText: "[NATIVE] Skip backward command handled.") }
178
170
  } else {
179
171
  if DEBUG_REMOTECOMMANDS { PrintUtils.printLog(logText: "[NATIVE] Skip backward command not handled.") }
@@ -0,0 +1,203 @@
1
+ //
2
+ // THEOplayerRCTCacheAPI.swift
3
+ // Theoplayer
4
+ //
5
+ // Created by William Van Haevre on 01/08/2023.
6
+ //
7
+
8
+ import Foundation
9
+ import UIKit
10
+ import THEOplayerSDK
11
+
12
+ let CACHE_EVENT_PROP_STATUS: String = "status"
13
+ let CACHE_EVENT_PROP_PROGRESS: String = "progress"
14
+ let CACHE_EVENT_PROP_TASK: String = "task"
15
+ let CACHE_EVENT_PROP_TASKS: String = "tasks"
16
+
17
+ let CACHE_TAG: String = "[CacheAPI]"
18
+
19
+ @objc(THEOplayerRCTCacheAPI)
20
+ class THEOplayerRCTCacheAPI: RCTEventEmitter {
21
+ // MARK: Cache Listeners
22
+ private var cacheStatusListener: EventListener?
23
+
24
+ // MARK: CacheTask listeners (attached dynamically to new tasks)
25
+ private var taskStateChangeListeners: [String:EventListener] = [:] // key is CacheTask.id
26
+ private var taskProgressListeners: [String:EventListener] = [:] // key is CacheTask.id
27
+
28
+ override static func moduleName() -> String! {
29
+ return "CacheModule"
30
+ }
31
+
32
+ override static func requiresMainQueueSetup() -> Bool {
33
+ return false
34
+ }
35
+
36
+ override func supportedEvents() -> [String]! {
37
+ return [
38
+ "onCacheStatusChange",
39
+ "onAddCachingTaskEvent",
40
+ "onRemoveCachingTaskEvent",
41
+ "onCachingTaskProgressEvent",
42
+ "onCachingTaskStatusChangeEvent"
43
+ ]
44
+ }
45
+
46
+ override init() {
47
+ super.init()
48
+
49
+ // attach listeners
50
+ self.attachCacheListeners()
51
+ }
52
+
53
+ deinit {
54
+ self.detachCacheListeners()
55
+ }
56
+
57
+ // MARK: - attach/dettach cache Listeners
58
+ private func attachCacheListeners() {
59
+ // STATE_CHANGE
60
+ self.cacheStatusListener = THEOplayer.cache.addEventListener(type: CacheEventTypes.STATE_CHANGE) { [weak self] event in
61
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received STATE_CHANGE event from THEOplayer.cache") }
62
+ self?.sendEvent(withName: "onCacheStatusChange", body: [
63
+ CACHE_EVENT_PROP_STATUS: THEOplayerRCTTypeUtils.cacheStatusToString(THEOplayer.cache.status)
64
+ ])
65
+ }
66
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] StateChange listener attached to THEOplayer.cache") }
67
+
68
+ // Attach listeners to all task currently known to cache
69
+ for cachingTask in THEOplayer.cache.tasks {
70
+ self.attachTaskListenersToTask(cachingTask)
71
+ }
72
+ }
73
+
74
+ private func detachCacheListeners() {
75
+ // STATE_CHANGE
76
+ if let cacheStatusListener = self.cacheStatusListener {
77
+ THEOplayer.cache.removeEventListener(type: CacheEventTypes.STATE_CHANGE, listener: cacheStatusListener)
78
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] StateChange listener dettached from THEOplayer.cache") }
79
+ }
80
+ }
81
+
82
+ private func attachTaskListenersToTask(_ newTask: CachingTask) {
83
+ // add STATE_CHANGE listeners to newly created task
84
+ self.taskStateChangeListeners[newTask.id] = newTask.addEventListener(type: CachingTaskEventTypes.STATE_CHANGE) { [weak self] event in
85
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received STATE_CHANGE event for task with id \(newTask.id): status is \(THEOplayerRCTTypeUtils.cachingTaskStatusToString(newTask.status))") }
86
+ self?.sendEvent(withName: "onCachingTaskStatusChangeEvent", body: [
87
+ CACHETASK_PROP_ID: newTask.id,
88
+ CACHE_EVENT_PROP_STATUS: THEOplayerRCTTypeUtils.cachingTaskStatusToString(newTask.status)
89
+ ])
90
+
91
+ if let errorEvent = event as? CachingTaskErrorStateChangeEvent,
92
+ let error = errorEvent.error {
93
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] STATE_CHANGE_ERROR event for task with id \(newTask.id): [error] \(error.code):\(error.category) - \(error.message)") }
94
+ } else if let idleEvent = event as? CachingTaskIdleStateChangeEvent {
95
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] STATE_CHANGE_IDLE event for task with id \(newTask.id): [reason] \(THEOplayerRCTTypeUtils.cacheStatusIdleReasonToString(idleEvent.idleReason))") }
96
+ }
97
+ }
98
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] StateChange listener attached to task with id \(newTask.id).") }
99
+
100
+ // add PROGRESS listeners to newly created task
101
+ self.taskProgressListeners[newTask.id] = newTask.addEventListener(type: CachingTaskEventTypes.PROGRESS) { [weak self] event in
102
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Received PROGRESS event from task with id \(newTask.id): progress is \(newTask.percentageCached * 100.0)% of \(newTask.duration) sec.") }
103
+ self?.sendEvent(withName: "onCachingTaskProgressEvent", body: [
104
+ CACHETASK_PROP_ID: newTask.id,
105
+ CACHE_EVENT_PROP_PROGRESS: THEOplayerRCTCacheAggregator.aggregateCacheTaskProgress(task: newTask)
106
+ ] as [String : Any])
107
+ }
108
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Progress listener attached to task with id \(newTask.id).") }
109
+ }
110
+
111
+ private func detachTaskListenersFromTask(_ task: CachingTask) {
112
+ // STATE_CHANGE
113
+ if let taskStateChangeListener = self.taskStateChangeListeners[task.id] {
114
+ task.removeEventListener(type: CachingTaskEventTypes.STATE_CHANGE, listener: taskStateChangeListener)
115
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] StateChange listener dettached from task with id \(task.id)") }
116
+ }
117
+ // PROGRESS
118
+ if let taskProgressListener = self.taskProgressListeners[task.id] {
119
+ task.removeEventListener(type: CachingTaskEventTypes.PROGRESS, listener: taskProgressListener)
120
+ if DEBUG_CACHE_EVENTS { PrintUtils.printLog(logText: "[NATIVE] Progress listener dettached from task with id \(task.id)") }
121
+ }
122
+ }
123
+
124
+ // MARK: API
125
+
126
+ @objc(getInitialState:rejecter:)
127
+ func getInitialState(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
128
+ resolve([
129
+ CACHE_EVENT_PROP_STATUS: THEOplayerRCTTypeUtils.cacheStatusToString(THEOplayer.cache.status),
130
+ CACHE_EVENT_PROP_TASKS: THEOplayerRCTCacheAggregator.aggregateCacheTasks(tasks: THEOplayer.cache.tasks)
131
+ ] as [String : Any])
132
+ }
133
+
134
+ @objc(createTask:params:)
135
+ func createTask(_ src: NSDictionary, params: NSDictionary) -> Void {
136
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] createTask triggered on Cache API.") }
137
+ let params = THEOplayerRCTCachingParametersBuilder.buildCachingParameters(params)
138
+ let (sourceDescription, _) = THEOplayerRCTSourceDescriptionBuilder.buildSourceDescription(src)
139
+ if let srcDescription = sourceDescription,
140
+ let newTask = THEOplayer.cache.createTask(source: srcDescription, parameters: params) {
141
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] New cache task created with id \(newTask.id)") }
142
+
143
+ // emit onAddCachingTaskEvent
144
+ self.sendEvent(withName: "onAddCachingTaskEvent", body: [
145
+ CACHE_EVENT_PROP_TASK: THEOplayerRCTCacheAggregator.aggregateCacheTask(task: newTask)
146
+ ])
147
+
148
+ // attach the state and progress listeners to the new task
149
+ self.attachTaskListenersToTask(newTask)
150
+ }
151
+ }
152
+
153
+ @objc(startCachingTask:)
154
+ func startCachingTask(_ id: NSString) -> Void {
155
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] Start task triggered on Cache API for task with id \(id).") }
156
+ if let task = self.taskById(id as String) {
157
+ task.start()
158
+ }
159
+ }
160
+
161
+ @objc(pauseCachingTask:)
162
+ func pauseCachingTask(_ id: NSString) -> Void {
163
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] Pause task triggered on Cache API for task with id \(id).") }
164
+ if let task = self.taskById(id as String) {
165
+ task.pause()
166
+ }
167
+ }
168
+
169
+ @objc(removeCachingTask:)
170
+ func removeCachingTask(_ id: NSString) -> Void {
171
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] Remove task triggered on Cache API for task with id \(id).") }
172
+ if let task = self.taskById(id as String) {
173
+ // remove the task
174
+ task.remove()
175
+ // remove the listeners
176
+ self.detachTaskListenersFromTask(task)
177
+ }
178
+ }
179
+
180
+ @objc(renewLicense:drmConfig:)
181
+ func renewLicense(_ id: NSString, drmConfig: NSDictionary) -> Void {
182
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] Renew license triggered on Cache API for task with id \(id).") }
183
+ if let task = self.taskById(id as String) {
184
+ guard let contentProtectionData = drmConfig as? [String:Any] else {
185
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] Renew license failed for task with id \(id): Unable to extract drm configuration data.") }
186
+ return
187
+ }
188
+ let sanitisedContentProtectionData = THEOplayerRCTSourceDescriptionBuilder.sanitiseContentProtectionData(contentProtectionData)
189
+ if let contentProtectionConfig = THEOplayerRCTSourceDescriptionBuilder.buildContentProtection(sanitisedContentProtectionData) {
190
+ task.license.renew(contentProtectionConfig)
191
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] License renewed for task with id \(id).") }
192
+ } else {
193
+ if DEBUG_CACHE_API { PrintUtils.printLog(logText: "[NATIVE] Renew license failed for task with id \(id): Invalid contentProtection input.") }
194
+ }
195
+ }
196
+ }
197
+
198
+ private func taskById(_ id: String) -> CachingTask? {
199
+ return THEOplayer.cache.tasks.first {
200
+ cachingTask in cachingTask.id == id
201
+ }
202
+ }
203
+ }
@@ -0,0 +1,87 @@
1
+ // THEOplayerRCTContentProtectionAggregator.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+
6
+ let CACHETASK_PROP_ID: String = "id"
7
+ let CACHETASK_PROP_STATUS: String = "status"
8
+ let CACHETASK_PROP_SOURCE: String = "source"
9
+ let CACHETASK_PROP_PARAMETERS: String = "parameters"
10
+ let CACHETASK_PROP_DURATION: String = "duration"
11
+ let CACHETASK_PROP_CACHED: String = "cached"
12
+ let CACHETASK_PROP_SECONDS_CACHED: String = "secondsCached"
13
+ let CACHETASK_PROP_PERCENTAGE_CACHED: String = "percentageCached"
14
+ let CACHETASK_PROP_BYTES: String = "bytes"
15
+ let CACHETASK_PROP_BYTES_CACHED: String = "bytesCached"
16
+ let CACHETASK_PROP_PARAMETERS_AMOUNT: String = "amount"
17
+ let CACHETASK_PROP_PARAMETERS_BANDWIDTH: String = "bandwidth"
18
+ let CACHETASK_PROP_PARAMETERS_EXPIRATION_DATE: String = "expirationDate"
19
+ let CACHETASK_PROP_TIMERANGE_START: String = "start"
20
+ let CACHETASK_PROP_TIMERANGE_END: String = "end"
21
+ let CACHETASK_PROP_PARAMETERS_CELLULAR: String = "allowsCellularAccess"
22
+ let CACHETASK_PROP_PARAMETERS_TRACK_SELECTION: String = "preferredTrackSelection"
23
+ let CACHETASK_PROP_PARAMETERS_AUDIO_TRACK_SELECTION: String = "audioTrackSelection"
24
+ let CACHETASK_PROP_PARAMETERS_TEXT_TRACK_SELECTION: String = "textTrackSelection"
25
+
26
+ let CACHE_AGGREGATOR_TAG: String = "[CacheAggregator]"
27
+
28
+ class THEOplayerRCTCacheAggregator {
29
+
30
+ class func aggregateCacheTasks(tasks: [CachingTask]) -> [[String:Any]] {
31
+ var aggregatedData: [[String:Any]] = []
32
+ tasks.forEach { task in
33
+ aggregatedData.append(THEOplayerRCTCacheAggregator.aggregateCacheTask(task: task))
34
+ }
35
+ return aggregatedData
36
+ }
37
+
38
+ class func aggregateCacheTask(task: CachingTask) -> [String:Any] {
39
+ var aggregatedData: [String:Any] = [:]
40
+ aggregatedData[CACHETASK_PROP_ID] = task.id
41
+ aggregatedData[CACHETASK_PROP_STATUS] = THEOplayerRCTTypeUtils.cachingTaskStatusToString(task.status)
42
+ aggregatedData[CACHETASK_PROP_PARAMETERS] = THEOplayerRCTCacheAggregator.aggregateCacheTaskParameters(params: task.parameters)
43
+ aggregatedData[CACHETASK_PROP_SOURCE] = THEOplayerRCTSourceDescriptionAggregator.aggregateCacheTaskSourceDescription(sourceDescription: task.source)
44
+ for (key, value) in THEOplayerRCTCacheAggregator.aggregateCacheTaskProgress(task: task) {
45
+ aggregatedData[key] = value
46
+ }
47
+ return aggregatedData
48
+ }
49
+
50
+ class func aggregateCacheTaskProgress(task: CachingTask) -> [String:Any] {
51
+ var aggregatedData: [String:Any] = [:]
52
+ aggregatedData[CACHETASK_PROP_DURATION] = task.duration // in sec
53
+ aggregatedData[CACHETASK_PROP_CACHED] = THEOplayerRCTCacheAggregator.aggregateCachedTimeRanges(ranges: task.cached)
54
+ aggregatedData[CACHETASK_PROP_SECONDS_CACHED] = task.secondsCached
55
+ aggregatedData[CACHETASK_PROP_PERCENTAGE_CACHED] = task.percentageCached
56
+ aggregatedData[CACHETASK_PROP_BYTES] = -1 // default setting, as iOS does not provide estimate yet.
57
+ aggregatedData[CACHETASK_PROP_BYTES_CACHED] = task.bytesCached
58
+ return aggregatedData
59
+
60
+ }
61
+
62
+ private class func aggregateCacheTaskParameters(params: CachingParameters) -> [String:Any] {
63
+ var aggregatedData: [String:Any] = [:]
64
+ aggregatedData[CACHETASK_PROP_PARAMETERS_AMOUNT] = "100%"
65
+ if let bandwidthValue = params.bandwidth {
66
+ aggregatedData[CACHETASK_PROP_PARAMETERS_BANDWIDTH] = bandwidthValue
67
+ }
68
+ aggregatedData[CACHETASK_PROP_PARAMETERS_EXPIRATION_DATE] = params.expirationDate.timeIntervalSince1970 * 1000 // sec -> msec
69
+ aggregatedData[CACHETASK_PROP_PARAMETERS_CELLULAR] = params.allowsCellularAccess
70
+ aggregatedData[CACHETASK_PROP_PARAMETERS_TRACK_SELECTION] = [
71
+ CACHETASK_PROP_PARAMETERS_AUDIO_TRACK_SELECTION : params.preferredTrackSelection.audioTrackSelection,
72
+ CACHETASK_PROP_PARAMETERS_TEXT_TRACK_SELECTION: params.preferredTrackSelection.textTrackSelection
73
+ ]
74
+ return aggregatedData
75
+ }
76
+
77
+ private class func aggregateCachedTimeRanges(ranges: [TimeRange]) -> [[String:Any]] {
78
+ var aggregatedData: [[String:Any]] = []
79
+ for timeRange in ranges {
80
+ aggregatedData.append([
81
+ CACHETASK_PROP_TIMERANGE_START : timeRange.start * 1000, // sec -> msec
82
+ CACHETASK_PROP_TIMERANGE_END : timeRange.end * 1000 // sec -> msec
83
+ ])
84
+ }
85
+ return aggregatedData
86
+ }
87
+ }