react-native-theoplayer 1.8.0 → 1.8.2

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 (28) hide show
  1. package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +3 -3
  2. package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +1 -0
  3. package/ios/{THEOplayerRCTViewMainEventHandler.swift → THEOplayerRCTMainEventHandler.swift} +1 -1
  4. package/ios/{THEOplayerRCTViewMediaTrackEventHandler.swift → THEOplayerRCTMediaTrackEventHandler.swift} +2 -2
  5. package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +19 -114
  6. package/ios/{THEOplayerRCTViewTextTrackEventHandler.swift → THEOplayerRCTTextTrackEventHandler.swift} +2 -2
  7. package/ios/THEOplayerRCTView.swift +33 -133
  8. package/ios/{THEOplayerRCTAdAggregator.swift → ads/THEOplayerRCTAdAggregator.swift} +1 -1
  9. package/ios/ads/THEOplayerRCTAdsAPI+DAI.swift +108 -0
  10. package/ios/{THEOplayerRCTAdsAPI.swift → ads/THEOplayerRCTAdsAPI.swift} +6 -96
  11. package/ios/{THEOplayerRCTViewAdEventHandler.swift → ads/THEOplayerRCTAdsEventHandler.swift} +3 -3
  12. package/ios/ads/THEOplayerRCTSourceDescriptionBuilder+Ads.swift +130 -0
  13. package/ios/ads/THEOplayerRCTView+Ads.swift +15 -0
  14. package/ios/ads/THEOplayerRCTView+AdsConfig.swift +82 -0
  15. package/ios/casting/THEOplayerRCTCastAPI+Airplay.swift +97 -0
  16. package/ios/casting/THEOplayerRCTCastAPI+Chromecast.swift +132 -0
  17. package/ios/casting/THEOplayerRCTCastAPI.swift +53 -0
  18. package/ios/{THEOplayerRCTViewCastEventHandler.swift → casting/THEOplayerRCTCastEventHandler.swift} +1 -1
  19. package/ios/casting/THEOplayerRCTView+CastConfig.swift +47 -0
  20. package/ios/casting/THEOplayerRCTView+Casting.swift +17 -0
  21. package/ios/custom/react-native-theoplayer_custom.podspec +6 -6
  22. package/package.json +1 -1
  23. package/react-native-theoplayer.podspec +1 -1
  24. package/ios/THEOplayerRCTCastAPI.swift +0 -275
  25. /package/ios/{THEOplayerRCTContentProtectionAPI.swift → contentprotection/THEOplayerRCTContentProtectionAPI.swift} +0 -0
  26. /package/ios/{THEOplayerRCTContentProtectionAggregator.swift → contentprotection/THEOplayerRCTContentProtectionAggregator.swift} +0 -0
  27. /package/ios/{THEOplayerRCTProxyContentProtectionIntegration.swift → contentprotection/THEOplayerRCTProxyContentProtectionIntegration.swift} +0 -0
  28. /package/ios/{THEOplayerRCTProxyContentProtectionIntegrationFactory.swift → contentprotection/THEOplayerRCTProxyContentProtectionIntegrationFactory.swift} +0 -0
@@ -10,7 +10,6 @@ import Foundation
10
10
  import UIKit
11
11
 
12
12
  let ERROR_CODE_ADS_ACCESS_FAILURE = "ads_access_failure"
13
- let ERROR_CODE_DAI_ACCESS_FAILURE = "dai_access_failure"
14
13
  let ERROR_CODE_ADS_GET_PLAYING_STATE_FAILED = "ads_get_playing_state_failure"
15
14
  let ERROR_CODE_ADS_GET_CURRENT_ADBREAK_FAILED = "ads_get_current_adbreak_failure"
16
15
  let ERROR_CODE_ADS_GET_CURRENT_ADBREAK_UNDEFINED = "ads_get_current_adbreak_undefined"
@@ -18,16 +17,11 @@ let ERROR_CODE_ADS_GET_CURRENT_ADS_FAILED = "ads_get_current_ads_failure"
18
17
  let ERROR_CODE_ADS_GET_CURRENT_ADS_UNDEFINED = "ads_get_current_ads_undefined"
19
18
  let ERROR_CODE_ADS_GET_SCHEDULED_ADBREAKS_FAILED = "ads_get_scheduled_adbreaks_failure"
20
19
  let ERROR_CODE_ADS_GET_SCHEDULED_ADBREAKS_UNDEFINED = "ads_get_scheduled_adbreaks_undefined"
21
- let ERROR_CODE_DAI_GET_SNAPBACK_FAILED = "dai_get_snapback_failed"
22
- let ERROR_CODE_DAI_GET_SNAPBACK_UNDEFINED = "dai_get_snapback_undefined"
23
-
24
20
  let ERROR_MESSAGE_ADS_ACCESS_FAILURE = "Could not access THEOplayer Ads Module"
25
- let ERROR_MESSAGE_DAI_ACCESS_FAILURE = "Could not access THEOplayer Ads DAI Module"
26
21
  let ERROR_MESSAGE_ADS_GET_CURRENT_ADBREAK_UNDEFINED = "Undefined adBreak object"
27
22
  let ERROR_MESSAGE_ADS_GET_CURRENT_ADS_UNDEFINED = "Undefined ads array"
28
23
  let ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE = "This functionality is not supported by the provided iOS SDK"
29
24
  let ERROR_MESSAGE_ADS_GET_SCHEDULED_ADBREAKS_UNDEFINED = "Undefined adbreaks array"
30
- let ERROR_MESSAGE_DAI_GET_SNAPBACK_UNDEFINED = "Undefined dai snapback"
31
25
 
32
26
  @objc(THEOplayerRCTAdsAPI)
33
27
  class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
@@ -41,7 +35,8 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
41
35
  return false
42
36
  }
43
37
 
44
- #if ADS && (GOOGLE_IMA || GOOGLE_DAI)
38
+ #if (GOOGLE_IMA || GOOGLE_DAI)
39
+
45
40
  @objc(skip:)
46
41
  func skip(_ node: NSNumber) -> Void {
47
42
 
@@ -158,14 +153,16 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
158
153
  let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
159
154
  if let adData = adDict as? [String:Any],
160
155
  let ads = theView.ads(),
161
- let adDescription = THEOplayerRCTSourceDescriptionBuilder.buildAdDescription(adData) {
156
+ let adDescription = THEOplayerRCTSourceDescriptionBuilder.buildSingleAdDescription(adData) {
162
157
  ads.schedule(adDescription: adDescription)
163
158
  } else {
164
159
  if DEBUG_ADS_API { print("[NATIVE] Could not schedule new ad.") }
165
160
  }
166
161
  }
167
162
  }
163
+
168
164
  #else
165
+
169
166
  @objc(skip:)
170
167
  func skip(_ node: NSNumber) -> Void {
171
168
  if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
@@ -202,94 +199,7 @@ class THEOplayerRCTAdsAPI: NSObject, RCTBridgeModule {
202
199
  if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
203
200
  return
204
201
  }
205
- #endif
206
-
207
- #if os(iOS) && ADS && GOOGLE_DAI
208
- @objc(daiSnapback:resolver:rejecter:)
209
- func daiSnapback(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
210
- DispatchQueue.main.async {
211
- let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
212
- if let ads = theView.ads(),
213
- let dai = ads.dai {
214
- dai.requestSnapBack { enabled, error in
215
- if let err = error {
216
- reject(ERROR_CODE_DAI_GET_SNAPBACK_FAILED, err.localizedDescription, error)
217
- if DEBUG_ADS_API { print("[NATIVE] Retrieving dai snapback status failed: \(err.localizedDescription)") }
218
- } else if let snapBack = enabled {
219
- resolve(snapBack)
220
- } else {
221
- reject(ERROR_CODE_DAI_GET_SNAPBACK_UNDEFINED, ERROR_MESSAGE_DAI_GET_SNAPBACK_UNDEFINED, nil)
222
- if DEBUG_ADS_API { print("[NATIVE] Retrieving dai snapback status failed.") }
223
- }
224
- }
225
- } else {
226
- reject(ERROR_CODE_DAI_ACCESS_FAILURE, ERROR_MESSAGE_DAI_ACCESS_FAILURE, nil)
227
- if DEBUG_ADS_API { print("[NATIVE] Could not retrieve dai snapback status (ads DAI module unavailable).") }
228
- }
229
- }
230
- }
231
-
232
- @objc(daiSetSnapback:enabled:)
233
- func daiSetSnapback(_ node: NSNumber, enabled: Bool) -> Void {
234
- DispatchQueue.main.async {
235
- let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
236
- if let ads = theView.ads(),
237
- let dai = ads.dai {
238
- dai.setSnapBack(enabled, completionHandler: nil)
239
- } else {
240
- if DEBUG_ADS_API { print("[NATIVE] Could not update dai snapback status (ads DAI module unavailable).") }
241
- }
242
- }
243
- }
244
202
 
245
- @objc(daiContentTimeForStreamTime:time:resolver:rejecter:)
246
- func daiContentTimeForStreamTime(_ node: NSNumber, timeValue: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
247
- DispatchQueue.main.async {
248
- let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
249
- if let ads = theView.ads(),
250
- let dai = ads.dai {
251
- let streamTime = timeValue.doubleValue * 0.001 // msec -> sec
252
- let contentTime = dai.contentTime(from: streamTime) * 1000.0 // sec -> msec
253
- resolve(contentTime)
254
- } else {
255
- reject(ERROR_CODE_DAI_ACCESS_FAILURE, ERROR_MESSAGE_DAI_ACCESS_FAILURE, nil)
256
- if DEBUG_ADS_API { print("[NATIVE] Could not convert stream time to content time (ads DAI module unavailable).") }
257
- }
258
- }
259
- }
260
-
261
- @objc(daiStreamTimeForContentTime:time:resolver:rejecter:)
262
- func daiStreamTimeForContentTime(_ node: NSNumber, timeValue: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
263
- DispatchQueue.main.async {
264
- let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
265
- if let ads = theView.ads(),
266
- let dai = ads.dai {
267
- let contentTime = timeValue.doubleValue * 0.001 // msec -> sec
268
- let streamTime = dai.streamTime(from: contentTime) * 1000.0 // sec -> msec
269
- resolve(streamTime)
270
- } else {
271
- reject(ERROR_CODE_DAI_ACCESS_FAILURE, ERROR_MESSAGE_DAI_ACCESS_FAILURE, nil)
272
- if DEBUG_ADS_API { print("[NATIVE] Could not convert content time to stream time (ads DAI module unavailable).") }
273
- }
274
- }
275
- }
276
- #else
277
- @objc(daiSnapback:resolver:rejecter:)
278
- func daiSnapback(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
279
- if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
280
- resolve(false)
281
- }
282
-
283
- @objc(daiContentTimeForStreamTime:time:resolver:rejecter:)
284
- func daiContentTimeForStreamTime(_ node: NSNumber, timeValue: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
285
- if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
286
- resolve(timeValue.doubleValue)
287
- }
288
-
289
- @objc(daiStreamTimeForContentTime:time:resolver:rejecter:)
290
- func daiStreamTimeForContentTime(_ node: NSNumber, timeValue: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
291
- if DEBUG_ADS_API { print(ERROR_MESSAGE_ADS_UNSUPPORTED_FEATURE) }
292
- resolve(timeValue.doubleValue)
293
- }
294
203
  #endif
204
+
295
205
  }
@@ -16,7 +16,7 @@ let EVENT_TYPE_AD_THIRD_QUARTILE: String = "adthirdquartile"
16
16
  let EVENT_TYPE_AD_MIDPOINT: String = "admidpoint"
17
17
  let EVENT_TYPE_AD_LOADED: String = "adloaded"
18
18
 
19
- class THEOplayerRCTViewAdEventHandler {
19
+ class THEOplayerRCTAdsEventHandler {
20
20
  // MARK: Members
21
21
  private weak var player: THEOplayer?
22
22
 
@@ -54,7 +54,7 @@ class THEOplayerRCTViewAdEventHandler {
54
54
  return
55
55
  }
56
56
 
57
- #if ADS && (GOOGLE_IMA || GOOGLE_DAI)
57
+ #if (GOOGLE_IMA || GOOGLE_DAI)
58
58
  // AD_BEGIN
59
59
  self.adBeginListener = player.ads.addEventListener(type: AdsEventTypes.AD_BEGIN) { [weak self] event in
60
60
  if DEBUG_THEOPLAYER_EVENTS { print("[NATIVE] Received AD_BEGIN event from THEOplayer Ads") }
@@ -180,7 +180,7 @@ class THEOplayerRCTViewAdEventHandler {
180
180
  return
181
181
  }
182
182
 
183
- #if ADS && (GOOGLE_IMA || GOOGLE_DAI)
183
+ #if (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)
@@ -0,0 +1,130 @@
1
+ // THEOplayerRCTSourceDescriptionBuilder.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+ import UIKit
6
+
7
+ let SD_PROP_ADS: String = "ads"
8
+
9
+ extension THEOplayerRCTSourceDescriptionBuilder {
10
+
11
+ /**
12
+ Builds a THEOplayer SourceDescription that can be passed as a source for the THEOplayer.
13
+ - returns: a THEOplayer TypedSource. In case of SSAI we support GoogleDAITypedSource with GoogleDAIVodConfiguration or GoogleDAILiveConfiguration
14
+ */
15
+ static func buildAdDescriptions(_ sourceData: NSDictionary) -> [AdDescription]? {
16
+ var adsDescriptions: [AdDescription]?
17
+
18
+ #if GOOGLE_IMA
19
+ if let ads = sourceData[SD_PROP_ADS] {
20
+ adsDescriptions = []
21
+ // case: array of ads objects
22
+ if let adsDataArray = ads as? [[String:Any]] {
23
+ for adsData in adsDataArray {
24
+ if let adDescription = THEOplayerRCTSourceDescriptionBuilder.buildSingleAdDescription(adsData) {
25
+ adsDescriptions?.append(adDescription)
26
+ } else {
27
+ if DEBUG_SOURCE_DESCRIPTION_BUIDER {
28
+ print("[NATIVE] Could not create THEOplayer GoogleImaAdDescription from adsData array")
29
+ }
30
+ return nil
31
+ }
32
+ }
33
+ }
34
+ // case: single ads object
35
+ else if let adsData = ads as? [String:Any] {
36
+ if let adDescription = THEOplayerRCTSourceDescriptionBuilder.buildSingleAdDescription(adsData) {
37
+ adsDescriptions?.append(adDescription)
38
+ } else {
39
+ if DEBUG_SOURCE_DESCRIPTION_BUIDER {
40
+ print("[NATIVE] Could not create THEOplayer GoogleImaAdDescription from adsData")
41
+ }
42
+ return nil
43
+ }
44
+ }
45
+ }
46
+ #endif
47
+
48
+ return adsDescriptions
49
+ }
50
+
51
+ /**
52
+ Creates a THEOplayer GoogleImaAdDescription. This requires an ads property in the RN source description.
53
+ - returns: a THEOplayer GoogleImaAdDescription
54
+ */
55
+ static func buildSingleAdDescription(_ adsData: [String:Any]) -> AdDescription? {
56
+ #if GOOGLE_IMA
57
+ if let integration = adsData[SD_PROP_INTEGRATION] as? String,
58
+ integration == AdIntegration.google_ima._rawValue {
59
+ // timeOffset can be Int or String: 10, "01:32:54.78", "1234.56", "start", "end", "10%", ...
60
+ let timeOffset = adsData[SD_PROP_TIME_OFFSET] as? String ?? String(adsData[SD_PROP_TIME_OFFSET] as? Int ?? 0)
61
+ var srcString: String?
62
+ if let sourcesData = adsData[SD_PROP_SOURCES] as? [String:Any] {
63
+ srcString = sourcesData[SD_PROP_SRC] as? String
64
+ } else if let sourcesData = adsData[SD_PROP_SOURCES] as? String {
65
+ srcString = sourcesData
66
+ }
67
+ if let src = srcString {
68
+ return GoogleImaAdDescription(src: src, timeOffset: timeOffset)
69
+ } else {
70
+ if DEBUG_SOURCE_DESCRIPTION_BUIDER { print("[NATIVE] AdDescription requires 'src' property in 'ads' description.") }
71
+ }
72
+ }
73
+ if DEBUG_SOURCE_DESCRIPTION_BUIDER { print("[NATIVE] We currently require and only support the 'google-ima' integration in the 'ads' description.") }
74
+ #endif
75
+
76
+ return nil
77
+ }
78
+
79
+ static func buildDAITypedSource(_ typedSourceData: [String:Any], contentProtection: MultiplatformDRMConfiguration?) -> TypedSource? {
80
+ #if GOOGLE_DAI
81
+ // check for alternative Google DAI SSAI
82
+ if let ssaiData = typedSourceData[SD_PROP_SSAI] as? [String:Any] {
83
+ if let integration = ssaiData[SD_PROP_INTEGRATION] as? String,
84
+ integration == SSAIIntegrationId.GoogleDAISSAIIntegrationID._rawValue {
85
+ if let availabilityType = ssaiData[SD_PROP_AVAILABILITY_TYPE] as? String {
86
+ // build a GoogleDAIConfiguration
87
+ var googleDaiConfig: GoogleDAIConfiguration?
88
+ let authToken = ssaiData[SD_PROP_AUTH_TOKEN] as? String
89
+ let streamActivityMonitorID = ssaiData[SD_PROP_STREAM_ACTIVITY_MONITOR_ID] as? String
90
+ let adTagParameters = ssaiData[SD_PROP_AD_TAG_PARAMETERS] as? [String:String]
91
+ let apiKey = ssaiData[SD_PROP_APIKEY] as? String ?? ""
92
+ switch availabilityType {
93
+ case StreamType.vod._rawValue:
94
+ if let videoId = ssaiData[SD_PROP_VIDEOID] as? String,
95
+ let contentSourceID = ssaiData[SD_PROP_CONTENT_SOURCE_ID] as? String {
96
+ googleDaiConfig = GoogleDAIVodConfiguration(videoID: videoId,
97
+ contentSourceID: contentSourceID,
98
+ apiKey: apiKey,
99
+ authToken: authToken,
100
+ streamActivityMonitorID: streamActivityMonitorID,
101
+ adTagParameters: adTagParameters)
102
+ }
103
+ case StreamType.live._rawValue:
104
+ if let assetKey = ssaiData[SD_PROP_ASSET_KEY] as? String {
105
+ googleDaiConfig = GoogleDAILiveConfiguration(assetKey: assetKey,
106
+ apiKey: apiKey,
107
+ authToken: authToken,
108
+ streamActivityMonitorID: streamActivityMonitorID,
109
+ adTagParameters: adTagParameters)
110
+ }
111
+ default:
112
+ if DEBUG_SOURCE_DESCRIPTION_BUIDER {
113
+ print("[NATIVE] THEOplayer ssai 'availabilityType' must be 'live' or 'vod'")
114
+ }
115
+ return nil
116
+ }
117
+ // when valid, create a GoogleDAITypedSource from the GoogleDAIConfiguration
118
+ if let config = googleDaiConfig {
119
+ return GoogleDAITypedSource(src: "", type: "application/x-mpegurl",
120
+ drm: contentProtection, ssai: config)
121
+ }
122
+ }
123
+ }
124
+ }
125
+ #endif
126
+
127
+ return nil
128
+ }
129
+
130
+ }
@@ -0,0 +1,15 @@
1
+ // THEOplayerRCTView+Ads.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+
6
+ extension THEOplayerRCTView {
7
+
8
+ func ads() -> Ads? {
9
+ guard let player = self.player else {
10
+ return nil
11
+ }
12
+ return player.ads
13
+ }
14
+
15
+ }
@@ -0,0 +1,82 @@
1
+ // THEOplayerRCTView+Ads.swift
2
+
3
+ import Foundation
4
+ import THEOplayerSDK
5
+
6
+ struct AdsConfig {
7
+ var adSUIEnabled: Bool = true
8
+ var googleImaUsesNativeIma: Bool = true
9
+ var adPreloadTypeString: String = "none"
10
+ }
11
+
12
+ #if os(iOS)
13
+
14
+ extension THEOplayerRCTView {
15
+
16
+ func parseAdsConfig(configDict: NSDictionary) {
17
+ if let adsConfig = configDict["ads"] as? NSDictionary {
18
+ self.adsConfig.adSUIEnabled = adsConfig["uiEnabled"] as? Bool ?? true
19
+ if let adPreloadType = adsConfig["preload"] as? String {
20
+ self.adsConfig.adPreloadTypeString = adPreloadType
21
+ }
22
+ if let googleImaConfiguration = adsConfig["googleImaConfiguration"] as? NSDictionary {
23
+ self.adsConfig.googleImaUsesNativeIma = googleImaConfiguration["useNativeIma"] as? Bool ?? true
24
+ }
25
+ }
26
+ }
27
+
28
+ #if (GOOGLE_IMA || GOOGLE_DAI)
29
+ func playerAdsConfiguration() -> AdsConfiguration? {
30
+ // NOTE: GoogleIMAAdsConfiguration, GoogleDAIAdsConfigurationBuilder, GoogleDAIAdsConfigurationBuilder require iOS SDK 4.5.1 or higher
31
+ let googleIMAAdsConfiguration = GoogleIMAAdsConfiguration()
32
+ googleIMAAdsConfiguration.useNativeIma = self.adsConfig.googleImaUsesNativeIma
33
+ googleIMAAdsConfiguration.disableUI = !self.adsConfig.adSUIEnabled
34
+ let daiBuilder = GoogleDAIAdsConfigurationBuilder()
35
+ daiBuilder.disableUI = !self.adsConfig.adSUIEnabled
36
+ daiBuilder.enableBackgroundPlayback = true
37
+ let googleDaiAdsConfiguration = daiBuilder.build()
38
+ return AdsConfiguration(showCountdown: self.adsConfig.adSUIEnabled,
39
+ preload: self.adPreloadType(),
40
+ googleIma: googleIMAAdsConfiguration,
41
+ googleDai: googleDaiAdsConfiguration)
42
+
43
+ // For lower iOS SDK versions replace the above with:
44
+ /*let googleIMAConfiguration = GoogleIMAConfiguration()
45
+ googleIMAConfiguration.useNativeIma = self.googleImaUsesNativeIma
46
+ googleIMAConfiguration.disableUI = !self.adSUIEnabled
47
+ return AdsConfiguration(showCountdown: self.adSUIEnabled,
48
+ preload: self.adPreloadType,
49
+ googleImaConfiguration: googleIMAConfiguration)*/
50
+ }
51
+
52
+ private func adPreloadType() -> THEOplayerSDK.AdPreloadType {
53
+ switch self.adsConfig.adPreloadTypeString {
54
+ case "midroll-and-postroll":
55
+ return THEOplayerSDK.AdPreloadType.MIDROLL_AND_POSTROLL
56
+ case "none":
57
+ return THEOplayerSDK.AdPreloadType.NONE
58
+ default :
59
+ return THEOplayerSDK.AdPreloadType.NONE
60
+ }
61
+ }
62
+ #else
63
+ func playerAdsConfiguration() -> AdsConfiguration? { return nil }
64
+ #endif
65
+
66
+ }
67
+
68
+ #elseif os(tvOS)
69
+
70
+ extension THEOplayerRCTView {
71
+
72
+ func parseAdsConfig(configDict: NSDictionary) {}
73
+
74
+ #if GOOGLE_IMA
75
+ func playerAdsConfiguration() -> AdsConfiguration? { return AdsConfiguration() }
76
+ #else
77
+ func playerAdsConfiguration() -> AdsConfiguration? { return nil }
78
+ #endif
79
+
80
+ }
81
+
82
+ #endif
@@ -0,0 +1,97 @@
1
+ // THEOplayerRCTCastAPI+Airplay.swift
2
+
3
+ import Foundation
4
+
5
+ let ERROR_CODE_AIRPLAY_ACCESS_FAILURE = "airplay_access_failure"
6
+ let ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE = "Airplay is not supported by the provided iOS SDK"
7
+ let ERROR_MESSAGE_AIRPLAY_ACCESS_FAILURE = "Could not access THEOplayer Airplay API"
8
+
9
+ extension THEOplayerRCTCastAPI {
10
+
11
+ #if os(iOS)
12
+
13
+ @objc(airplayCasting:resolver:rejecter:)
14
+ func airplayCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
15
+ DispatchQueue.main.async {
16
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
17
+ if let cast = theView.cast(),
18
+ let airplay = cast.airPlay {
19
+ resolve(airplay.casting)
20
+ } else {
21
+ reject(ERROR_CODE_AIRPLAY_ACCESS_FAILURE, ERROR_MESSAGE_AIRPLAY_ACCESS_FAILURE, nil)
22
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current airplay casting status.") }
23
+ }
24
+ }
25
+ }
26
+
27
+ @objc(airplayState:resolver:rejecter:)
28
+ func airplayState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
29
+ DispatchQueue.main.async {
30
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
31
+ if let cast = theView.cast(),
32
+ let airplay = cast.airPlay {
33
+ resolve(airplay.state._rawValue)
34
+ } else {
35
+ reject(ERROR_CODE_AIRPLAY_ACCESS_FAILURE, ERROR_MESSAGE_AIRPLAY_ACCESS_FAILURE, nil)
36
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current airplay state.") }
37
+ }
38
+ }
39
+ }
40
+
41
+ @objc(airplayStart:)
42
+ func airplayStart(_ node: NSNumber) -> Void {
43
+ DispatchQueue.main.async {
44
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
45
+ if let cast = theView.cast(),
46
+ let airplay = cast.airPlay {
47
+ if DEBUG_CAST_API { print("[NATIVE] Starting airplay session.") }
48
+ airplay.start()
49
+ } else {
50
+ if DEBUG_CAST_API { print("[NATIVE] Could not start airplay session.") }
51
+ }
52
+ }
53
+ }
54
+
55
+ @objc(airplayStop:)
56
+ func airplayStop(_ node: NSNumber) -> Void {
57
+ DispatchQueue.main.async {
58
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
59
+ if let cast = theView.cast(),
60
+ let airplay = cast.airPlay {
61
+ if DEBUG_CAST_API { print("[NATIVE] Stopping airplay session.") }
62
+ airplay.stop()
63
+ } else {
64
+ if DEBUG_CAST_API { print("[NATIVE] Could not stop airplay session.") }
65
+ }
66
+ }
67
+ }
68
+
69
+ #else
70
+
71
+ @objc(airplayCasting:resolver:rejecter:)
72
+ func airplayCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
73
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
74
+ resolve(false)
75
+ }
76
+
77
+ @objc(airplayState:resolver:rejecter:)
78
+ func airplayState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
79
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
80
+ resolve("unavailable")
81
+ }
82
+
83
+ @objc(airplayStart:)
84
+ func airplayStart(_ node: NSNumber) -> Void {
85
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
86
+ }
87
+
88
+ @objc(airplayStop:)
89
+ func airplayStop(_ node: NSNumber) -> Void {
90
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_AIRPLAY_UNSUPPORTED_FEATURE) }
91
+ }
92
+
93
+ #endif
94
+ }
95
+
96
+
97
+
@@ -0,0 +1,132 @@
1
+ // THEOplayerRCTCastAPI+Chromecast.swift
2
+
3
+ import Foundation
4
+
5
+ let ERROR_CODE_CHROMECAST_ACCESS_FAILURE = "chromecast_access_failure"
6
+ let ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE = "Chromecast is not supported by the provided iOS SDK"
7
+ let ERROR_MESSAGE_CHROMECAST_ACCESS_FAILURE = "Could not access THEOplayer Chromecast API"
8
+
9
+ extension THEOplayerRCTCastAPI {
10
+
11
+ #if os(iOS) && CHROMECAST
12
+
13
+ @objc(chromecastCasting:resolver:rejecter:)
14
+ func chromecastCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
15
+ DispatchQueue.main.async {
16
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
17
+ if let cast = theView.cast(),
18
+ let chromecast = cast.chromecast {
19
+ resolve(chromecast.casting)
20
+ } else {
21
+ reject(ERROR_CODE_CHROMECAST_ACCESS_FAILURE, ERROR_MESSAGE_CHROMECAST_ACCESS_FAILURE, nil)
22
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current chromecast casting status.") }
23
+ }
24
+ }
25
+ }
26
+
27
+ @objc(chromecastState:resolver:rejecter:)
28
+ func chromecastState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
29
+ DispatchQueue.main.async {
30
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
31
+ if let cast = theView.cast(),
32
+ let chromecast = cast.chromecast {
33
+ resolve(chromecast.state?._rawValue)
34
+ } else {
35
+ reject(ERROR_CODE_CHROMECAST_ACCESS_FAILURE, ERROR_MESSAGE_CHROMECAST_ACCESS_FAILURE, nil)
36
+ if DEBUG_CAST_API { print("[NATIVE] Could not retrieve current chromecast state.") }
37
+ }
38
+ }
39
+ }
40
+
41
+ @objc(chromecastStart:)
42
+ func chromecastStart(_ node: NSNumber) -> Void {
43
+ DispatchQueue.main.async {
44
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
45
+ if let cast = theView.cast(),
46
+ let chromecast = cast.chromecast {
47
+ if DEBUG_CAST_API { print("[NATIVE] Starting chromecast session.") }
48
+ chromecast.start()
49
+ } else {
50
+ if DEBUG_CAST_API { print("[NATIVE] Could not start chromecast session.") }
51
+ }
52
+ }
53
+ }
54
+
55
+ @objc(chromecastStop:)
56
+ func chromecastStop(_ node: NSNumber) -> Void {
57
+ DispatchQueue.main.async {
58
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
59
+ if let cast = theView.cast(),
60
+ let chromecast = cast.chromecast {
61
+ if DEBUG_CAST_API { print("[NATIVE] Stopping chromecast session.") }
62
+ chromecast.stop()
63
+ } else {
64
+ if DEBUG_CAST_API { print("[NATIVE] Could not stop chromecast session.") }
65
+ }
66
+ }
67
+ }
68
+
69
+ @objc(chromecastJoin:)
70
+ func chromecastJoin(_ node: NSNumber) -> Void {
71
+ DispatchQueue.main.async {
72
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
73
+ if let cast = theView.cast(),
74
+ let chromecast = cast.chromecast {
75
+ if DEBUG_CAST_API { print("[NATIVE] Joining chromecast session.") }
76
+ chromecast.join()
77
+ } else {
78
+ if DEBUG_CAST_API { print("[NATIVE] Could not join chromecast session.") }
79
+ }
80
+ }
81
+ }
82
+
83
+ @objc(chromecastLeave:)
84
+ func chromecastLeave(_ node: NSNumber) -> Void {
85
+ DispatchQueue.main.async {
86
+ let theView = self.bridge.uiManager.view(forReactTag: node) as! THEOplayerRCTView
87
+ if let cast = theView.cast(),
88
+ let chromecast = cast.chromecast {
89
+ if DEBUG_CAST_API { print("[NATIVE] Leaving chromecast session.") }
90
+ chromecast.leave()
91
+ } else {
92
+ if DEBUG_CAST_API { print("[NATIVE] Could not leave chromecast session.") }
93
+ }
94
+ }
95
+ }
96
+
97
+ #else
98
+
99
+ @objc(chromecastCasting:resolver:rejecter:)
100
+ func chromecastCasting(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
101
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
102
+ resolve(false)
103
+ }
104
+
105
+ @objc(chromecastState:resolver:rejecter:)
106
+ func chromecastState(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
107
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
108
+ resolve("unavailable")
109
+ }
110
+
111
+ @objc(chromecastStart:)
112
+ func chromecastStart(_ node: NSNumber) -> Void {
113
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
114
+ }
115
+
116
+ @objc(chromecastStop:)
117
+ func chromecastStop(_ node: NSNumber) -> Void {
118
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
119
+ }
120
+
121
+ @objc(chromecastJoin:)
122
+ func chromecastJoin(_ node: NSNumber) -> Void {
123
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
124
+ }
125
+
126
+ @objc(chromecastLeave:)
127
+ func chromecastLeave(_ node: NSNumber) -> Void {
128
+ if DEBUG_CAST_API { print(ERROR_MESSAGE_CHROMECAST_UNSUPPORTED_FEATURE) }
129
+ }
130
+
131
+ #endif
132
+ }