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.
- package/README.md +2 -0
- package/android/src/main/java/com/theoplayer/PlayerConfigAdapter.kt +115 -0
- package/android/src/main/java/com/theoplayer/PlayerEventEmitter.kt +648 -0
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.kt +23 -0
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.kt +446 -0
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.kt +117 -0
- package/android/src/main/java/com/theoplayer/{TimeUpdateRate.java → TimeUpdateRate.kt} +2 -2
- package/android/src/main/java/com/theoplayer/ads/AdAdapter.kt +161 -0
- package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.kt +90 -0
- package/android/src/main/java/com/theoplayer/ads/AdsModule.kt +140 -0
- package/android/src/main/java/com/theoplayer/cast/CastEventAdapter.kt +81 -0
- package/android/src/main/java/com/theoplayer/cast/CastModule.kt +75 -0
- package/android/src/main/java/com/theoplayer/drm/ContentProtectionAdapter.kt +2 -2
- package/android/src/main/java/com/theoplayer/drm/ContentProtectionModule.kt +1 -2
- package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegration.kt +1 -2
- package/android/src/main/java/com/theoplayer/drm/ProxyContentProtectionIntegrationFactory.kt +3 -5
- package/android/src/main/java/com/theoplayer/source/SourceAdapter.kt +402 -0
- package/android/src/main/java/com/theoplayer/track/MediaTrackEventType.kt +6 -0
- package/android/src/main/java/com/theoplayer/track/MediaTrackType.kt +6 -0
- package/android/src/main/java/com/theoplayer/track/QualityListAdapter.kt +43 -0
- package/android/src/main/java/com/theoplayer/track/QualityListFilter.kt +28 -0
- package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.kt +10 -0
- package/android/src/main/java/com/theoplayer/track/TrackEventType.kt +7 -0
- package/android/src/main/java/com/theoplayer/track/TrackListAdapter.kt +219 -0
- package/android/src/main/java/com/theoplayer/util/ViewResolver.kt +19 -0
- package/ios/THEOplayerRCTAdAggregator.swift +15 -6
- package/ios/THEOplayerRCTAdsAPI.swift +39 -40
- package/ios/THEOplayerRCTBridge.m +54 -1
- package/ios/THEOplayerRCTCastAPI.swift +275 -0
- package/ios/THEOplayerRCTDebug.swift +3 -0
- package/ios/THEOplayerRCTSourceDescriptionBuilder.swift +91 -19
- package/ios/THEOplayerRCTTrackEventTypes.swift +17 -0
- package/ios/{THEOplayerRCTMetadataAggregator.swift → THEOplayerRCTTrackMetadataAggregator.swift} +69 -55
- package/ios/THEOplayerRCTView.swift +126 -22
- package/ios/THEOplayerRCTViewAdEventHandler.swift +7 -5
- package/ios/THEOplayerRCTViewCastEventHandler.swift +124 -0
- package/ios/THEOplayerRCTViewMainEventHandler.swift +1 -1
- package/ios/THEOplayerRCTViewMediaTrackEventHandler.swift +185 -0
- package/ios/THEOplayerRCTViewTextTrackEventHandler.swift +30 -13
- package/ios/custom/Frameworks/ios/put_custom_ios_xcframework_here.txt +1 -1
- package/ios/custom/Frameworks/tvos/put_custom_tvos_xcframework_here.txt +2 -0
- package/ios/custom/react-native-theoplayer_custom.podspec +46 -0
- package/lib/commonjs/api/THEOplayerView.js.map +1 -1
- package/lib/commonjs/api/barrel.js +21 -8
- package/lib/commonjs/api/barrel.js.map +1 -1
- package/lib/commonjs/api/cast/Airplay.js +6 -0
- package/lib/commonjs/api/cast/Airplay.js.map +1 -0
- package/lib/commonjs/api/cast/CastAPI.js +6 -0
- package/lib/commonjs/api/cast/CastAPI.js.map +1 -0
- package/lib/commonjs/api/cast/CastConfiguration.js +2 -0
- package/lib/commonjs/api/cast/CastConfiguration.js.map +1 -0
- package/lib/commonjs/api/cast/CastState.js +2 -0
- package/lib/commonjs/api/cast/CastState.js.map +1 -0
- package/lib/commonjs/api/cast/Chromecast.js +6 -0
- package/lib/commonjs/api/cast/Chromecast.js.map +1 -0
- package/lib/commonjs/api/cast/barrel.js +71 -0
- package/lib/commonjs/api/cast/barrel.js.map +1 -0
- package/lib/commonjs/api/config/PlayerConfiguration.js.map +1 -1
- package/lib/commonjs/api/error/ChromecastError.js +2 -0
- package/lib/commonjs/api/error/ChromecastError.js.map +1 -0
- package/lib/commonjs/api/error/barrel.js +13 -0
- package/lib/commonjs/api/error/barrel.js.map +1 -1
- package/lib/commonjs/api/event/CastEvent.js +21 -0
- package/lib/commonjs/api/event/CastEvent.js.map +1 -0
- package/lib/commonjs/api/event/TrackEvent.js +17 -1
- package/lib/commonjs/api/event/TrackEvent.js.map +1 -1
- package/lib/commonjs/api/event/barrel.js +25 -12
- package/lib/commonjs/api/event/barrel.js.map +1 -1
- package/lib/commonjs/api/source/SourceDescription.js.map +1 -1
- package/lib/commonjs/api/source/barrel.js +13 -0
- package/lib/commonjs/api/source/barrel.js.map +1 -1
- package/lib/commonjs/api/source/metadata/MetadataDescription.js +2 -0
- package/lib/commonjs/api/source/metadata/MetadataDescription.js.map +1 -0
- package/lib/commonjs/api/source/metadata/barrel.js +19 -0
- package/lib/commonjs/api/source/metadata/barrel.js.map +1 -0
- package/lib/commonjs/internal/THEOplayerView.js +30 -0
- package/lib/commonjs/internal/THEOplayerView.js.map +1 -1
- package/lib/commonjs/internal/THEOplayerView.web.js +80 -20
- package/lib/commonjs/internal/THEOplayerView.web.js.map +1 -1
- package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js +34 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js +46 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js +42 -0
- package/lib/commonjs/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
- package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js +31 -0
- package/lib/commonjs/internal/cast/THEOplayerWebCastApi.js.map +1 -0
- package/lib/commonjs/internal/web/stub/CastButtonStub.js +16 -0
- package/lib/commonjs/internal/web/stub/CastButtonStub.js.map +1 -0
- package/lib/module/api/THEOplayerView.js.map +1 -1
- package/lib/module/api/barrel.js +1 -0
- package/lib/module/api/barrel.js.map +1 -1
- package/lib/module/api/cast/Airplay.js +2 -0
- package/lib/module/api/cast/Airplay.js.map +1 -0
- package/lib/module/api/cast/CastAPI.js +2 -0
- package/lib/module/api/cast/CastAPI.js.map +1 -0
- package/lib/module/api/cast/CastConfiguration.js +2 -0
- package/lib/module/api/cast/CastConfiguration.js.map +1 -0
- package/lib/module/api/cast/CastState.js +2 -0
- package/lib/module/api/cast/CastState.js.map +1 -0
- package/lib/module/api/cast/Chromecast.js +2 -0
- package/lib/module/api/cast/Chromecast.js.map +1 -0
- package/lib/module/api/cast/barrel.js +6 -0
- package/lib/module/api/cast/barrel.js.map +1 -0
- package/lib/module/api/config/PlayerConfiguration.js.map +1 -1
- package/lib/module/api/error/ChromecastError.js +2 -0
- package/lib/module/api/error/ChromecastError.js.map +1 -0
- package/lib/module/api/error/barrel.js +1 -0
- package/lib/module/api/error/barrel.js.map +1 -1
- package/lib/module/api/event/CastEvent.js +14 -0
- package/lib/module/api/event/CastEvent.js.map +1 -0
- package/lib/module/api/event/TrackEvent.js +14 -0
- package/lib/module/api/event/TrackEvent.js.map +1 -1
- package/lib/module/api/event/barrel.js +2 -1
- package/lib/module/api/event/barrel.js.map +1 -1
- package/lib/module/api/source/SourceDescription.js.map +1 -1
- package/lib/module/api/source/barrel.js +1 -0
- package/lib/module/api/source/barrel.js.map +1 -1
- package/lib/module/api/source/metadata/MetadataDescription.js +2 -0
- package/lib/module/api/source/metadata/MetadataDescription.js.map +1 -0
- package/lib/module/api/source/metadata/barrel.js +2 -0
- package/lib/module/api/source/metadata/barrel.js.map +1 -0
- package/lib/module/internal/THEOplayerView.js +29 -0
- package/lib/module/internal/THEOplayerView.js.map +1 -1
- package/lib/module/internal/THEOplayerView.web.js +80 -21
- package/lib/module/internal/THEOplayerView.web.js.map +1 -1
- package/lib/module/internal/cast/THEOplayerNativeAirplay.js +24 -0
- package/lib/module/internal/cast/THEOplayerNativeAirplay.js.map +1 -0
- package/lib/module/internal/cast/THEOplayerNativeCastApi.js +34 -0
- package/lib/module/internal/cast/THEOplayerNativeCastApi.js.map +1 -0
- package/lib/module/internal/cast/THEOplayerNativeChromecast.js +32 -0
- package/lib/module/internal/cast/THEOplayerNativeChromecast.js.map +1 -0
- package/lib/module/internal/cast/THEOplayerWebCastApi.js +22 -0
- package/lib/module/internal/cast/THEOplayerWebCastApi.js.map +1 -0
- package/lib/module/internal/web/stub/CastButtonStub.js +6 -0
- package/lib/module/internal/web/stub/CastButtonStub.js.map +1 -0
- package/lib/typescript/lib/commonjs/api/cast/Airplay.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/cast/CastAPI.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/cast/CastConfiguration.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/cast/CastState.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/cast/Chromecast.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/cast/barrel.d.ts +1 -0
- package/lib/typescript/lib/commonjs/api/error/ChromecastError.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/event/CastEvent.d.ts +2 -0
- package/lib/typescript/lib/commonjs/api/event/TrackEvent.d.ts +4 -0
- package/lib/typescript/lib/commonjs/api/source/metadata/MetadataDescription.d.ts +0 -0
- package/lib/typescript/lib/commonjs/api/source/metadata/barrel.d.ts +1 -0
- package/lib/typescript/lib/commonjs/internal/THEOplayerView.d.ts +3 -0
- package/lib/typescript/lib/commonjs/internal/THEOplayerView.web.d.ts +3 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeCastApi.d.ts +12 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
- package/lib/typescript/lib/commonjs/internal/cast/THEOplayerWebCastApi.d.ts +8 -0
- package/lib/typescript/lib/commonjs/internal/web/stub/CastButtonStub.d.ts +2 -0
- package/lib/typescript/lib/module/api/barrel.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/Airplay.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/CastAPI.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/CastConfiguration.d.ts +0 -0
- package/lib/typescript/lib/module/api/cast/CastState.d.ts +0 -0
- package/lib/typescript/lib/module/api/cast/Chromecast.d.ts +1 -0
- package/lib/typescript/lib/module/api/cast/barrel.d.ts +3 -0
- package/lib/typescript/lib/module/api/error/ChromecastError.d.ts +0 -0
- package/lib/typescript/lib/module/api/event/CastEvent.d.ts +1 -0
- package/lib/typescript/lib/module/api/event/TrackEvent.d.ts +2 -0
- package/lib/typescript/lib/module/api/event/barrel.d.ts +2 -1
- package/lib/typescript/lib/module/api/source/barrel.d.ts +1 -0
- package/lib/typescript/lib/module/api/source/metadata/MetadataDescription.d.ts +0 -0
- package/lib/typescript/lib/module/api/source/metadata/barrel.d.ts +1 -0
- package/lib/typescript/lib/module/internal/THEOplayerView.d.ts +3 -0
- package/lib/typescript/lib/module/internal/THEOplayerView.web.d.ts +3 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerNativeAirplay.d.ts +8 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerNativeCastApi.d.ts +11 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerNativeChromecast.d.ts +10 -0
- package/lib/typescript/lib/module/internal/cast/THEOplayerWebCastApi.d.ts +7 -0
- package/lib/typescript/lib/module/internal/web/stub/CastButtonStub.d.ts +2 -0
- package/lib/typescript/src/api/THEOplayerView.d.ts +21 -3
- package/lib/typescript/src/api/barrel.d.ts +1 -0
- package/lib/typescript/src/api/cast/Airplay.d.ts +27 -0
- package/lib/typescript/src/api/cast/CastAPI.d.ts +25 -0
- package/lib/typescript/src/api/cast/CastConfiguration.d.ts +41 -0
- package/lib/typescript/src/api/cast/CastState.d.ts +10 -0
- package/lib/typescript/src/api/cast/Chromecast.d.ts +39 -0
- package/lib/typescript/src/api/cast/barrel.d.ts +5 -0
- package/lib/typescript/src/api/config/PlayerConfiguration.d.ts +6 -1
- package/lib/typescript/src/api/error/ChromecastError.d.ts +34 -0
- package/lib/typescript/src/api/error/barrel.d.ts +1 -0
- package/lib/typescript/src/api/event/CastEvent.d.ts +21 -0
- package/lib/typescript/src/api/event/TrackEvent.d.ts +49 -3
- package/lib/typescript/src/api/event/barrel.d.ts +2 -1
- package/lib/typescript/src/api/source/SourceDescription.d.ts +7 -0
- package/lib/typescript/src/api/source/barrel.d.ts +1 -0
- package/lib/typescript/src/api/source/metadata/MetadataDescription.d.ts +12 -0
- package/lib/typescript/src/api/source/metadata/barrel.d.ts +1 -0
- package/lib/typescript/src/internal/THEOplayerView.d.ts +9 -1
- package/lib/typescript/src/internal/THEOplayerView.web.d.ts +7 -2
- package/lib/typescript/src/internal/cast/THEOplayerNativeAirplay.d.ts +9 -0
- package/lib/typescript/src/internal/cast/THEOplayerNativeCastApi.d.ts +10 -0
- package/lib/typescript/src/internal/cast/THEOplayerNativeChromecast.d.ts +11 -0
- package/lib/typescript/src/internal/cast/THEOplayerWebCastApi.d.ts +9 -0
- package/lib/typescript/src/internal/web/stub/CastButtonStub.d.ts +3 -0
- package/package.json +2 -2
- package/react-native-theoplayer.podspec +2 -2
- package/src/api/THEOplayerView.ts +25 -3
- package/src/api/barrel.ts +1 -0
- package/src/api/cast/Airplay.ts +31 -0
- package/src/api/cast/CastAPI.ts +30 -0
- package/src/api/cast/CastConfiguration.ts +44 -0
- package/src/api/cast/CastState.ts +10 -0
- package/src/api/cast/Chromecast.ts +45 -0
- package/src/api/cast/barrel.ts +5 -0
- package/src/api/config/PlayerConfiguration.ts +7 -1
- package/src/api/error/ChromecastError.ts +46 -0
- package/src/api/error/barrel.ts +1 -0
- package/src/api/event/CastEvent.ts +45 -0
- package/src/api/event/TrackEvent.ts +58 -2
- package/src/api/event/barrel.ts +2 -1
- package/src/api/source/SourceDescription.ts +8 -0
- package/src/api/source/barrel.ts +1 -0
- package/src/api/source/metadata/MetadataDescription.ts +13 -0
- package/src/api/source/metadata/barrel.ts +1 -0
- package/src/internal/THEOplayerView.tsx +35 -0
- package/src/internal/THEOplayerView.web.tsx +87 -19
- package/src/internal/cast/THEOplayerNativeAirplay.ts +22 -0
- package/src/internal/cast/THEOplayerNativeCastApi.ts +28 -0
- package/src/internal/cast/THEOplayerNativeChromecast.ts +30 -0
- package/src/internal/cast/THEOplayerWebCastApi.ts +21 -0
- package/src/internal/web/stub/CastButtonStub.tsx +7 -0
- package/android/src/main/java/com/theoplayer/PlayerConfigHelper.java +0 -70
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerPackage.java +0 -32
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerView.java +0 -525
- package/android/src/main/java/com/theoplayer/ReactTHEOplayerViewManager.java +0 -127
- package/android/src/main/java/com/theoplayer/SourceHelper.java +0 -362
- package/android/src/main/java/com/theoplayer/VideoEventEmitter.java +0 -442
- package/android/src/main/java/com/theoplayer/ads/AdEventAdapter.java +0 -92
- package/android/src/main/java/com/theoplayer/ads/AdInfo.java +0 -168
- package/android/src/main/java/com/theoplayer/ads/AdsModule.java +0 -152
- package/android/src/main/java/com/theoplayer/track/QualityListAdapter.java +0 -54
- package/android/src/main/java/com/theoplayer/track/QualityListFilter.java +0 -40
- package/android/src/main/java/com/theoplayer/track/TextTrackCueEventType.java +0 -11
- package/android/src/main/java/com/theoplayer/track/TrackEventType.java +0 -11
- package/android/src/main/java/com/theoplayer/track/TrackListInfo.java +0 -212
- package/android/src/main/java/com/theoplayer/util/ViewResolver.java +0 -42
- 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
|
+
}
|
|
@@ -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
|
-
//
|
|
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:
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
+
}
|
package/ios/{THEOplayerRCTMetadataAggregator.swift → THEOplayerRCTTrackMetadataAggregator.swift}
RENAMED
|
@@ -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
|
|
29
|
+
class THEOplayerRCTTrackMetadataAggregator {
|
|
30
30
|
|
|
31
|
-
class func
|
|
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 :
|
|
37
|
-
EVENT_PROP_AUDIO_TRACKS :
|
|
38
|
-
EVENT_PROP_VIDEO_TRACKS :
|
|
39
|
-
EVENT_PROP_SELECTED_TEXT_TRACK:
|
|
40
|
-
EVENT_PROP_SELECTED_AUDIO_TRACK:
|
|
41
|
-
EVENT_PROP_SELECTED_VIDEO_TRACK:
|
|
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(
|
|
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(
|
|
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:
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
111
|
-
var
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|