@takeoffmedia/react-native-penthera 0.1.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 (96) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +203 -0
  3. package/android/build.gradle +105 -0
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +51 -0
  6. package/android/src/main/java/com/takeoffmediareactnativepenthera/AssetQueueObserver.kt +148 -0
  7. package/android/src/main/java/com/takeoffmediareactnativepenthera/EventEmitter.kt +53 -0
  8. package/android/src/main/java/com/takeoffmediareactnativepenthera/PentheraModule.kt +104 -0
  9. package/android/src/main/java/com/takeoffmediareactnativepenthera/PentheraPackage.kt +16 -0
  10. package/android/src/main/java/com/takeoffmediareactnativepenthera/YourPlayerActivity.kt +14 -0
  11. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/DemoLicenseManager.kt +50 -0
  12. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/OfflineVideoEngine.kt +227 -0
  13. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/PentheraContentProvider.kt +17 -0
  14. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/ServiceStarter.kt +65 -0
  15. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/data/Drm.kt +6 -0
  16. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/data/Item.kt +34 -0
  17. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/NotificationFactory.kt +279 -0
  18. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/NotificationType.kt +10 -0
  19. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/notification/ServiceForegroundNotificationProvider.kt +98 -0
  20. package/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/util/Util.kt +22 -0
  21. package/android/src/main/res/drawable/ic_launcher_background.xml +170 -0
  22. package/android/src/main/res/drawable/small_logo.png +0 -0
  23. package/android/src/main/res/values/colors.xml +6 -0
  24. package/android/src/main/res/values/strings.xml +61 -0
  25. package/android/src/main/res/values/styles.xml +10 -0
  26. package/android/src/main/res/xml/network_security_config.xml +9 -0
  27. package/ios/Catalog.swift +30 -0
  28. package/ios/EventEmitter.swift +53 -0
  29. package/ios/Penthera-Bridging-Header.h +3 -0
  30. package/ios/Penthera.m +40 -0
  31. package/ios/Penthera.swift +384 -0
  32. package/ios/Penthera.xcodeproj/project.pbxproj +283 -0
  33. package/ios/Util.swift +16 -0
  34. package/ios/drm/FairPlayDrmSetup.swift +107 -0
  35. package/ios/drm/FairPlayLicenseProcessingDelegate.swift +42 -0
  36. package/lib/commonjs/data/data.json +58 -0
  37. package/lib/commonjs/hooks/index.js +13 -0
  38. package/lib/commonjs/hooks/index.js.map +1 -0
  39. package/lib/commonjs/hooks/usePenthera.js +146 -0
  40. package/lib/commonjs/hooks/usePenthera.js.map +1 -0
  41. package/lib/commonjs/index.js +36 -0
  42. package/lib/commonjs/index.js.map +1 -0
  43. package/lib/commonjs/interface/HomeTypes.js +6 -0
  44. package/lib/commonjs/interface/HomeTypes.js.map +1 -0
  45. package/lib/commonjs/interface/Idata.js +2 -0
  46. package/lib/commonjs/interface/Idata.js.map +1 -0
  47. package/lib/commonjs/interface/PentheraTypes.js +2 -0
  48. package/lib/commonjs/interface/PentheraTypes.js.map +1 -0
  49. package/lib/commonjs/nativeModules/index.js +48 -0
  50. package/lib/commonjs/nativeModules/index.js.map +1 -0
  51. package/lib/commonjs/utils/Penthera.js +19 -0
  52. package/lib/commonjs/utils/Penthera.js.map +1 -0
  53. package/lib/module/data/data.json +58 -0
  54. package/lib/module/hooks/index.js +2 -0
  55. package/lib/module/hooks/index.js.map +1 -0
  56. package/lib/module/hooks/usePenthera.js +139 -0
  57. package/lib/module/hooks/usePenthera.js.map +1 -0
  58. package/lib/module/index.js +5 -0
  59. package/lib/module/index.js.map +1 -0
  60. package/lib/module/interface/HomeTypes.js +2 -0
  61. package/lib/module/interface/HomeTypes.js.map +1 -0
  62. package/lib/module/interface/Idata.js +2 -0
  63. package/lib/module/interface/Idata.js.map +1 -0
  64. package/lib/module/interface/PentheraTypes.js +2 -0
  65. package/lib/module/interface/PentheraTypes.js.map +1 -0
  66. package/lib/module/nativeModules/index.js +35 -0
  67. package/lib/module/nativeModules/index.js.map +1 -0
  68. package/lib/module/utils/Penthera.js +12 -0
  69. package/lib/module/utils/Penthera.js.map +1 -0
  70. package/lib/typescript/hooks/index.d.ts +2 -0
  71. package/lib/typescript/hooks/index.d.ts.map +1 -0
  72. package/lib/typescript/hooks/usePenthera.d.ts +19 -0
  73. package/lib/typescript/hooks/usePenthera.d.ts.map +1 -0
  74. package/lib/typescript/index.d.ts +4 -0
  75. package/lib/typescript/index.d.ts.map +1 -0
  76. package/lib/typescript/interface/HomeTypes.d.ts +15 -0
  77. package/lib/typescript/interface/HomeTypes.d.ts.map +1 -0
  78. package/lib/typescript/interface/Idata.d.ts +30 -0
  79. package/lib/typescript/interface/Idata.d.ts.map +1 -0
  80. package/lib/typescript/interface/PentheraTypes.d.ts +104 -0
  81. package/lib/typescript/interface/PentheraTypes.d.ts.map +1 -0
  82. package/lib/typescript/nativeModules/index.d.ts +9 -0
  83. package/lib/typescript/nativeModules/index.d.ts.map +1 -0
  84. package/lib/typescript/utils/Penthera.d.ts +11 -0
  85. package/lib/typescript/utils/Penthera.d.ts.map +1 -0
  86. package/package.json +166 -0
  87. package/src/data/data.json +58 -0
  88. package/src/hooks/index.ts +1 -0
  89. package/src/hooks/usePenthera.ts +160 -0
  90. package/src/index.tsx +5 -0
  91. package/src/interface/HomeTypes.ts +16 -0
  92. package/src/interface/Idata.ts +34 -0
  93. package/src/interface/PentheraTypes.ts +104 -0
  94. package/src/nativeModules/index.ts +58 -0
  95. package/src/utils/Penthera.ts +10 -0
  96. package/takeoffmedia-react-native-penthera.podspec +36 -0
@@ -0,0 +1,30 @@
1
+ struct Catalog: Codable {
2
+ var id: String = ""
3
+ var url: String = ""
4
+ var thumbnail: String = ""
5
+
6
+ var showId: String = ""
7
+ var showTitle: String = ""
8
+
9
+ var title: String = ""
10
+ var description: String = ""
11
+ var rate: String = ""
12
+ }
13
+
14
+ struct OfflineCatalog: Codable {
15
+ var id: String = ""
16
+ var thumbnail: String = ""
17
+ var wallpaper: String = ""
18
+ var subtitle: String = ""
19
+ var url: String = ""
20
+ var certificateUrl: String = ""
21
+ var licenseUrl: String = ""
22
+ var isCompleted: Bool
23
+ var isPaused: Bool
24
+ }
25
+
26
+ struct Event: Codable {
27
+ var code: String = ""
28
+ var assetId: String = ""
29
+ var body: String = ""
30
+ }
@@ -0,0 +1,53 @@
1
+ struct PentheraEvent {
2
+ static let DID_START_DOWNLOADING = "DID_START_DOWNLOADING"
3
+ static let PROGRESS_UPDATED = "PROGRESS_UPDATED"
4
+ static let DOWNLOAD_COMPLETE = "DOWNLOAD_COMPLETE"
5
+ static let CONFIG_ASSET_FAILED = "CONFIG_ASSET_FAILED"
6
+ static let ASSET_RESUME_DOWNLOAD_UPDATED = "ASSET_RESUME_DOWNLOAD_UPDATED"
7
+ static let ASSET_DELETED = "ASSET_DELETED"
8
+ static let FAIR_PLAY_FAILED_INIT_DELEGATE = "FAIR_PLAY_FAILED_INIT_DELEGATE"
9
+ static let FAIR_PLAY_EXTRACT_CID = "FAIR_PLAY_EXTRACT_CID"
10
+ static let FAIR_PLAY_PREPARE_SPC = "FAIR_PLAY_PREPARE_SPC"
11
+ static let FAIR_PLAY_EXTRACT_CKC = "FAIR_PLAY_EXTRACT_CKC"
12
+ static let FAIR_PLAY_LICENSE_DELEGATE_ERROR = "FAIR_PLAY_LICENSE_DELEGATE_ERROR"
13
+ static let PENDING_ASSET_FOUND = "PENDING_ASSET_FOUND"
14
+ static let ERROR_DOWNLOAD = "ERROR_DOWNLOAD"
15
+ }
16
+
17
+ class EventEmitter {
18
+
19
+ /// Shared Instance.
20
+ public static var sharedInstance = EventEmitter()
21
+
22
+ // ReactNativeEventEmitter is instantiated by React Native with the bridge.
23
+ private var eventEmitter: Penthera!
24
+
25
+ private init() {}
26
+
27
+ // When React Native instantiates the emitter it is registered here.
28
+ func registerEventEmitter(eventEmitter: Penthera) {
29
+ self.eventEmitter = eventEmitter
30
+ }
31
+
32
+ func dispatch(name: String, code: String, assetId: String, body: String) {
33
+ let event = Event(code: code, assetId: assetId, body: body)
34
+ let decoder = JSONEncoder()
35
+ do {
36
+ let data = try decoder.encode(event)
37
+ let json = String(data: data, encoding: .utf8)!
38
+ eventEmitter.sendEvent(withName: name, body: json)
39
+ } catch {
40
+
41
+ }
42
+ }
43
+
44
+ /// All Events which must be support by React Native.
45
+ lazy var allEvents: [String] = {
46
+ var allEventNames: [String] = ["penthera"]
47
+
48
+ // Append all events here
49
+
50
+ return allEventNames
51
+ }()
52
+
53
+ }
@@ -0,0 +1,3 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTViewManager.h>
3
+ #import <React/RCTEventEmitter.h>
package/ios/Penthera.m ADDED
@@ -0,0 +1,40 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <VirtuosoClientDownloadEngine/VirtuosoClientDownloadEngine.h>
3
+ #import <React/RCTEventEmitter.h>
4
+
5
+ @interface RCT_EXTERN_MODULE(Penthera, RCTEventEmitter)
6
+
7
+ RCT_EXTERN_METHOD(multiply:(float)a withB:(float)b
8
+ withResolver:(RCTPromiseResolveBlock)resolve
9
+ withRejecter:(RCTPromiseRejectBlock)reject)
10
+
11
+ RCT_EXTERN_METHOD(initializeSdk:(NSString*)user
12
+ withBackplaneUrl:(NSString*)backplaneUrl
13
+ withPublicKey:(NSString*)publicKey
14
+ withPrivateKey:(NSString*)privateKey
15
+ withResolver:(RCTPromiseResolveBlock)resolve
16
+ withRejecter:(RCTPromiseRejectBlock)reject)
17
+
18
+ RCT_EXTERN_METHOD(getDownloads:(NSString*)blank
19
+ withResolver:(RCTPromiseResolveBlock)resolve
20
+ withRejecter:(RCTPromiseRejectBlock)reject)
21
+
22
+ RCT_EXTERN_METHOD(download:(NSString*)catalog
23
+ withResolver:(RCTPromiseResolveBlock)resolve
24
+ withRejecter:(RCTPromiseRejectBlock)reject)
25
+
26
+ RCT_EXTERN_METHOD(delete:(NSString*)assetID
27
+ withResolver:(RCTPromiseResolveBlock)resolve
28
+ withRejecter:(RCTPromiseRejectBlock)reject)
29
+
30
+
31
+ RCT_EXTERN_METHOD(playAsset:(NSString*)assetID
32
+ withResolver:(RCTPromiseResolveBlock)resolve
33
+ withRejecter:(RCTPromiseRejectBlock)reject)
34
+
35
+ + (BOOL)requiresMainQueueSetup
36
+ {
37
+ return NO;
38
+ }
39
+
40
+ @end
@@ -0,0 +1,384 @@
1
+ import VirtuosoClientDownloadEngine
2
+
3
+ @objc(Penthera)
4
+ class Penthera: RCTEventEmitter, VirtuosoDownloadEngineNotificationsDelegate {
5
+ var downloadEngineNotifications: VirtuosoDownloadEngineNotificationManager!
6
+
7
+ public override init() {
8
+ super.init()
9
+ EventEmitter.sharedInstance.registerEventEmitter(eventEmitter: self)
10
+ }
11
+
12
+ @objc(multiply:withB:withResolver:withRejecter:)
13
+ func multiply(a: Float, b: Float, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
14
+ resolve(a*b)
15
+ }
16
+
17
+ @objc(initializeSdk:withBackplaneUrl:withPublicKey:withPrivateKey:withResolver:withRejecter:)
18
+ func initializeSdk(user: String, backplaneUrl: String, publicKey: String, privateKey: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
19
+ guard let engineConfig = VirtuosoEngineConfig(
20
+ user: user,
21
+ backplaneUrl: backplaneUrl,
22
+ publicKey: publicKey,
23
+ privateKey: privateKey) else {
24
+ return reject("Penthera", "engine Config", nil)
25
+ }
26
+ self.downloadEngineNotifications = VirtuosoDownloadEngineNotificationManager.init(delegate: self)
27
+ let virtuoso = VirtuosoDownloadEngine.instance()
28
+ virtuoso.startup(engineConfig) { status in
29
+ switch(status) {
30
+ case .vde_EngineStartupSuccess:
31
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: "Virtuoso Success", assetId: "test", body: "asset")
32
+ resolve("Success")
33
+ case .vde_EngineStartupAlreadyStarted:
34
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Aready Started")
35
+ resolve("Already Started")
36
+ case .vde_EngineStartupSuccessNoBackplane:
37
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Backplane")
38
+ resolve("No Backplane")
39
+ case .vde_EngineStartupInvalidOptions:
40
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Invalid")
41
+ resolve("Invalid Option")
42
+ case .vde_EngineStartupMethodIsDeprecated:
43
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Method Decraped")
44
+ resolve("Decraped")
45
+ case .vde_EngineStartupInternalException:
46
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Internal Exception")
47
+ resolve("Internal Exception")
48
+ case .vde_EngineDataMigrationError:
49
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Migrate Error")
50
+ resolve("Error")
51
+ @unknown default:
52
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", body: "Virtuoso Default")
53
+ resolve("Error Default")
54
+ }
55
+ }
56
+ }
57
+
58
+ @objc(getDownloads:withResolver:withRejecter:)
59
+ func getDownloads(blank: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
60
+ let completedAssets = VirtuosoAsset.completedAssets(withAvailabilityFilter: false)
61
+ let pendingAssets = VirtuosoAsset.pendingAssets(withAvailabilityFilter: false)
62
+ var offlineCatalogs: [OfflineCatalog] = []
63
+
64
+ for case let va as VirtuosoAsset in completedAssets {
65
+ let thumbnail = va.findAllAncillaries(withTag: "thumbnail").first
66
+ let wallpaper = va.findAllAncillaries(withTag: "wallpaper").first
67
+ let catalog = OfflineCatalog(
68
+ id: va.assetID,
69
+ thumbnail: thumbnail?.localFilePath ?? "",
70
+ wallpaper: wallpaper?.localFilePath ?? "",
71
+ isCompleted: va.isPlayable,
72
+ isPaused: va.isPaused)
73
+ offlineCatalogs.append(catalog)
74
+ }
75
+
76
+ for case let va as VirtuosoAsset in pendingAssets {
77
+ let catalog = OfflineCatalog(
78
+ id: va.assetID,
79
+ isCompleted: false,
80
+ isPaused: va.isPaused)
81
+ offlineCatalogs.append(catalog)
82
+ }
83
+
84
+ let decoder = JSONEncoder()
85
+ do {
86
+ let data = try decoder.encode(offlineCatalogs)
87
+ let json = String(data: data, encoding: .utf8)!
88
+ resolve(json)
89
+ } catch {
90
+ reject("penthere", error.localizedDescription, error)
91
+ }
92
+ //resolve(downloadComplete.map{ ($0 as? VirtuosoAsset)?.assetID })
93
+ }
94
+
95
+ func getDownloadedAsset(assetID: String) -> VirtuosoAsset? {
96
+ print("Entra getDownloadedAsset>>>")
97
+ // assets that have finished downloading
98
+ let completedAssets = VirtuosoAsset.completedAssets(withAvailabilityFilter: false)
99
+ guard let asset = completedAssets.filter({ ($0 as! VirtuosoAsset).assetID == assetID }).first as? VirtuosoAsset else {
100
+ return nil
101
+ }
102
+ return asset
103
+ }
104
+
105
+ public func downloadEngineDidStartDownloadingAsset(_ asset: VirtuosoAsset) {
106
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.DID_START_DOWNLOADING, assetId: asset.assetID, body: "")
107
+ }
108
+
109
+ public func downloadEngineProgressUpdated(for asset: VirtuosoAsset) {
110
+ let percentage: Float = Float(asset.fractionComplete)/Float(asset.estimatedSize)
111
+ if(percentage.isFinite) {
112
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.PROGRESS_UPDATED, assetId: asset.assetID, body: "\(Int(asset.fractionComplete*100))")
113
+ }
114
+ }
115
+
116
+ public func downloadEngineProgressUpdatedProcessing(for asset: VirtuosoAsset) {
117
+
118
+ }
119
+
120
+ public func downloadEngineDidFinishDownloadingAsset(_ asset: VirtuosoAsset) {
121
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.DOWNLOAD_COMPLETE, assetId: asset.assetID, body: "")
122
+ }
123
+
124
+ public func downloadEngineDidEncounterError(for asset: VirtuosoAsset, error: Error?, task: URLSessionTask?, data: Data?, statusCode: NSNumber?) {
125
+ asset.delete()
126
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.ERROR_DOWNLOAD, assetId: asset.assetID, body: error.debugDescription ?? "Error downloading")
127
+ /*EventEmitter.sharedInstance.dispatch(name: "penthera", body: "\(asset.assetID): Engine did encounter error \(error?.localizedDescription ?? "-")")*/
128
+ }
129
+
130
+ public func downloadEngineInternalQueueUpdate(asset: VirtuosoAsset) {
131
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", code: "TEST downloadEngineInternalQueueUpdate", body: "Queue updated", assetId: asset.assetID)
132
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: "TEST downloadEngineInternalQueueUpdate", assetId: asset.assetID, body: "Queue updated")
133
+ }
134
+
135
+ public func downloadEngineStartupComplete(_ succeeded: Bool, asset: VirtuosoAsset) {
136
+ //EventEmitter.sharedInstance.dispatch(name: "penthera", code: "Test downloadEngineStartupComplete", body: "SDK startup complete", assetId: asset.assetID)
137
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: "TEST downloadEngineStartupComplete", assetId: asset.assetID, body: "SDK startup complete")
138
+ }
139
+
140
+
141
+
142
+
143
+ func getPendingAsset(assetID: String) -> VirtuosoAsset? {
144
+ let pendingAssets = VirtuosoAsset.pendingAssets(withAvailabilityFilter: false)
145
+ guard let asset = pendingAssets.filter({ ($0 as! VirtuosoAsset).assetID == assetID }).first as? VirtuosoAsset else {
146
+ return nil
147
+ }
148
+ return asset
149
+ }
150
+
151
+ func getAncillaryFiles(files: [String: AnyObject]) -> [VirtuosoAncillaryFile] {
152
+ var ancillaryFiles: [VirtuosoAncillaryFile] = []
153
+ files.forEach { file in
154
+ guard let url = file.value as? String else {
155
+ return
156
+ }
157
+ guard let ancillaryFile = VirtuosoAncillaryFile(downloadUrl: url, andTag: file.key) else {
158
+ return
159
+ }
160
+ ancillaryFiles.append(ancillaryFile)
161
+ }
162
+ return ancillaryFiles
163
+ }
164
+
165
+ @objc(download:withResolver:withRejecter:)
166
+ func download(catalogString: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
167
+ let virtuoso = VirtuosoDownloadEngine.instance()
168
+ var queue = virtuoso.assetsInQueue()
169
+
170
+ //let decoder = JSONDecoder()
171
+
172
+ do {
173
+
174
+
175
+ let data = catalogString.getDictionary()
176
+
177
+ guard let item = data!["item"] as! [String: AnyObject]? else {
178
+ reject("No item", nil, nil)
179
+ return
180
+ }
181
+ guard let url = data!["url"] as? String else {
182
+ reject("No url", nil, nil)
183
+ return
184
+ }
185
+
186
+ let assetID = item["id"] as! String? ?? ""
187
+ let hasDRM = item["drm"] as! Bool? ?? false
188
+
189
+ let downloadAsset = getDownloadedAsset(assetID: assetID)
190
+ let pendingAsset = getPendingAsset(assetID: assetID)
191
+
192
+ if (pendingAsset != nil) {
193
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.PENDING_ASSET_FOUND, assetId: assetID, body: "")
194
+ pendingAsset?.delete()
195
+ return
196
+ }
197
+
198
+ if(downloadAsset == nil && pendingAsset == nil) {
199
+
200
+ DispatchQueue.global(qos: .background).async {
201
+ guard let config = VirtuosoAssetConfig(url: url,
202
+ assetID: assetID,
203
+ description: "\(assetID)",
204
+ type: .vde_AssetTypeHLS) else {
205
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.CONFIG_ASSET_FAILED, assetId: assetID, body: "-")
206
+ return
207
+ }
208
+
209
+ // Ancillary Files
210
+ let thumbnails = item["thumbnails"] as! [String: AnyObject]? ?? [:]
211
+ let subtitles = item["subtitles"] as! [String: AnyObject]? ?? [:]
212
+ config.ancillaries = self.getAncillaryFiles(files: thumbnails) + self.getAncillaryFiles(files: subtitles)
213
+
214
+
215
+ //DRM
216
+ if(hasDRM) {
217
+
218
+ guard let drm = data!["drm"] as! [String: AnyObject]? else {
219
+ reject("No drm", nil, nil)
220
+ return
221
+ }
222
+
223
+ let token = drm["token"] as! String? ?? ""
224
+ let licenceHttpHeader = drm["licence_server_http_header"] as! String? ?? ""
225
+ let licence = drm["licence_server"] as! String? ?? ""
226
+ let cert = drm["fairplay_cert"] as! String? ?? ""
227
+
228
+ guard let drmSetup = FairPlayDrmSetup(assetID: assetID, certificateUrl: cert, licenceUrl: licence, header: licenceHttpHeader, token: token) else {
229
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.FAIR_PLAY_LICENSE_DELEGATE_ERROR, assetId: "", body: "")
230
+ return
231
+ }
232
+
233
+ if !drmSetup.configure() {
234
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.FAIR_PLAY_LICENSE_DELEGATE_ERROR, assetId: "", body: "")
235
+ return
236
+ }
237
+ config.protectionType = .vde_AssetProtectionTypeFairPlay
238
+
239
+ }
240
+
241
+ let asset = VirtuosoAsset.init(config: config)
242
+
243
+ let data = item["data"] as! [String: AnyObject]? ?? [:]
244
+
245
+ asset?.userInfo = data
246
+
247
+ config.ancillaries?.forEach{ file in
248
+ asset?.add(file)
249
+ }
250
+
251
+
252
+ //asset?.add(subtitle!)
253
+
254
+ //let calendar = Calendar.current
255
+ //guard let expiryDate = calendar.date(byAdding: .minute, value: 1, to: Date()) else {
256
+ // return
257
+ //}
258
+
259
+ //asset?.expiryAfterDownload = expiryDate.timeIntervalSinceNow
260
+
261
+ queue.append(asset!)
262
+ resolve(assetID)
263
+ //resolve(queue.count)
264
+ }
265
+ }
266
+
267
+ } catch {
268
+ reject("penthera", error.localizedDescription, error)
269
+ }
270
+ }
271
+
272
+ @objc(delete:withResolver:withRejecter:)
273
+ func delete(assetID: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
274
+ //DispatchQueue.global(qos: .background).async {
275
+
276
+ let downloadComplete = VirtuosoAsset.completedAssets(withAvailabilityFilter: false)
277
+ if(downloadComplete.count > 0) {
278
+ (downloadComplete.first as! VirtuosoAsset).delete()
279
+ }
280
+ resolve("Delete complete")
281
+ DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
282
+ EventEmitter.sharedInstance.dispatch(name: "penthera", code: PentheraEvent.ASSET_DELETED, assetId: assetID, body: "")
283
+ }
284
+ }
285
+
286
+ @objc open override func supportedEvents() -> [String] {
287
+ return EventEmitter.sharedInstance.allEvents
288
+ }
289
+
290
+ @objc(playAsset:withResolver:withRejecter:)
291
+ func playAsset(assetID: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
292
+
293
+ let downloadComplete = VirtuosoAsset.completedAssets(withAvailabilityFilter: false)
294
+ guard let asset = downloadComplete.filter({ ($0 as! VirtuosoAsset).assetID == assetID }).first as? VirtuosoAsset else {
295
+ reject("Error streaming asset", "", nil)
296
+ return
297
+ }
298
+
299
+ let decoder = JSONEncoder()
300
+
301
+ do {
302
+
303
+
304
+ // let subtitle = vcHttpServer?.ancillaryURLForAncillary(withTag: "subtitle", usingMime: "text/vtt")
305
+ // let thumbnailOffline = asset.findAllAncillaries(withTag: "thumbnailOffline").first
306
+ //let wallpaper = asset.findAllAncillaries(withTag: "wallpaper").first
307
+
308
+ let vcHttpServer = VirtuosoClientHTTPServer(asset: asset)
309
+
310
+ let licenseURL = vcHttpServer?.fairPlayLicenseServerURL
311
+ let certificateURL = vcHttpServer?.fairPlayCertificateDataURL(forSubType: nil)
312
+
313
+ //let avContentKeySession = VirtuosoLicenseManager.registeredAVContentKeySession()
314
+
315
+ //let userInfoData = try encoder.encode(asset.userInfo)
316
+ //let userInfo = String(data: userInfoData, encoding: .utf8)
317
+
318
+ let assetData = [
319
+ "id": asset.assetID,
320
+ "url": vcHttpServer?.playbackURL ?? "",
321
+ "certificate": certificateURL ,
322
+ "license": licenseURL
323
+ ]
324
+
325
+ let data = try decoder.encode(assetData)
326
+ let json = String(data: data, encoding: .utf8)!
327
+ resolve(json)
328
+
329
+ // let config = PlayerConfig()
330
+ // config.styleConfig.userInterfaceType = .system
331
+ // config.key = "ASSSSSS"
332
+
333
+ // let player = PlayerFactory.create(playerConfig: config)
334
+
335
+ // guard let streamUrl = URL(string: vcHttpServer!.playbackURL) else {
336
+ // return
337
+ // }
338
+
339
+ // // Create a SourceConfig
340
+ // let sourceConfig = SourceConfig(url: streamUrl, type: .hls)
341
+ // print(streamUrl.absoluteString)
342
+
343
+ // // Optionally set additional properties
344
+ // sourceConfig.title = "Art of motion"
345
+
346
+ // DispatchQueue.main.async {
347
+ // let source = SourceFactory.create(from: sourceConfig)
348
+
349
+ // player.load(source: source)
350
+
351
+
352
+ // let viewController = UIApplication.shared.windows.first?.rootViewController as? UIViewController
353
+
354
+ // let playerView = PlayerView(player: player, frame: (viewController?.view.bounds)!)
355
+
356
+ // // Adding the view to the a container View
357
+ // viewController?.view.addSubview(playerView)
358
+ // viewController?.view.bringSubviewToFront(playerView)
359
+ // }
360
+
361
+
362
+ /*
363
+ let demoPlayer = DemoPlayerViewController()
364
+ DispatchQueue.main.async {
365
+ asset.play(using: .vde_AssetPlaybackTypeLocal,
366
+ andPlayer: demoPlayer as VirtuosoPlayer,
367
+ onSuccess: {
368
+ // Present the player
369
+
370
+ let viewController = UIApplication.shared.windows.first?.rootViewController as? UIViewController
371
+ viewController?.present(demoPlayer, animated: true)
372
+ //self.present(demoPlayer, animated: true, completion: nil)
373
+ },
374
+ onFail: {
375
+ //self.error = nil
376
+ })
377
+ }*/
378
+
379
+ } catch {
380
+ reject("penthere", error.localizedDescription, error)
381
+ }
382
+ }
383
+
384
+ }