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
@@ -3,38 +3,53 @@
3
3
  import Foundation
4
4
  import UIKit
5
5
  import THEOplayerSDK
6
+
7
+ #if CHROMECAST
8
+ import GoogleCast
9
+ #endif
6
10
 
7
11
  class THEOplayerRCTView: UIView {
8
12
  // MARK: Members
9
13
  private var player: THEOplayer?
10
14
  private var mainEventHandler: THEOplayerRCTViewMainEventHandler
11
15
  private var textTrackEventHandler: THEOplayerRCTViewTextTrackEventHandler
16
+ private var mediaTrackEventHandler: THEOplayerRCTViewMediaTrackEventHandler
12
17
  private var adEventHandler: THEOplayerRCTViewAdEventHandler
18
+ private var castEventHandler: THEOplayerRCTViewCastEventHandler
13
19
 
14
20
  // MARK: Bridged props
15
21
  private var src: SourceDescription?
16
22
  private var license: String?
17
23
  private var licenseUrl: String?
18
24
  private var chromeless: Bool = true
19
- private var adSUIEnabled: Bool = true
20
- private var adPreloadType: THEOplayerSDK.AdPreloadType = THEOplayerSDK.AdPreloadType.MIDROLL_AND_POSTROLL
21
- private var googleImaUsesNativeIma: Bool = true
22
25
  private var config: THEOplayerConfiguration?
23
- private var paused: Bool = false
24
- private var muted: Bool = true
26
+ private var paused: Bool = true
27
+ private var muted: Bool = false
25
28
  private var playbackRate: Double = 1.0
26
29
  private var selectedTextTrackUid: Int = 0
27
30
  private var selectedVideoTrackUid: Int = 0
28
31
  private var selectedAudioTrackUid: Int = 0
29
32
  private var seek: Double? = nil // in msec
30
33
  private var fullscreen: Bool = false
34
+ private var chromecastReceiverApplicationId: String?
35
+
36
+ #if os(iOS)
37
+ private var castStrategy: THEOplayerSDK.CastStrategy = THEOplayerSDK.CastStrategy.manual
38
+ #endif
39
+ #if os(iOS) && ADS && (GOOGLE_IMA || GOOGLE_DAI)
40
+ private var adSUIEnabled: Bool = true
41
+ private var googleImaUsesNativeIma: Bool = true
42
+ private var adPreloadType: THEOplayerSDK.AdPreloadType = .MIDROLL_AND_POSTROLL
43
+ #endif
31
44
 
32
45
  // MARK: - Initialisation / view setup
33
46
  init() {
34
47
  // create event handlers to maintain event props
35
48
  self.mainEventHandler = THEOplayerRCTViewMainEventHandler()
36
49
  self.textTrackEventHandler = THEOplayerRCTViewTextTrackEventHandler()
50
+ self.mediaTrackEventHandler = THEOplayerRCTViewMediaTrackEventHandler()
37
51
  self.adEventHandler = THEOplayerRCTViewAdEventHandler()
52
+ self.castEventHandler = THEOplayerRCTViewCastEventHandler()
38
53
 
39
54
  super.init(frame: .zero)
40
55
  }
@@ -42,7 +57,10 @@ class THEOplayerRCTView: UIView {
42
57
  func destroy() {
43
58
  self.mainEventHandler.destroy()
44
59
  self.textTrackEventHandler.destroy()
60
+ self.mediaTrackEventHandler.destroy()
45
61
  self.adEventHandler.destroy()
62
+ self.castEventHandler.destroy()
63
+
46
64
  self.player?.destroy()
47
65
  self.player = nil
48
66
  if DEBUG_THEOPLAYER_INTERACTION { print("[NATIVE] THEOplayer instance destroyed.") }
@@ -54,6 +72,15 @@ class THEOplayerRCTView: UIView {
54
72
  }
55
73
  return player.ads
56
74
  }
75
+
76
+ #if os(iOS)
77
+ func cast() -> Cast? {
78
+ guard let player = self.player else {
79
+ return nil
80
+ }
81
+ return player.cast
82
+ }
83
+ #endif
57
84
 
58
85
  required init?(coder aDecoder: NSCoder) {
59
86
  fatalError("[NATIVE] init(coder:) has not been implemented")
@@ -95,21 +122,29 @@ class THEOplayerRCTView: UIView {
95
122
  return
96
123
  }
97
124
 
98
- // reset player for new source
99
- if self.player != nil {
125
+ var isCasting = false
126
+ #if os(iOS)
127
+ isCasting = self.player?.cast?.casting ?? false // TO FIX: remove 'isCasting' workaround
128
+ #endif
129
+
130
+ if !isCasting || self.player == nil {
100
131
  self.player?.destroy()
101
132
  self.player = nil
102
- }
103
- DispatchQueue.main.async {
104
- self.initPlayer()
105
- if let player = self.player {
106
- // couple player instance to event handlers
107
- self.mainEventHandler.setPlayer(player)
108
- self.textTrackEventHandler.setPlayer(player)
109
- self.adEventHandler.setPlayer(player)
110
- // couple player instance to view
111
- player.addAsSubview(of: self)
133
+ DispatchQueue.main.async {
134
+ self.initPlayer()
135
+ if let player = self.player {
136
+ // couple player instance to event handlers
137
+ self.mainEventHandler.setPlayer(player)
138
+ self.textTrackEventHandler.setPlayer(player)
139
+ self.mediaTrackEventHandler.setPlayer(player)
140
+ self.adEventHandler.setPlayer(player)
141
+ self.castEventHandler.setPlayer(player)
142
+ // couple player instance to view
143
+ player.addAsSubview(of: self)
144
+ }
145
+ self.syncAllPlayerProps()
112
146
  }
147
+ } else {
113
148
  self.syncAllPlayerProps()
114
149
  }
115
150
  }
@@ -118,6 +153,7 @@ class THEOplayerRCTView: UIView {
118
153
  if DEBUG_THEOPLAYER_INTERACTION { print("[NATIVE] 'lazy' init THEOplayer instance") }
119
154
  #if os(tvOS)
120
155
  self.player = THEOplayer(configuration: THEOplayerConfiguration(chromeless: self.chromeless,
156
+ ads: self.initAdsConfiguration(),
121
157
  license: self.license,
122
158
  licenseUrl: self.licenseUrl,
123
159
  pip: nil))
@@ -128,24 +164,48 @@ class THEOplayerRCTView: UIView {
128
164
  cssPaths: cssPaths,
129
165
  pip: nil,
130
166
  ads: self.initAdsConfiguration(),
167
+ cast: self.initCastConfiguration(),
131
168
  license: self.license,
132
169
  licenseUrl: self.licenseUrl))
133
170
  #endif
134
171
  }
135
-
172
+
136
173
  private func initAdsConfiguration() -> AdsConfiguration? {
137
- #if ADS && (GOOGLE_IMA || GOOGLE_DAI)
138
- let googleIMAConfiguration = GoogleIMAConfiguration()
174
+ #if os(iOS) && ADS && (GOOGLE_IMA || GOOGLE_DAI)
175
+ // NOTE: GoogleIMAAdsConfiguration, GoogleDAIAdsConfigurationBuilder, GoogleDAIAdsConfigurationBuilder require iOS SDK 4.5.1 or higher
176
+ let googleIMAAdsConfiguration = GoogleIMAAdsConfiguration()
177
+ googleIMAAdsConfiguration.useNativeIma = self.googleImaUsesNativeIma
178
+ googleIMAAdsConfiguration.disableUI = !self.adSUIEnabled
179
+ let daiBuilder = GoogleDAIAdsConfigurationBuilder()
180
+ daiBuilder.disableUI = !self.adSUIEnabled
181
+ daiBuilder.enableBackgroundPlayback = true
182
+ let googleDaiAdsConfiguration = daiBuilder.build()
183
+ return AdsConfiguration(showCountdown: self.adSUIEnabled,
184
+ preload: self.adPreloadType,
185
+ googleIma: googleIMAAdsConfiguration,
186
+ googleDai: googleDaiAdsConfiguration)
187
+
188
+ // For lower iOS SDK versions replace the above with:
189
+ /*let googleIMAConfiguration = GoogleIMAConfiguration()
139
190
  googleIMAConfiguration.useNativeIma = self.googleImaUsesNativeIma
140
191
  googleIMAConfiguration.disableUI = !self.adSUIEnabled
141
192
  return AdsConfiguration(showCountdown: self.adSUIEnabled,
142
193
  preload: self.adPreloadType,
143
- googleImaConfiguration: googleIMAConfiguration)
194
+ googleImaConfiguration: googleIMAConfiguration)*/
195
+
196
+ #elseif os(tvOS) && ADS && GOOGLE_IMA
197
+ return AdsConfiguration()
144
198
  #else
145
199
  return nil
146
200
  #endif
147
-
148
201
  }
202
+
203
+ #if os(iOS)
204
+ private func initCastConfiguration() -> CastConfiguration? {
205
+ // prepare the config
206
+ return CastConfiguration(strategy: self.castStrategy)
207
+ }
208
+ #endif
149
209
 
150
210
  private func syncPlayerSrc() {
151
211
  // set sourceDescription on player
@@ -161,6 +221,7 @@ class THEOplayerRCTView: UIView {
161
221
  self.license = configDict["license"] as? String
162
222
  self.licenseUrl = configDict["licenseUrl"] as? String
163
223
  self.chromeless = configDict["chromeless"] as? Bool ?? true
224
+ #if os(iOS) && ADS && (GOOGLE_IMA || GOOGLE_DAI)
164
225
  if let adsConfig = configDict["ads"] as? NSDictionary {
165
226
  self.adSUIEnabled = adsConfig["uiEnabled"] as? Bool ?? true
166
227
  if let adPreloadType = adsConfig["preload"] as? String {
@@ -170,6 +231,27 @@ class THEOplayerRCTView: UIView {
170
231
  self.googleImaUsesNativeIma = googleImaConfiguration["useNativeIma"] as? Bool ?? true
171
232
  }
172
233
  }
234
+ #endif
235
+ #if os(iOS)
236
+ if let castConfig = configDict["cast"] as? NSDictionary {
237
+ if let castStrategy = castConfig["strategy"] as? String {
238
+ switch castStrategy {
239
+ case "auto":
240
+ self.castStrategy = THEOplayerSDK.CastStrategy.auto
241
+ case "manual":
242
+ self.castStrategy = THEOplayerSDK.CastStrategy.manual
243
+ case "disabled":
244
+ self.castStrategy = THEOplayerSDK.CastStrategy.disabled
245
+ default :
246
+ self.castStrategy = THEOplayerSDK.CastStrategy.manual
247
+ }
248
+ }
249
+ if let chromecastConfig = castConfig["chromecast"] as? NSDictionary,
250
+ let castReceiverApplicationId = chromecastConfig["appID"] as? String {
251
+ self.chromecastReceiverApplicationId = castReceiverApplicationId
252
+ }
253
+ }
254
+ #endif
173
255
  if DEBUG_PROP_UPDATES { print("[NATIVE] config prop updated.") }
174
256
  }
175
257
 
@@ -475,6 +557,20 @@ class THEOplayerRCTView: UIView {
475
557
  if DEBUG_PROP_UPDATES { print("[NATIVE] nativeTextTrackEvent prop set.") }
476
558
  }
477
559
 
560
+ // MARK: - Listener based MEDIATRACK event bridging
561
+
562
+ @objc(setOnNativeMediaTrackListEvent:)
563
+ func setOnNativeMediaTrackListEvent(nativeMediaTrackListEvent: @escaping RCTDirectEventBlock) {
564
+ self.mediaTrackEventHandler.onNativeMediaTrackListEvent = nativeMediaTrackListEvent
565
+ if DEBUG_PROP_UPDATES { print("[NATIVE] nativeMediaTrackListEvent prop set.") }
566
+ }
567
+
568
+ @objc(setOnNativeMediaTrackEvent:)
569
+ func setOnNativeMediaTrackEvent(nativeMediaTrackEvent: @escaping RCTDirectEventBlock) {
570
+ self.mediaTrackEventHandler.onNativeMediaTrackEvent = nativeMediaTrackEvent
571
+ if DEBUG_PROP_UPDATES { print("[NATIVE] nativeMediaTrackEvent prop set.") }
572
+ }
573
+
478
574
  // MARK: - Listener based AD event bridging
479
575
 
480
576
  @objc(setOnNativeAdEvent:)
@@ -482,4 +578,12 @@ class THEOplayerRCTView: UIView {
482
578
  self.adEventHandler.onNativeAdEvent = nativeAdEvent
483
579
  if DEBUG_PROP_UPDATES { print("[NATIVE] nativeAdEvent prop set.") }
484
580
  }
581
+
582
+ // MARK: - Listener based CAST event bridging
583
+
584
+ @objc(setOnNativeCastEvent:)
585
+ func setOnNativeCastEvent(nativeCastEvent: @escaping RCTDirectEventBlock) {
586
+ self.castEventHandler.onNativeCastEvent = nativeCastEvent
587
+ if DEBUG_PROP_UPDATES { print("[NATIVE] nativeCastEvent prop set.") }
588
+ }
485
589
  }
@@ -37,9 +37,7 @@ class THEOplayerRCTViewAdEventHandler {
37
37
  // MARK: - destruction
38
38
  func destroy() {
39
39
  // dettach listeners
40
- #if ADS && (GOOGLE_IMA || GOOLGE_DAI)
41
40
  self.dettachListeners()
42
- #endif
43
41
  }
44
42
 
45
43
  // MARK: - player setup / breakdown
@@ -47,9 +45,7 @@ class THEOplayerRCTViewAdEventHandler {
47
45
  self.player = player;
48
46
 
49
47
  // attach listeners
50
- #if ADS && (GOOGLE_IMA || GOOLGE_DAI)
51
48
  self.attachListeners()
52
- #endif
53
49
  }
54
50
 
55
51
  // MARK: - attach/dettach Listeners
@@ -57,7 +53,8 @@ class THEOplayerRCTViewAdEventHandler {
57
53
  guard let player = self.player else {
58
54
  return
59
55
  }
60
-
56
+
57
+ #if ADS && (GOOGLE_IMA || GOOGLE_DAI)
61
58
  // AD_BEGIN
62
59
  self.adBeginListener = player.ads.addEventListener(type: AdsEventTypes.AD_BEGIN) { [weak self] event in
63
60
  if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received AD_BEGIN event from THEOplayer Ads") }
@@ -174,6 +171,8 @@ class THEOplayerRCTViewAdEventHandler {
174
171
  }
175
172
  }
176
173
  if DEBUG_EVENTHANDLER { print("[NATIVE] AdThirdQuartile listener attached to THEOplayer.ads") }
174
+ #endif
175
+
177
176
  }
178
177
 
179
178
  private func dettachListeners() {
@@ -181,6 +180,7 @@ class THEOplayerRCTViewAdEventHandler {
181
180
  return
182
181
  }
183
182
 
183
+ #if ADS && (GOOGLE_IMA || GOOGLE_DAI)
184
184
  // AD_BEGIN
185
185
  if let adBeginListener = self.adBeginListener {
186
186
  player.ads.removeEventListener(type: AdsEventTypes.AD_BEGIN, listener: adBeginListener)
@@ -234,5 +234,7 @@ class THEOplayerRCTViewAdEventHandler {
234
234
  player.ads.removeEventListener(type: AdsEventTypes.AD_LOADED, listener: adLoadedListener)
235
235
  if DEBUG_EVENTHANDLER { print("[NATIVE] adLoadedListener listener dettached from THEOplayer.ads") }
236
236
  }
237
+ #endif
238
+
237
239
  }
238
240
  }
@@ -0,0 +1,124 @@
1
+ // THEOplayerRCTViewCastEventHandler.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+
6
+ let CAST_EVENT_PROP_TYPE: String = "type"
7
+ let CAST_EVENT_PROP_STATE: String = "state"
8
+ let CAST_EVENT_PROP_ERROR: String = "error"
9
+ let CAST_EVENT_PROP_ERROR_CODE: String = "errorCode"
10
+ let CAST_EVENT_PROP_ERROR_DESCRIPTION: String = "description"
11
+
12
+ let EVENT_TYPE_CHROMECAST_STATE_CHANGE: String = "chromecaststatechange"
13
+ let EVENT_TYPE_CHROMECAST_ERROR: String = "chromecasterror"
14
+ let EVENT_TYPE_AIRPLAY_STATE_CHANGE: String = "airplaystatechange"
15
+
16
+ class THEOplayerRCTViewCastEventHandler {
17
+ // MARK: Members
18
+ private weak var player: THEOplayer?
19
+
20
+ // MARK: Events
21
+ var onNativeCastEvent: RCTDirectEventBlock?
22
+
23
+ // MARK: Cast Listeners
24
+ private var chromecastStateChangeListener: EventListener?
25
+ private var chromecastErrorListener: EventListener?
26
+ private var airplayStateChangeListener: EventListener?
27
+
28
+
29
+ // MARK: - destruction
30
+ func destroy() {
31
+ // dettach listeners
32
+ self.dettachListeners()
33
+ }
34
+
35
+ // MARK: - player setup / breakdown
36
+ func setPlayer(_ player: THEOplayer) {
37
+ self.player = player;
38
+
39
+ // attach listeners
40
+ self.attachListeners()
41
+ }
42
+
43
+ // MARK: - attach/dettach Listeners
44
+ private func attachListeners() {
45
+ guard let player = self.player else {
46
+ return
47
+ }
48
+
49
+ #if os(iOS) && CHROMECAST
50
+ // CHROMECAST STATE_CHANGE
51
+ self.chromecastStateChangeListener = player.cast?.chromecast?.addEventListener(type: ChromecastEventTypes.STATE_CHANGE) { [weak self] event in
52
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received Chromecast STATE_CHANGE event from THEOplayer cast.chromecast") }
53
+ if let forwardedCastEvent = self?.onNativeCastEvent {
54
+ let newCastState = event.state._rawValue
55
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] New Chromecast state: \(newCastState)") }
56
+ forwardedCastEvent([
57
+ CAST_EVENT_PROP_TYPE: EVENT_TYPE_CHROMECAST_STATE_CHANGE,
58
+ CAST_EVENT_PROP_STATE: newCastState
59
+ ])
60
+ }
61
+ }
62
+ if DEBUG_EVENTHANDLER { print("[NATIVE] Chromecast StateChange listener attached to THEOplayer cast.chromecast") }
63
+
64
+ // CHROMECAST ERROR
65
+ self.chromecastErrorListener = player.cast?.chromecast?.addEventListener(type: ChromecastEventTypes.ERROR) { [weak self] event in
66
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received Chromecast ERROR event from THEOplayer cast.chromecast") }
67
+ if let forwardedCastEvent = self?.onNativeCastEvent {
68
+ let error = event.error
69
+ forwardedCastEvent([
70
+ CAST_EVENT_PROP_TYPE: EVENT_TYPE_CHROMECAST_ERROR,
71
+ CAST_EVENT_PROP_ERROR: [
72
+ CAST_EVENT_PROP_ERROR_CODE: error.errorCode._rawValue,
73
+ CAST_EVENT_PROP_ERROR_DESCRIPTION: error.description ?? ""
74
+ ]
75
+ ])
76
+ }
77
+ }
78
+ if DEBUG_EVENTHANDLER { print("[NATIVE] Chromecast Error listener attached to THEOplayer cast.chromecast") }
79
+ #endif
80
+
81
+ #if os(iOS)
82
+ // AIRPLAY STATE_CHANGE
83
+ self.airplayStateChangeListener = player.cast?.airPlay?.addEventListener(type: AirPlayEventTypes.STATE_CHANGE) { [weak self] event in
84
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received Airplay STATE_CHANGE event from THEOplayer cast.airplay") }
85
+ if let forwardedCastEvent = self?.onNativeCastEvent,
86
+ let castState = event.state {
87
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] New Airplay state: \(castState)") }
88
+ forwardedCastEvent([
89
+ CAST_EVENT_PROP_TYPE: EVENT_TYPE_AIRPLAY_STATE_CHANGE,
90
+ CAST_EVENT_PROP_STATE: castState._rawValue
91
+ ])
92
+ }
93
+ }
94
+ if DEBUG_EVENTHANDLER { print("[NATIVE] Airplay StateChange listener attached to THEOplayer cast.airplay") }
95
+ #endif
96
+ }
97
+
98
+
99
+ private func dettachListeners() {
100
+ guard let player = self.player else {
101
+ return
102
+ }
103
+
104
+ #if os(iOS) && CHROMECAST
105
+ // CHROMECAST STATE_CHANGE
106
+ if let chromecastStateChangeListener = self.chromecastStateChangeListener {
107
+ player.cast?.chromecast?.removeEventListener(type: ChromecastEventTypes.STATE_CHANGE, listener: chromecastStateChangeListener)
108
+ if DEBUG_EVENTHANDLER { print("[NATIVE] Chromecast StateChange listener dettached from THEOplayer cast.chromecast") }
109
+ }
110
+ if let chromecastErrorListener = self.chromecastErrorListener {
111
+ player.cast?.chromecast?.removeEventListener(type: ChromecastEventTypes.ERROR, listener: chromecastErrorListener)
112
+ if DEBUG_EVENTHANDLER { print("[NATIVE] Chromecast Error listener dettached from THEOplayer cast.chromecast") }
113
+ }
114
+ #endif
115
+
116
+ #if os(iOS)
117
+ // AIRPLAY STATE_CHANGE
118
+ if let airplayStateChangeListener = self.airplayStateChangeListener {
119
+ player.cast?.airPlay?.removeEventListener(type: AirPlayEventTypes.STATE_CHANGE, listener: airplayStateChangeListener)
120
+ if DEBUG_EVENTHANDLER { print("[NATIVE] Airplay StateChange listener dettached from THEOplayer cast.airplay") }
121
+ }
122
+ #endif
123
+ }
124
+ }
@@ -242,7 +242,7 @@ class THEOplayerRCTViewMainEventHandler {
242
242
  self.loadedMetadataListener = player.addEventListener(type: PlayerEventTypes.LOADED_META_DATA) { [weak self] event in
243
243
  if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received LOADED_META_DATA event from THEOplayer") }
244
244
  if let forwardedLoadedMetadataEvent = self?.onNativeLoadedMetadata {
245
- let metadata = THEOplayerRCTMetadataAggregator.aggregateMetadata(player: player)
245
+ let metadata = THEOplayerRCTTrackMetadataAggregator.aggregateTrackMetadata(player: player)
246
246
  print(metadata)
247
247
  forwardedLoadedMetadataEvent(metadata)
248
248
  }
@@ -0,0 +1,185 @@
1
+ // THEOplayerRCTViewMediaTrackEventHandler.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+
6
+ class THEOplayerRCTViewMediaTrackEventHandler {
7
+ // MARK: Members
8
+ private weak var player: THEOplayer?
9
+
10
+ // MARK: Events
11
+ var onNativeMediaTrackListEvent: RCTDirectEventBlock?
12
+ var onNativeMediaTrackEvent: RCTDirectEventBlock? // currently not in use on iOS THEOplayerSDK
13
+
14
+ // MARK: mediaTrackList Listeners
15
+ private var audioAddTrackListener: EventListener?
16
+ private var audioRemoveTrackListener: EventListener?
17
+ private var audioChangeTrackListener: EventListener?
18
+ private var videoAddTrackListener: EventListener?
19
+ private var videoRemoveTrackListener: EventListener?
20
+ private var videoChangeTrackListener: EventListener?
21
+
22
+ // MARK: mediaTrack listeners (attached dynamically to new mediatracks)
23
+ private var audioChangeTrackListeners: [Int:EventListener] = [:]
24
+ private var videoChangeTrackListeners: [Int:EventListener] = [:]
25
+
26
+
27
+ // MARK: - destruction
28
+ func destroy() {
29
+ // dettach listeners
30
+ self.dettachListeners()
31
+ }
32
+
33
+ // MARK: - player setup / breakdown
34
+ func setPlayer(_ player: THEOplayer) {
35
+ self.player = player;
36
+
37
+ // attach listeners
38
+ self.attachListeners()
39
+ }
40
+
41
+ // MARK: - attach/dettach mediaTrackList Listeners
42
+ private func attachListeners() {
43
+ guard let player = self.player else {
44
+ return
45
+ }
46
+
47
+ // AUDIO ADD_TRACK
48
+ self.audioAddTrackListener = player.audioTracks.addEventListener(type: AudioTrackListEventTypes.ADD_TRACK) { [weak self] event in
49
+ guard let welf = self else { return }
50
+ if let forwardedMediaTrackListEvent = welf.onNativeMediaTrackListEvent,
51
+ let audioTrack = event.track as? AudioTrack {
52
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received ADD_TRACK event from THEOplayer audioTrack list: trackUid = \(audioTrack.uid)") }
53
+ // trigger tracklist event
54
+ forwardedMediaTrackListEvent([
55
+ "track" : THEOplayerRCTTrackMetadataAggregator.aggregatedAudioTrackInfo(audioTrack: audioTrack),
56
+ "type" : TrackListEventType.ADD_TRACK.rawValue,
57
+ "trackType": MediaTrackType.AUDIO.rawValue
58
+ ])
59
+ }
60
+ }
61
+ if DEBUG_EVENTHANDLER { print("[NATIVE] AddTrack listener attached to THEOplayer audioTrack list") }
62
+
63
+ // AUDIO REMOVE_TRACK
64
+ self.audioRemoveTrackListener = player.audioTracks.addEventListener(type: AudioTrackListEventTypes.REMOVE_TRACK) { [weak self] event in
65
+ guard let welf = self else { return }
66
+ if let forwardedMediaTrackListEvent = welf.onNativeMediaTrackListEvent,
67
+ let audioTrack = event.track as? AudioTrack {
68
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received REMOVE_TRACK event from THEOplayer audioTrack list: trackUid = \(audioTrack.uid)") }
69
+ // trigger tracklist event
70
+ forwardedMediaTrackListEvent([
71
+ "track" : THEOplayerRCTTrackMetadataAggregator.aggregatedAudioTrackInfo(audioTrack: audioTrack),
72
+ "type" : TrackListEventType.REMOVE_TRACK.rawValue,
73
+ "trackType": MediaTrackType.AUDIO.rawValue
74
+ ])
75
+ }
76
+ }
77
+ if DEBUG_EVENTHANDLER { print("[NATIVE] RemoveTrack listener attached to THEOplayer audioTrack list") }
78
+
79
+ // AUDIO CHANGE
80
+ self.audioChangeTrackListener = player.audioTracks.addEventListener(type: AudioTrackListEventTypes.CHANGE) { [weak self] event in
81
+ guard let welf = self else { return }
82
+ if let forwardedMediaTrackListEvent = welf.onNativeMediaTrackListEvent,
83
+ let audioTrack = event.track as? AudioTrack {
84
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received CHANGE event from THEOplayer audioTrack list: trackUid = \(audioTrack.uid)") }
85
+ // trigger tracklist event
86
+ forwardedMediaTrackListEvent([
87
+ "track" : THEOplayerRCTTrackMetadataAggregator.aggregatedAudioTrackInfo(audioTrack: audioTrack),
88
+ "type" : TrackListEventType.CHANGE_TRACK.rawValue,
89
+ "trackType": MediaTrackType.AUDIO.rawValue
90
+ ])
91
+ }
92
+ }
93
+ if DEBUG_EVENTHANDLER { print("[NATIVE] ChangeTrack listener attached to THEOplayer audioTrack list") }
94
+
95
+ // VIDEO ADD_TRACK
96
+ self.videoAddTrackListener = player.videoTracks.addEventListener(type: VideoTrackListEventTypes.ADD_TRACK) { [weak self] event in
97
+ guard let welf = self else { return }
98
+ if let forwardedMediaTrackListEvent = welf.onNativeMediaTrackListEvent,
99
+ let videoTrack = event.track as? VideoTrack {
100
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received ADD_TRACK event from THEOplayer videoTrack list: trackUid = \(videoTrack.uid)") }
101
+ // trigger tracklist event
102
+ forwardedMediaTrackListEvent([
103
+ "track" : THEOplayerRCTTrackMetadataAggregator.aggregatedVideoTrackInfo(videoTrack: videoTrack),
104
+ "type" : TrackListEventType.ADD_TRACK.rawValue,
105
+ "trackType": MediaTrackType.VIDEO.rawValue
106
+ ])
107
+ }
108
+ }
109
+ if DEBUG_EVENTHANDLER { print("[NATIVE] AddTrack listener attached to THEOplayer videoTrack list") }
110
+
111
+ // VIDEO REMOVE_TRACK
112
+ self.videoRemoveTrackListener = player.videoTracks.addEventListener(type: VideoTrackListEventTypes.REMOVE_TRACK) { [weak self] event in
113
+ guard let welf = self else { return }
114
+ if let forwardedMediaTrackListEvent = welf.onNativeMediaTrackListEvent,
115
+ let videoTrack = event.track as? VideoTrack {
116
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received REMOVE_TRACK event from THEOplayer videoTrack list: trackUid = \(videoTrack.uid)") }
117
+ // trigger tracklist event
118
+ forwardedMediaTrackListEvent([
119
+ "track" : THEOplayerRCTTrackMetadataAggregator.aggregatedVideoTrackInfo(videoTrack: videoTrack),
120
+ "type" : TrackListEventType.REMOVE_TRACK.rawValue,
121
+ "trackType": MediaTrackType.VIDEO.rawValue
122
+ ])
123
+ }
124
+ }
125
+ if DEBUG_EVENTHANDLER { print("[NATIVE] RemoveTrack listener attached to THEOplayer videoTrack list") }
126
+
127
+ // VIDEO CHANGE
128
+ self.videoChangeTrackListener = player.videoTracks.addEventListener(type: VideoTrackListEventTypes.CHANGE) { [weak self] event in
129
+ guard let welf = self else { return }
130
+ if let forwardedMediaTrackListEvent = welf.onNativeMediaTrackListEvent,
131
+ let videoTrack = event.track as? VideoTrack {
132
+ if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received CHANGE event from THEOplayer videoTrack list: trackUid = \(videoTrack.uid)") }
133
+ // trigger tracklist event
134
+ forwardedMediaTrackListEvent([
135
+ "track" : THEOplayerRCTTrackMetadataAggregator.aggregatedVideoTrackInfo(videoTrack: videoTrack),
136
+ "type" : TrackListEventType.CHANGE_TRACK.rawValue,
137
+ "trackType": MediaTrackType.VIDEO.rawValue
138
+ ])
139
+ }
140
+ }
141
+ if DEBUG_EVENTHANDLER { print("[NATIVE] ChangeTrack listener attached to THEOplayer audioTrack list") }
142
+ }
143
+
144
+ private func dettachListeners() {
145
+ guard let player = self.player else {
146
+ return
147
+ }
148
+
149
+ // AUDIO ADD_TRACK
150
+ if let audioAddTrackListener = self.audioAddTrackListener {
151
+ player.audioTracks.removeEventListener(type: AudioTrackListEventTypes.ADD_TRACK, listener: audioAddTrackListener)
152
+ if DEBUG_EVENTHANDLER { print("[NATIVE] AddTrack listener dettached from THEOplayer audioTrack list") }
153
+ }
154
+
155
+ // AUDIO REMOVE_TRACK
156
+ if let audioRemoveTrackListener = self.audioRemoveTrackListener {
157
+ player.audioTracks.removeEventListener(type: AudioTrackListEventTypes.REMOVE_TRACK, listener: audioRemoveTrackListener)
158
+ if DEBUG_EVENTHANDLER { print("[NATIVE] RemoveTrack listener dettached from THEOplayer audioTrack list") }
159
+ }
160
+
161
+ // AUDIO CHANGE
162
+ if let audioChangeTrackListener = self.audioChangeTrackListener {
163
+ player.audioTracks.removeEventListener(type: AudioTrackListEventTypes.CHANGE, listener: audioChangeTrackListener)
164
+ if DEBUG_EVENTHANDLER { print("[NATIVE] ChangeTrack listener dettached from THEOplayer audioTrack list") }
165
+ }
166
+
167
+ // VIDEO ADD_TRACK
168
+ if let videoAddTrackListener = self.videoAddTrackListener {
169
+ player.videoTracks.removeEventListener(type: VideoTrackListEventTypes.ADD_TRACK, listener: videoAddTrackListener)
170
+ if DEBUG_EVENTHANDLER { print("[NATIVE] AddTrack listener dettached from THEOplayer videoTrack list") }
171
+ }
172
+
173
+ // VIDEO REMOVE_TRACK
174
+ if let videoRemoveTrackListener = self.videoRemoveTrackListener {
175
+ player.videoTracks.removeEventListener(type: VideoTrackListEventTypes.REMOVE_TRACK, listener: videoRemoveTrackListener)
176
+ if DEBUG_EVENTHANDLER { print("[NATIVE] RemoveTrack listener dettached from THEOplayer videoTrack list") }
177
+ }
178
+
179
+ // VIDEO CHANGE
180
+ if let videoChangeTrackListener = self.videoChangeTrackListener {
181
+ player.videoTracks.removeEventListener(type: VideoTrackListEventTypes.CHANGE, listener: videoChangeTrackListener)
182
+ if DEBUG_EVENTHANDLER { print("[NATIVE] ChangeTrack listener dettached from THEOplayer videoTrack list") }
183
+ }
184
+ }
185
+ }