react-native-theoplayer 1.7.1 → 1.8.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 (243) hide show
  1. package/README.md +2 -0
  2. package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +115 -0
  3. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +648 -0
  4. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +23 -0
  5. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +446 -0
  6. package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.kt +117 -0
  7. package/android/src/main/java/com/theoplayer/{TimeUpdateRate.java → TimeUpdateRate.kt} +2 -2
  8. package/android/src/main/java/com/theoplayer/ads/AdAdapter.kt +161 -0
  9. package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.kt +90 -0
  10. package/android/src/main/java/com/theoplayer/ads/AdsModule.kt +140 -0
  11. package/android/src/main/java/com/theoplayer/cast/CastEventAdapter.kt +81 -0
  12. package/android/src/main/java/com/theoplayer/cast/CastModule.kt +75 -0
  13. package/android/src/main/java/com/theoplayer/drm/ContentProtectionAdapter.kt +2 -2
  14. package/android/src/main/java/com/theoplayer/drm/ContentProtectionModule.kt +1 -2
  15. package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegration.kt +1 -2
  16. package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegrationFactory.kt +3 -5
  17. package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +402 -0
  18. package/android/src/main/java/com/theoplayer/track/MediaTrackEventType.kt +6 -0
  19. package/android/src/main/java/com/theoplayer/track/MediaTrackType.kt +6 -0
  20. package/android/src/main/java/com/theoplayer/track/QualityListAdapter.kt +43 -0
  21. package/android/src/main/java/com/theoplayer/track/QualityListFilter.kt +28 -0
  22. package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.kt +10 -0
  23. package/android/src/main/java/com/theoplayer/track/TrackEventType.kt +7 -0
  24. package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +219 -0
  25. package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +19 -0
  26. package/ios/THEOplayerRCTAdAggregator.swift +15 -6
  27. package/ios/THEOplayerRCTAdsAPI.swift +39 -40
  28. package/ios/THEOplayerRCTBridge.m +54 -1
  29. package/ios/THEOplayerRCTCastAPI.swift +275 -0
  30. package/ios/THEOplayerRCTDebug.swift +3 -0
  31. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +91 -19
  32. package/ios/THEOplayerRCTTrackEventTypes.swift +17 -0
  33. package/ios/{THEOplayerRCTMetadataAggregator.swift → THEOplayerRCTTrackMetadataAggregator.swift} +69 -55
  34. package/ios/THEOplayerRCTView.swift +126 -22
  35. package/ios/THEOplayerRCTViewAdEventHandler.swift +7 -5
  36. package/ios/THEOplayerRCTViewCastEventHandler.swift +124 -0
  37. package/ios/THEOplayerRCTViewMainEventHandler.swift +1 -1
  38. package/ios/THEOplayerRCTViewMediaTrackEventHandler.swift +185 -0
  39. package/ios/THEOplayerRCTViewTextTrackEventHandler.swift +30 -13
  40. package/ios/custom/Frameworks/ios/put_custom_ios_xcframework_here.txt +1 -1
  41. package/ios/custom/Frameworks/tvos/put_custom_tvos_xcframework_here.txt +2 -0
  42. package/ios/custom/react-native-theoplayer_custom.podspec +46 -0
  43. package/lib/commonjs/api/THEOplayerView.js.map +1 -1
  44. package/lib/commonjs/api/barrel.js +21 -8
  45. package/lib/commonjs/api/barrel.js.map +1 -1
  46. package/lib/commonjs/api/cast/Airplay.js +6 -0
  47. package/lib/commonjs/api/cast/Airplay.js.map +1 -0
  48. package/lib/commonjs/api/cast/CastAPI.js +6 -0
  49. package/lib/commonjs/api/cast/CastAPI.js.map +1 -0
  50. package/lib/commonjs/api/cast/CastConfiguration.js +2 -0
  51. package/lib/commonjs/api/cast/CastConfiguration.js.map +1 -0
  52. package/lib/commonjs/api/cast/CastState.js +2 -0
  53. package/lib/commonjs/api/cast/CastState.js.map +1 -0
  54. package/lib/commonjs/api/cast/Chromecast.js +6 -0
  55. package/lib/commonjs/api/cast/Chromecast.js.map +1 -0
  56. package/lib/commonjs/api/cast/barrel.js +71 -0
  57. package/lib/commonjs/api/cast/barrel.js.map +1 -0
  58. package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
  59. package/lib/commonjs/api/error/ChromecastError.js +2 -0
  60. package/lib/commonjs/api/error/ChromecastError.js.map +1 -0
  61. package/lib/commonjs/api/error/barrel.js +13 -0
  62. package/lib/commonjs/api/error/barrel.js.map +1 -1
  63. package/lib/commonjs/api/event/CastEvent.js +21 -0
  64. package/lib/commonjs/api/event/CastEvent.js.map +1 -0
  65. package/lib/commonjs/api/event/TrackEvent.js +17 -1
  66. package/lib/commonjs/api/event/TrackEvent.js.map +1 -1
  67. package/lib/commonjs/api/event/barrel.js +25 -12
  68. package/lib/commonjs/api/event/barrel.js.map +1 -1
  69. package/lib/commonjs/api/source/SourceDescription.js.map +1 -1
  70. package/lib/commonjs/api/source/barrel.js +13 -0
  71. package/lib/commonjs/api/source/barrel.js.map +1 -1
  72. package/lib/commonjs/api/source/metadata/MetadataDescription.js +2 -0
  73. package/lib/commonjs/api/source/metadata/MetadataDescription.js.map +1 -0
  74. package/lib/commonjs/api/source/metadata/barrel.js +19 -0
  75. package/lib/commonjs/api/source/metadata/barrel.js.map +1 -0
  76. package/lib/commonjs/internal/THEOplayerView.js +30 -0
  77. package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
  78. package/lib/commonjs/internal/THEOplayerView.web.js +80 -20
  79. package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
  80. package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js +34 -0
  81. package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
  82. package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js +46 -0
  83. package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
  84. package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js +42 -0
  85. package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
  86. package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js +31 -0
  87. package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js.map +1 -0
  88. package/lib/commonjs/internal/web/stub/CastButtonStub.js +16 -0
  89. package/lib/commonjs/internal/web/stub/CastButtonStub.js.map +1 -0
  90. package/lib/module/api/THEOplayerView.js.map +1 -1
  91. package/lib/module/api/barrel.js +1 -0
  92. package/lib/module/api/barrel.js.map +1 -1
  93. package/lib/module/api/cast/Airplay.js +2 -0
  94. package/lib/module/api/cast/Airplay.js.map +1 -0
  95. package/lib/module/api/cast/CastAPI.js +2 -0
  96. package/lib/module/api/cast/CastAPI.js.map +1 -0
  97. package/lib/module/api/cast/CastConfiguration.js +2 -0
  98. package/lib/module/api/cast/CastConfiguration.js.map +1 -0
  99. package/lib/module/api/cast/CastState.js +2 -0
  100. package/lib/module/api/cast/CastState.js.map +1 -0
  101. package/lib/module/api/cast/Chromecast.js +2 -0
  102. package/lib/module/api/cast/Chromecast.js.map +1 -0
  103. package/lib/module/api/cast/barrel.js +6 -0
  104. package/lib/module/api/cast/barrel.js.map +1 -0
  105. package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
  106. package/lib/module/api/error/ChromecastError.js +2 -0
  107. package/lib/module/api/error/ChromecastError.js.map +1 -0
  108. package/lib/module/api/error/barrel.js +1 -0
  109. package/lib/module/api/error/barrel.js.map +1 -1
  110. package/lib/module/api/event/CastEvent.js +14 -0
  111. package/lib/module/api/event/CastEvent.js.map +1 -0
  112. package/lib/module/api/event/TrackEvent.js +14 -0
  113. package/lib/module/api/event/TrackEvent.js.map +1 -1
  114. package/lib/module/api/event/barrel.js +2 -1
  115. package/lib/module/api/event/barrel.js.map +1 -1
  116. package/lib/module/api/source/SourceDescription.js.map +1 -1
  117. package/lib/module/api/source/barrel.js +1 -0
  118. package/lib/module/api/source/barrel.js.map +1 -1
  119. package/lib/module/api/source/metadata/MetadataDescription.js +2 -0
  120. package/lib/module/api/source/metadata/MetadataDescription.js.map +1 -0
  121. package/lib/module/api/source/metadata/barrel.js +2 -0
  122. package/lib/module/api/source/metadata/barrel.js.map +1 -0
  123. package/lib/module/internal/THEOplayerView.js +29 -0
  124. package/lib/module/internal/THEOplayerView.js.map +1 -1
  125. package/lib/module/internal/THEOplayerView.web.js +80 -21
  126. package/lib/module/internal/THEOplayerView.web.js.map +1 -1
  127. package/lib/module/internal/cast/THEOplayerNativeAirplay.js +24 -0
  128. package/lib/module/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
  129. package/lib/module/internal/cast/THEOplayerNativeCastApi.js +34 -0
  130. package/lib/module/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
  131. package/lib/module/internal/cast/THEOplayerNativeChromecast.js +32 -0
  132. package/lib/module/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
  133. package/lib/module/internal/cast/THEOplayerWebCastApi.js +22 -0
  134. package/lib/module/internal/cast/THEOplayerWebCastApi.js.map +1 -0
  135. package/lib/module/internal/web/stub/CastButtonStub.js +6 -0
  136. package/lib/module/internal/web/stub/CastButtonStub.js.map +1 -0
  137. package/lib/typescript/lib/commonjs/api/cast/Airplay.d.ts +1 -0
  138. package/lib/typescript/lib/commonjs/api/cast/CastAPI.d.ts +1 -0
  139. package/lib/typescript/lib/commonjs/api/cast/CastConfiguration.d.ts +0 -0
  140. package/lib/typescript/lib/commonjs/api/cast/CastState.d.ts +0 -0
  141. package/lib/typescript/lib/commonjs/api/cast/Chromecast.d.ts +1 -0
  142. package/lib/typescript/lib/commonjs/api/cast/barrel.d.ts +1 -0
  143. package/lib/typescript/lib/commonjs/api/error/ChromecastError.d.ts +0 -0
  144. package/lib/typescript/lib/commonjs/api/event/CastEvent.d.ts +2 -0
  145. package/lib/typescript/lib/commonjs/api/event/TrackEvent.d.ts +4 -0
  146. package/lib/typescript/lib/commonjs/api/source/metadata/MetadataDescription.d.ts +0 -0
  147. package/lib/typescript/lib/commonjs/api/source/metadata/barrel.d.ts +1 -0
  148. package/lib/typescript/lib/commonjs/internal/THEOplayerView.d.ts +3 -0
  149. package/lib/typescript/lib/commonjs/internal/THEOplayerView.web.d.ts +3 -0
  150. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
  151. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeCastApi.d.ts +12 -0
  152. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
  153. package/lib/typescript/lib/commonjs/internal/cast/THEOplayerWebCastApi.d.ts +8 -0
  154. package/lib/typescript/lib/commonjs/internal/web/stub/CastButtonStub.d.ts +2 -0
  155. package/lib/typescript/lib/module/api/barrel.d.ts +1 -0
  156. package/lib/typescript/lib/module/api/cast/Airplay.d.ts +1 -0
  157. package/lib/typescript/lib/module/api/cast/CastAPI.d.ts +1 -0
  158. package/lib/typescript/lib/module/api/cast/CastConfiguration.d.ts +0 -0
  159. package/lib/typescript/lib/module/api/cast/CastState.d.ts +0 -0
  160. package/lib/typescript/lib/module/api/cast/Chromecast.d.ts +1 -0
  161. package/lib/typescript/lib/module/api/cast/barrel.d.ts +3 -0
  162. package/lib/typescript/lib/module/api/error/ChromecastError.d.ts +0 -0
  163. package/lib/typescript/lib/module/api/event/CastEvent.d.ts +1 -0
  164. package/lib/typescript/lib/module/api/event/TrackEvent.d.ts +2 -0
  165. package/lib/typescript/lib/module/api/event/barrel.d.ts +2 -1
  166. package/lib/typescript/lib/module/api/source/barrel.d.ts +1 -0
  167. package/lib/typescript/lib/module/api/source/metadata/MetadataDescription.d.ts +0 -0
  168. package/lib/typescript/lib/module/api/source/metadata/barrel.d.ts +1 -0
  169. package/lib/typescript/lib/module/internal/THEOplayerView.d.ts +3 -0
  170. package/lib/typescript/lib/module/internal/THEOplayerView.web.d.ts +3 -0
  171. package/lib/typescript/lib/module/internal/cast/THEOplayerNativeAirplay.d.ts +8 -0
  172. package/lib/typescript/lib/module/internal/cast/THEOplayerNativeCastApi.d.ts +11 -0
  173. package/lib/typescript/lib/module/internal/cast/THEOplayerNativeChromecast.d.ts +10 -0
  174. package/lib/typescript/lib/module/internal/cast/THEOplayerWebCastApi.d.ts +7 -0
  175. package/lib/typescript/lib/module/internal/web/stub/CastButtonStub.d.ts +2 -0
  176. package/lib/typescript/src/api/THEOplayerView.d.ts +21 -3
  177. package/lib/typescript/src/api/barrel.d.ts +1 -0
  178. package/lib/typescript/src/api/cast/Airplay.d.ts +27 -0
  179. package/lib/typescript/src/api/cast/CastAPI.d.ts +25 -0
  180. package/lib/typescript/src/api/cast/CastConfiguration.d.ts +41 -0
  181. package/lib/typescript/src/api/cast/CastState.d.ts +10 -0
  182. package/lib/typescript/src/api/cast/Chromecast.d.ts +39 -0
  183. package/lib/typescript/src/api/cast/barrel.d.ts +5 -0
  184. package/lib/typescript/src/api/config/PlayerConfiguration.d.ts +6 -1
  185. package/lib/typescript/src/api/error/ChromecastError.d.ts +34 -0
  186. package/lib/typescript/src/api/error/barrel.d.ts +1 -0
  187. package/lib/typescript/src/api/event/CastEvent.d.ts +21 -0
  188. package/lib/typescript/src/api/event/TrackEvent.d.ts +49 -3
  189. package/lib/typescript/src/api/event/barrel.d.ts +2 -1
  190. package/lib/typescript/src/api/source/SourceDescription.d.ts +7 -0
  191. package/lib/typescript/src/api/source/barrel.d.ts +1 -0
  192. package/lib/typescript/src/api/source/metadata/MetadataDescription.d.ts +12 -0
  193. package/lib/typescript/src/api/source/metadata/barrel.d.ts +1 -0
  194. package/lib/typescript/src/internal/THEOplayerView.d.ts +9 -1
  195. package/lib/typescript/src/internal/THEOplayerView.web.d.ts +7 -2
  196. package/lib/typescript/src/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
  197. package/lib/typescript/src/internal/cast/THEOplayerNativeCastApi.d.ts +10 -0
  198. package/lib/typescript/src/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
  199. package/lib/typescript/src/internal/cast/THEOplayerWebCastApi.d.ts +9 -0
  200. package/lib/typescript/src/internal/web/stub/CastButtonStub.d.ts +3 -0
  201. package/package.json +2 -2
  202. package/react-native-theoplayer.podspec +2 -2
  203. package/src/api/THEOplayerView.ts +25 -3
  204. package/src/api/barrel.ts +1 -0
  205. package/src/api/cast/Airplay.ts +31 -0
  206. package/src/api/cast/CastAPI.ts +30 -0
  207. package/src/api/cast/CastConfiguration.ts +44 -0
  208. package/src/api/cast/CastState.ts +10 -0
  209. package/src/api/cast/Chromecast.ts +45 -0
  210. package/src/api/cast/barrel.ts +5 -0
  211. package/src/api/config/PlayerConfiguration.ts +7 -1
  212. package/src/api/error/ChromecastError.ts +46 -0
  213. package/src/api/error/barrel.ts +1 -0
  214. package/src/api/event/CastEvent.ts +45 -0
  215. package/src/api/event/TrackEvent.ts +58 -2
  216. package/src/api/event/barrel.ts +2 -1
  217. package/src/api/source/SourceDescription.ts +8 -0
  218. package/src/api/source/barrel.ts +1 -0
  219. package/src/api/source/metadata/MetadataDescription.ts +13 -0
  220. package/src/api/source/metadata/barrel.ts +1 -0
  221. package/src/internal/THEOplayerView.tsx +35 -0
  222. package/src/internal/THEOplayerView.web.tsx +87 -19
  223. package/src/internal/cast/THEOplayerNativeAirplay.ts +22 -0
  224. package/src/internal/cast/THEOplayerNativeCastApi.ts +28 -0
  225. package/src/internal/cast/THEOplayerNativeChromecast.ts +30 -0
  226. package/src/internal/cast/THEOplayerWebCastApi.ts +21 -0
  227. package/src/internal/web/stub/CastButtonStub.tsx +7 -0
  228. package/android/src/main/java/com/theoplayer/PlayerConfigHelper.java +0 -70
  229. package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.java +0 -32
  230. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.java +0 -525
  231. package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.java +0 -127
  232. package/android/src/main/java/com/theoplayer/SourceHelper.java +0 -362
  233. package/android/src/main/java/com/theoplayer/VideoEventEmitter.java +0 -442
  234. package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.java +0 -92
  235. package/android/src/main/java/com/theoplayer/ads/AdInfo.java +0 -168
  236. package/android/src/main/java/com/theoplayer/ads/AdsModule.java +0 -152
  237. package/android/src/main/java/com/theoplayer/track/QualityListAdapter.java +0 -54
  238. package/android/src/main/java/com/theoplayer/track/QualityListFilter.java +0 -40
  239. package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.java +0 -11
  240. package/android/src/main/java/com/theoplayer/track/TrackEventType.java +0 -11
  241. package/android/src/main/java/com/theoplayer/track/TrackListInfo.java +0 -212
  242. package/android/src/main/java/com/theoplayer/util/ViewResolver.java +0 -42
  243. package/ios/custom/react-native-theoplayer_custom_ios.podspec +0 -36
@@ -0,0 +1,275 @@
1
+ //
2
+ // THEOplayerRCTAdsAPI.swift
3
+ // Theoplayer
4
+ //
5
+ // Created by William van Haevre on 09/09/2022.
6
+ // Copyright © 2022 Facebook. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import UIKit
11
+
12
+ let ERROR_CODE_CAST_ACCESS_FAILURE = "cast_access_failure"
13
+ let ERROR_CODE_CHROMECAST_ACCESS_FAILURE = "chromecast_access_failure"
14
+ let ERROR_CODE_AIRPLAY_ACCESS_FAILURE = "airplay_access_failure"
15
+
16
+ let ERROR_MESSAGE_CASTING_UNSUPPORTED_FEATURE = "Chromecast and Airplay are not supported by the provided iOS SDK"
17
+ let ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE = "Chromecast is not supported by the provided iOS SDK"
18
+ let ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE = "Airplay is not supported by the provided iOS SDK"
19
+ let ERROR_MESSAGE_CAST_ACCESS_FAILURE = "Could not access THEOplayer Cast Module"
20
+ let ERROR_MESSAGE_CHROMECAST_ACCESS_FAILURE = "Could not access THEOplayer Chromecast API"
21
+ let ERROR_MESSAGE_AIRPLAY_ACCESS_FAILURE = "Could not access THEOplayer Airplay API"
22
+
23
+ @objc(THEOplayerRCTCastAPI)
24
+ class THEOplayerRCTCastAPI: NSObject, RCTBridgeModule {
25
+ @objc var bridge: RCTBridge!
26
+
27
+ static func moduleName() -> String! {
28
+ return "CastModule"
29
+ }
30
+
31
+ static func requiresMainQueueSetup() -> Bool {
32
+ return false
33
+ }
34
+
35
+ // MARK: CHROMECAST AND AIRPLAY
36
+
37
+ #if os(iOS)
38
+
39
+ @objc(casting:resolver:rejecter:)
40
+ func casting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
41
+ DispatchQueue.main.async {
42
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
43
+ if let cast = theView.cast() {
44
+ resolve(cast.casting)
45
+ } else {
46
+ reject(ERROR_CODE_CAST_ACCESS_FAILURE, ERROR_MESSAGE_CAST_ACCESS_FAILURE, nil)
47
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current casting status (cast module unavailable).") }
48
+ }
49
+ }
50
+ }
51
+
52
+ #else
53
+
54
+ @objc(casting:resolver:rejecter:)
55
+ func casting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
56
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CASTING_UNSUPPORTED_FEATURE) }
57
+ resolve(false)
58
+ }
59
+
60
+ #endif
61
+
62
+
63
+
64
+ // MARK: CHROMECAST SPECIFIC
65
+
66
+ #if os(iOS) && CHROMECAST
67
+ @objc(chromecastCasting:resolver:rejecter:)
68
+ func chromecastCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
69
+ DispatchQueue.main.async {
70
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
71
+ if let cast = theView.cast(),
72
+ let chromecast = cast.chromecast {
73
+ resolve(chromecast.casting)
74
+ } else {
75
+ reject(ERROR_CODE_CHROMECAST_ACCESS_FAILURE, ERROR_MESSAGE_CHROMECAST_ACCESS_FAILURE, nil)
76
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current chromecast casting status.") }
77
+ }
78
+ }
79
+ }
80
+
81
+ @objc(chromecastState:resolver:rejecter:)
82
+ func chromecastState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
83
+ DispatchQueue.main.async {
84
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
85
+ if let cast = theView.cast(),
86
+ let chromecast = cast.chromecast {
87
+ resolve(chromecast.state?._rawValue)
88
+ } else {
89
+ reject(ERROR_CODE_CHROMECAST_ACCESS_FAILURE, ERROR_MESSAGE_CHROMECAST_ACCESS_FAILURE, nil)
90
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current chromecast state.") }
91
+ }
92
+ }
93
+ }
94
+
95
+ @objc(chromecastStart:)
96
+ func chromecastStart(_ node: NSNumber) -> Void {
97
+ DispatchQueue.main.async {
98
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
99
+ if let cast = theView.cast(),
100
+ let chromecast = cast.chromecast {
101
+ if DEBUG_CAST_API { print("[NATIVE] Starting chromecast session.") }
102
+ chromecast.start()
103
+ } else {
104
+ if DEBUG_CAST_API { print("[NATIVE] Could not start chromecast session.") }
105
+ }
106
+ }
107
+ }
108
+
109
+ @objc(chromecastStop:)
110
+ func chromecastStop(_ node: NSNumber) -> Void {
111
+ DispatchQueue.main.async {
112
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
113
+ if let cast = theView.cast(),
114
+ let chromecast = cast.chromecast {
115
+ if DEBUG_CAST_API { print("[NATIVE] Stopping chromecast session.") }
116
+ chromecast.stop()
117
+ } else {
118
+ if DEBUG_CAST_API { print("[NATIVE] Could not stop chromecast session.") }
119
+ }
120
+ }
121
+ }
122
+
123
+ @objc(chromecastJoin:)
124
+ func chromecastJoin(_ node: NSNumber) -> Void {
125
+ DispatchQueue.main.async {
126
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
127
+ if let cast = theView.cast(),
128
+ let chromecast = cast.chromecast {
129
+ if DEBUG_CAST_API { print("[NATIVE] Joining chromecast session.") }
130
+ chromecast.join()
131
+ } else {
132
+ if DEBUG_CAST_API { print("[NATIVE] Could not join chromecast session.") }
133
+ }
134
+ }
135
+ }
136
+
137
+ @objc(chromecastLeave:)
138
+ func chromecastLeave(_ node: NSNumber) -> Void {
139
+ DispatchQueue.main.async {
140
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
141
+ if let cast = theView.cast(),
142
+ let chromecast = cast.chromecast {
143
+ if DEBUG_CAST_API { print("[NATIVE] Leaving chromecast session.") }
144
+ chromecast.leave()
145
+ } else {
146
+ if DEBUG_CAST_API { print("[NATIVE] Could not leave chromecast session.") }
147
+ }
148
+ }
149
+ }
150
+
151
+ #else
152
+
153
+ @objc(chromecastCasting:resolver:rejecter:)
154
+ func chromecastCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
155
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
156
+ resolve(false)
157
+ }
158
+
159
+ @objc(chromecastState:resolver:rejecter:)
160
+ func chromecastState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
161
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
162
+ resolve("unavailable")
163
+ }
164
+
165
+ @objc(chromecastStart:)
166
+ func chromecastStart(_ node: NSNumber) -> Void {
167
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
168
+ }
169
+
170
+ @objc(chromecastStop:)
171
+ func chromecastStop(_ node: NSNumber) -> Void {
172
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
173
+ }
174
+
175
+ @objc(chromecastJoin:)
176
+ func chromecastJoin(_ node: NSNumber) -> Void {
177
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
178
+ }
179
+
180
+ @objc(chromecastLeave:)
181
+ func chromecastLeave(_ node: NSNumber) -> Void {
182
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
183
+ }
184
+
185
+ #endif
186
+
187
+
188
+
189
+ // MARK: AIRPLAY SPECIFIC
190
+
191
+ #if os(iOS)
192
+
193
+ @objc(airplayCasting:resolver:rejecter:)
194
+ func airplayCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
195
+ DispatchQueue.main.async {
196
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
197
+ if let cast = theView.cast(),
198
+ let airplay = cast.airPlay {
199
+ resolve(airplay.casting)
200
+ } else {
201
+ reject(ERROR_CODE_AIRPLAY_ACCESS_FAILURE, ERROR_MESSAGE_AIRPLAY_ACCESS_FAILURE, nil)
202
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current airplay casting status.") }
203
+ }
204
+ }
205
+ }
206
+
207
+ @objc(airplayState:resolver:rejecter:)
208
+ func airplayState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
209
+ DispatchQueue.main.async {
210
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
211
+ if let cast = theView.cast(),
212
+ let airplay = cast.airPlay {
213
+ resolve(airplay.state._rawValue)
214
+ } else {
215
+ reject(ERROR_CODE_AIRPLAY_ACCESS_FAILURE, ERROR_MESSAGE_AIRPLAY_ACCESS_FAILURE, nil)
216
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current airplay state.") }
217
+ }
218
+ }
219
+ }
220
+
221
+ @objc(airplayStart:)
222
+ func airplayStart(_ node: NSNumber) -> Void {
223
+ DispatchQueue.main.async {
224
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
225
+ if let cast = theView.cast(),
226
+ let airplay = cast.airPlay {
227
+ if DEBUG_CAST_API { print("[NATIVE] Starting airplay session.") }
228
+ airplay.start()
229
+ } else {
230
+ if DEBUG_CAST_API { print("[NATIVE] Could not start airplay session.") }
231
+ }
232
+ }
233
+ }
234
+
235
+ @objc(airplayStop:)
236
+ func airplayStop(_ node: NSNumber) -> Void {
237
+ DispatchQueue.main.async {
238
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
239
+ if let cast = theView.cast(),
240
+ let airplay = cast.airPlay {
241
+ if DEBUG_CAST_API { print("[NATIVE] Stopping airplay session.") }
242
+ airplay.stop()
243
+ } else {
244
+ if DEBUG_CAST_API { print("[NATIVE] Could not stop airplay session.") }
245
+ }
246
+ }
247
+ }
248
+
249
+ #else
250
+
251
+ @objc(airplayCasting:resolver:rejecter:)
252
+ func airplayCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
253
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
254
+ resolve(false)
255
+ }
256
+
257
+ @objc(airplayState:resolver:rejecter:)
258
+ func airplayState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
259
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
260
+ resolve("unavailable")
261
+ }
262
+
263
+ @objc(airplayStart:)
264
+ func airplayStart(_ node: NSNumber) -> Void {
265
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
266
+ }
267
+
268
+ @objc(airplayStop:)
269
+ func airplayStop(_ node: NSNumber) -> Void {
270
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
271
+ }
272
+
273
+ #endif
274
+
275
+ }
@@ -23,3 +23,6 @@ let DEBUG_SOURCE_DESCRIPTION_BUIDER = DEBUG && false
23
23
 
24
24
  // Debug flag to monitor ads API usage
25
25
  let DEBUG_ADS_API = DEBUG && false
26
+
27
+ // Debug flag to monitor cast API usage
28
+ let DEBUG_CAST_API = DEBUG && false
@@ -8,6 +8,7 @@ let SD_PROP_SOURCES: String = "sources"
8
8
  let SD_PROP_POSTER: String = "poster"
9
9
  let SD_PROP_TEXTTRACKS: String = "textTracks"
10
10
  let SD_PROP_ADS: String = "ads"
11
+ let SD_PROP_METADATA: String = "metadata"
11
12
  let SD_PROP_SRC: String = "src"
12
13
  let SD_PROP_TYPE: String = "type"
13
14
  let SD_PROP_SSAI: String = "ssai"
@@ -35,6 +36,13 @@ let SD_PROP_CERTIFICATE_URL: String = "certificateURL"
35
36
  let SD_PROP_LICENSE_URL: String = "licenseAcquisitionURL"
36
37
  let SD_PROP_HEADERS: String = "headers"
37
38
  let SD_PROP_LICENSE_TYPE: String = "licenseType"
39
+ let SD_PROP_METADATA_IMAGES: String = "images"
40
+ let SD_PROP_METADATA_IMAGE_HEIGHT: String = "height"
41
+ let SD_PROP_METADATA_IMAGE_WIDTH: String = "width"
42
+ let SD_PROP_METADATA_RELEASE_DATE: String = "releaseDate"
43
+ let SD_PROP_METADATA_RELEASE_YEAR: String = "releaseYear"
44
+ let SD_PROP_METADATA_TITLE: String = "title"
45
+ let SD_PROP_METADATA_SUBTITLE: String = "subtitle"
38
46
 
39
47
  let EXTENSION_HLS: String = ".m3u8"
40
48
  let EXTENSION_MP4: String = ".mp4"
@@ -138,13 +146,19 @@ class THEOplayerRCTSourceDescriptionBuilder {
138
146
  }
139
147
  }
140
148
  #endif
149
+
150
+ // 5. extract metadata
151
+ var metadataDescription: MetadataDescription?
152
+ if let metadataData = sourceData[SD_PROP_METADATA] as? [String:Any] {
153
+ metadataDescription = THEOplayerRCTSourceDescriptionBuilder.buildMetaDataDescription(metadataData)
154
+ }
141
155
 
142
- // 5. construct and return SourceDescription
156
+ // 6. construct and return SourceDescription
143
157
  return SourceDescription(sources: typedSources,
144
158
  textTracks: textTrackDescriptions,
145
159
  ads: adsDescriptions,
146
160
  poster: poster,
147
- metadata: nil) // TODO
161
+ metadata: metadataDescription)
148
162
  }
149
163
 
150
164
  // MARK: Private build methods
@@ -169,7 +183,7 @@ class THEOplayerRCTSourceDescriptionBuilder {
169
183
  drm: contentProtection)
170
184
  }
171
185
 
172
- #if ADS && GOOGLE_DAI
186
+ #if os(iOS) && ADS && GOOGLE_DAI
173
187
  // check for alternative Google DAI SSAI
174
188
  if let ssaiData = typedSourceData[SD_PROP_SSAI] as? [String:Any] {
175
189
  if let integration = ssaiData[SD_PROP_INTEGRATION] as? String,
@@ -206,7 +220,7 @@ class THEOplayerRCTSourceDescriptionBuilder {
206
220
  }
207
221
  return nil
208
222
  }
209
- // when valid, create a GoolgeDAITypedSource from the GoogleDAIConfiguration
223
+ // when valid, create a GoogleDAITypedSource from the GoogleDAIConfiguration
210
224
  if let config = googleDaiConfig {
211
225
  return GoogleDAITypedSource(ssai: config)
212
226
  }
@@ -267,31 +281,89 @@ class THEOplayerRCTSourceDescriptionBuilder {
267
281
  return nil
268
282
  }
269
283
  #endif
284
+
285
+ /**
286
+ Creates a THEOplayer MetadataDescription. This requires a metadata property in the RN source description.
287
+ - returns: a THEOplayer MetadataDescription
288
+ */
289
+ static func buildMetaDataDescription(_ metadataData: [String:Any]) -> MetadataDescription? {
290
+ // first extract explicit casting metadata:
291
+ #if os(iOS)
292
+ var images: [ChromecastMetadataImage]?
293
+ if let metadataImagesArrayData = metadataData[SD_PROP_METADATA_IMAGES] as? [[String:Any]] {
294
+ images = THEOplayerRCTSourceDescriptionBuilder.buildChromecastMetaDataImagesArray(metadataImagesArrayData)
295
+ }
296
+ let type = THEOplayerRCTSourceDescriptionBuilder.buildChromecastMetadataType(metadataData[SD_PROP_TYPE] as? String)
297
+ let releaseDate = metadataData[SD_PROP_METADATA_RELEASE_DATE] as? String
298
+ let releaseYear = metadataData[SD_PROP_METADATA_RELEASE_YEAR] as? Int
299
+ let title = metadataData[SD_PROP_METADATA_TITLE] as? String
300
+ let subtitle = metadataData[SD_PROP_METADATA_SUBTITLE] as? String
301
+ // all the non-casting related metadata goes in the metadataKeys:
302
+ let metadataKeys = metadataData.filter { metadataElement in
303
+ !(metadataElement.key == SD_PROP_TYPE || metadataElement.key == SD_PROP_METADATA_IMAGES)
304
+ }
305
+ return ChromecastMetadataDescription(images: images,
306
+ releaseDate: releaseDate,
307
+ releaseYear: releaseYear,
308
+ title: title,
309
+ subtitle: subtitle,
310
+ type: type,
311
+ metadataKeys: metadataKeys)
312
+ #else
313
+ let title = metadataData[SD_PROP_METADATA_TITLE] as? String
314
+ return MetadataDescription(metadataKeys: metadataData, title: title)
315
+ #endif
316
+ }
317
+
318
+ #if os(iOS)
319
+ static func buildChromecastMetadataType(_ metadataType: String?) -> ChromecastMetadataType {
320
+ guard let typeString = metadataType else {
321
+ return ChromecastMetadataType.GENERIC
322
+ }
323
+ switch typeString {
324
+ case "none": return ChromecastMetadataType.NONE
325
+ case "audio": return ChromecastMetadataType.AUDIO
326
+ case "tv-show": return ChromecastMetadataType.TV_SHOW
327
+ case "generic": return ChromecastMetadataType.GENERIC
328
+ case "movie": return ChromecastMetadataType.MOVIE
329
+ default: return ChromecastMetadataType.GENERIC
330
+ }
331
+ }
332
+
333
+ static func buildChromecastMetaDataImagesArray(_ metadataImagesArrayData: [[String:Any]]) -> [ChromecastMetadataImage]? {
334
+ var images: [ChromecastMetadataImage] = []
335
+ for metadataImageData in metadataImagesArrayData {
336
+ if let image: ChromecastMetadataImage = THEOplayerRCTSourceDescriptionBuilder.buildChromecastMetaDataImage(metadataImageData) {
337
+ images.append(image)
338
+ }
339
+ }
340
+ return images.count > 0 ? images : nil
341
+ }
342
+
343
+ static func buildChromecastMetaDataImage(_ metadataImageData: [String:Any]) -> ChromecastMetadataImage? {
344
+ if let src = metadataImageData[SD_PROP_SRC] as? String,
345
+ let width = metadataImageData[SD_PROP_METADATA_IMAGE_WIDTH] as? Int,
346
+ let height = metadataImageData[SD_PROP_METADATA_IMAGE_HEIGHT] as? Int {
347
+ return ChromecastMetadataImage(src: src, width: width, height: height)
348
+ }
349
+ return nil
350
+ }
351
+ #endif
270
352
 
271
353
  /**
272
354
  Updates the contentProtectionData to a valid iOS SDK contentProtectionData, flattening out cross SDK differences
273
355
  - returns: a THEOplayer valid contentProtection data map
274
356
  */
275
357
  private static func sanitiseContentProtectionData(_ contentProtectionData: [String:Any]) -> [String:Any] {
276
- var sanitisedContentProtectionData: [String:Any] = [:]
277
- // integration
278
- let sanitisedIntegration = contentProtectionData[SD_PROP_INTEGRATION] as? String
279
- sanitisedContentProtectionData[SD_PROP_INTEGRATION] = sanitisedIntegration
280
- // integrationParameters
281
- let sanitisedIntegrationParameters = contentProtectionData[SD_PROP_INTEGRATION_PARAMETERS] as? [String:Any]
282
- sanitisedContentProtectionData[SD_PROP_INTEGRATION_PARAMETERS] = sanitisedIntegrationParameters
283
- // headers
284
- if let headers = contentProtectionData[SD_PROP_HEADERS] as? [String:String] {
285
- sanitisedContentProtectionData[SD_PROP_HEADERS] = headers
286
- }
287
- // fairplay
358
+ var sanitisedContentProtectionData: [String:Any] = contentProtectionData
359
+ // fairplay update
288
360
  if let fairplayData = contentProtectionData[SD_PROP_FAIRPLAY] as? [String:Any] {
289
361
  var sanitisedFairplayData: [String:Any] = [:]
290
362
  // certificateUrl
291
363
  if let certificateUrl = fairplayData[SD_PROP_CERTIFICATE_URL] as? String {
292
364
  sanitisedFairplayData[SD_PROP_CERTIFICATE_URL] = certificateUrl
293
365
  }
294
- // convert certifiate into certificteUrl with marker prefix (also supported by THEOplayer Web SDK
366
+ // convert certificate into certificateUrl with marker prefix (also supported by THEOplayer Web SDK)
295
367
  if let certificate = fairplayData[SD_PROP_CERTIFICATE] as? String {
296
368
  sanitisedFairplayData[SD_PROP_CERTIFICATE_URL] = "\(CERTIFICATE_MARKER)\(certificate)"
297
369
  }
@@ -309,14 +381,14 @@ class THEOplayerRCTSourceDescriptionBuilder {
309
381
  }
310
382
  sanitisedContentProtectionData[SD_PROP_FAIRPLAY] = sanitisedFairplayData
311
383
  }
312
- // widevine
384
+ // widevine update
313
385
  if let widevineData = contentProtectionData[SD_PROP_WIDEVINE] as? [String:Any] {
314
386
  var sanitisedWidevineData: [String:Any] = [:]
315
387
  // certificateUrl
316
388
  if let certificateUrl = widevineData[SD_PROP_CERTIFICATE_URL] as? String {
317
389
  sanitisedWidevineData[SD_PROP_CERTIFICATE_URL] = certificateUrl
318
390
  }
319
- // convert certifiate into certificteUrl with marker prefix (also supported by THEOplayer Web SDK
391
+ // convert certificate into certificateUrl with marker prefix (also supported by THEOplayer Web SDK)
320
392
  if let certificate = widevineData[SD_PROP_CERTIFICATE] as? String {
321
393
  sanitisedWidevineData[SD_PROP_CERTIFICATE_URL] = "\(CERTIFICATE_MARKER)\(certificate)"
322
394
  }
@@ -0,0 +1,17 @@
1
+ // THEOplayerRCTTrackEventTypes.swift
2
+
3
+ enum MediaTrackType: Int {
4
+ case AUDIO = 0
5
+ case VIDEO = 1
6
+ }
7
+
8
+ enum TrackListEventType: Int {
9
+ case ADD_TRACK = 0
10
+ case REMOVE_TRACK = 1
11
+ case CHANGE_TRACK = 2
12
+ }
13
+
14
+ enum TrackCueEventType: Int {
15
+ case ADD_CUE = 0
16
+ case REMOVE_CUE = 1
17
+ }
@@ -26,23 +26,24 @@ let PROP_CUES: String = "cues"
26
26
  let PROP_CUE_CONTENT: String = "content"
27
27
  let PROP_SRC: String = "src"
28
28
 
29
- class THEOplayerRCTMetadataAggregator {
29
+ class THEOplayerRCTTrackMetadataAggregator {
30
30
 
31
- class func aggregateMetadata(player: THEOplayer) -> [String:Any] {
31
+ class func aggregateTrackMetadata(player: THEOplayer) -> [String:Any] {
32
32
  let textTracks: TextTrackList = player.textTracks
33
33
  let audioTracks: AudioTrackList = player.audioTracks
34
34
  let videoTracks: VideoTrackList = player.videoTracks
35
35
  return [
36
- EVENT_PROP_TEXT_TRACKS : THEOplayerRCTMetadataAggregator.aggregatedTextTrackListInfo(textTracks: textTracks),
37
- EVENT_PROP_AUDIO_TRACKS : THEOplayerRCTMetadataAggregator.aggregatedAudioTrackListInfo(audioTracks: audioTracks),
38
- EVENT_PROP_VIDEO_TRACKS : THEOplayerRCTMetadataAggregator.aggregatedVideoTrackListInfo(videoTracks: videoTracks),
39
- EVENT_PROP_SELECTED_TEXT_TRACK: THEOplayerRCTMetadataAggregator.selectedTextTrack(textTracks: textTracks),
40
- EVENT_PROP_SELECTED_AUDIO_TRACK: THEOplayerRCTMetadataAggregator.selectedAudioTrack(audioTracks: audioTracks),
41
- EVENT_PROP_SELECTED_VIDEO_TRACK: THEOplayerRCTMetadataAggregator.selectedVideoTrack(videoTracks: videoTracks),
36
+ EVENT_PROP_TEXT_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackListInfo(textTracks: textTracks),
37
+ EVENT_PROP_AUDIO_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedAudioTrackListInfo(audioTracks: audioTracks),
38
+ EVENT_PROP_VIDEO_TRACKS : THEOplayerRCTTrackMetadataAggregator.aggregatedVideoTrackListInfo(videoTracks: videoTracks),
39
+ EVENT_PROP_SELECTED_TEXT_TRACK: THEOplayerRCTTrackMetadataAggregator.selectedTextTrack(textTracks: textTracks),
40
+ EVENT_PROP_SELECTED_AUDIO_TRACK: THEOplayerRCTTrackMetadataAggregator.selectedAudioTrack(audioTracks: audioTracks),
41
+ EVENT_PROP_SELECTED_VIDEO_TRACK: THEOplayerRCTTrackMetadataAggregator.selectedVideoTrack(videoTracks: videoTracks),
42
42
  EVENT_PROP_DURATION: THEOplayerRCTTypeUtils.encodeInfNan((player.duration ?? Double.nan) * 1000)
43
43
  ]
44
44
  }
45
45
 
46
+ // MARK: TEXTTRACKS
46
47
  class func aggregatedTextTrackListInfo(textTracks: TextTrackList) -> [[String:Any]] {
47
48
  var textTrackEntries:[[String:Any]] = []
48
49
  guard textTracks.count > 0 else {
@@ -50,7 +51,7 @@ class THEOplayerRCTMetadataAggregator {
50
51
  }
51
52
  for i in 0...textTracks.count-1 {
52
53
  let textTrack: TextTrack = textTracks.get(i)
53
- textTrackEntries.append(THEOplayerRCTMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack))
54
+ textTrackEntries.append(THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackInfo(textTrack: textTrack))
54
55
  }
55
56
  return textTrackEntries
56
57
  }
@@ -69,13 +70,27 @@ class THEOplayerRCTMetadataAggregator {
69
70
  if !textTrack.cues.isEmpty {
70
71
  var cueList: [[String:Any]] = []
71
72
  for cue in textTrack.cues {
72
- cueList.append(THEOplayerRCTMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: cue))
73
+ cueList.append(THEOplayerRCTTrackMetadataAggregator.aggregatedTextTrackCueInfo(textTrackCue: cue))
73
74
  }
74
75
  entry[PROP_CUES] = cueList
75
76
  }
76
77
  return entry
77
78
  }
78
79
 
80
+ private class func selectedTextTrack(textTracks: TextTrackList) -> Int {
81
+ guard textTracks.count > 0 else {
82
+ return 0
83
+ }
84
+ for i in 0...textTracks.count-1 {
85
+ let textTrack: TextTrack = textTracks.get(i)
86
+ if textTrack.mode == TextTrackMode.showing {
87
+ return textTrack.uid
88
+ }
89
+ }
90
+ return 0
91
+ }
92
+
93
+ // MARK: TEXTTRACK CUES
79
94
  class func aggregatedTextTrackCueInfo(textTrackCue: TextTrackCue) -> [String:Any] {
80
95
  var entry: [String:Any] = [:]
81
96
  entry[PROP_ID] = textTrackCue.id
@@ -86,61 +101,33 @@ class THEOplayerRCTMetadataAggregator {
86
101
  return entry
87
102
  }
88
103
 
104
+ // MARK: AUDIOTRACKS
89
105
  private class func aggregatedAudioTrackListInfo(audioTracks: AudioTrackList) -> [[String:Any]] {
90
106
  var audioTrackEntries:[[String:Any]] = []
91
107
  guard audioTracks.count > 0 else {
92
108
  return audioTrackEntries
93
109
  }
94
110
  for i in 0...audioTracks.count-1 {
95
- let audioTrack: MediaTrack = audioTracks.get(i)
96
- var entry: [String:Any] = [:]
97
- entry[PROP_ID] = audioTrack.id
98
- entry[PROP_UID] = audioTrack.uid
99
- entry[PROP_KIND] = audioTrack.kind
100
- entry[PROP_LANGUAGE] = audioTrack.language
101
- entry[PROP_LABEL] = audioTrack.label
102
- entry[PROP_QUALITIES] = [] // empty: qualities are not being exposed on iOS
103
- //entry[PROP_ACTIVE_QUALITY] = // undefined: qualities are not being exposed on iOS
104
- //entry[PROP_TARGET_QUALITY] = // undefined: qualities are not being exposed on iOS
105
- audioTrackEntries.append(entry)
111
+ if let audioTrack: AudioTrack = audioTracks.get(i) as? AudioTrack {
112
+ audioTrackEntries.append(THEOplayerRCTTrackMetadataAggregator.aggregatedAudioTrackInfo(audioTrack: audioTrack))
113
+ }
106
114
  }
107
115
  return audioTrackEntries
108
116
  }
109
-
110
- private class func aggregatedVideoTrackListInfo(videoTracks: VideoTrackList) -> [[String:Any]] {
111
- var videoTrackEntries:[[String:Any]] = []
112
- guard videoTracks.count > 0 else {
113
- return videoTrackEntries
114
- }
115
- for i in 0...videoTracks.count-1 {
116
- let videoTrack: MediaTrack = videoTracks.get(i)
117
- var entry: [String:Any] = [:]
118
- entry[PROP_ID] = videoTrack.id
119
- entry[PROP_UID] = videoTrack.uid
120
- entry[PROP_KIND] = videoTrack.kind
121
- entry[PROP_LANGUAGE] = videoTrack.language
122
- entry[PROP_LABEL] = videoTrack.label
123
- entry[PROP_QUALITIES] = [] // empty: qualities are not being exposed on iOS
124
- //entry[PROP_ACTIVE_QUALITY] = // undefined: qualities are not being exposed on iOS
125
- //entry[PROP_TARGET_QUALITY] = // undefined: qualities are not being exposed on iOS
126
- videoTrackEntries.append(entry)
127
- }
128
- return videoTrackEntries
129
- }
130
-
131
- private class func selectedTextTrack(textTracks: TextTrackList) -> Int {
132
- guard textTracks.count > 0 else {
133
- return 0
134
- }
135
- for i in 0...textTracks.count-1 {
136
- let textTrack: TextTrack = textTracks.get(i)
137
- if textTrack.mode == TextTrackMode.showing {
138
- return textTrack.uid
139
- }
140
- }
141
- return 0
117
+
118
+ class func aggregatedAudioTrackInfo(audioTrack: AudioTrack) -> [String:Any] {
119
+ var entry: [String:Any] = [:]
120
+ entry[PROP_ID] = audioTrack.id
121
+ entry[PROP_UID] = audioTrack.uid
122
+ entry[PROP_KIND] = audioTrack.kind
123
+ entry[PROP_LANGUAGE] = audioTrack.language
124
+ entry[PROP_LABEL] = audioTrack.label
125
+ entry[PROP_QUALITIES] = [] // empty: qualities are not being exposed on iOS
126
+ //entry[PROP_ACTIVE_QUALITY] = // undefined: qualities are not being exposed on iOS
127
+ //entry[PROP_TARGET_QUALITY] = // undefined: qualities are not being exposed on iOS
128
+ return entry
142
129
  }
143
-
130
+
144
131
  private class func selectedAudioTrack(audioTracks: AudioTrackList) -> Int {
145
132
  guard audioTracks.count > 0 else {
146
133
  return 0
@@ -154,6 +141,33 @@ class THEOplayerRCTMetadataAggregator {
154
141
  return 0
155
142
  }
156
143
 
144
+ // MARK: VIDEOTRACKS
145
+ private class func aggregatedVideoTrackListInfo(videoTracks: VideoTrackList) -> [[String:Any]] {
146
+ var videoTrackEntries:[[String:Any]] = []
147
+ guard videoTracks.count > 0 else {
148
+ return videoTrackEntries
149
+ }
150
+ for i in 0...videoTracks.count-1 {
151
+ if let videoTrack: VideoTrack = videoTracks.get(i) as? VideoTrack {
152
+ videoTrackEntries.append(THEOplayerRCTTrackMetadataAggregator.aggregatedVideoTrackInfo(videoTrack: videoTrack))
153
+ }
154
+ }
155
+ return videoTrackEntries
156
+ }
157
+
158
+ class func aggregatedVideoTrackInfo(videoTrack: VideoTrack) -> [String:Any] {
159
+ var entry: [String:Any] = [:]
160
+ entry[PROP_ID] = videoTrack.id
161
+ entry[PROP_UID] = videoTrack.uid
162
+ entry[PROP_KIND] = videoTrack.kind
163
+ entry[PROP_LANGUAGE] = videoTrack.language
164
+ entry[PROP_LABEL] = videoTrack.label
165
+ entry[PROP_QUALITIES] = [] // empty: qualities are not being exposed on iOS
166
+ //entry[PROP_ACTIVE_QUALITY] = // undefined: qualities are not being exposed on iOS
167
+ //entry[PROP_TARGET_QUALITY] = // undefined: qualities are not being exposed on iOS
168
+ return entry
169
+ }
170
+
157
171
  private class func selectedVideoTrack(videoTracks: VideoTrackList) -> Int {
158
172
  guard videoTracks.count > 0 else {
159
173
  return 0