@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
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Jonathan Machado
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+
2
+ # @takeoffmedia/react-native-penthera
3
+
4
+ This document provide information about the Penthera SDK implementation, we built 2 custom react native wrappers for iOS and Android using the Penthera native SDK
5
+
6
+ ## Penthera Cloud
7
+
8
+ Penthera Cloud (backplane), the SDK handles the requests to the Penthera Cloud from the SDK initialization, user login, downloads and so on.
9
+
10
+ ## Definition concepts
11
+
12
+ - userID: An unique string identifier of user provided by us, Penthera will use this value to identify and associate any interaction of the SDK with the logged user.
13
+
14
+ - deviceID: An unique string identifier of the device.
15
+
16
+ - asset: Any content downloaded or added to the download quote will be saved as an asset object in Penthera local storage, with an unique string identifier to handle the status of the assets.
17
+
18
+ - VirtuosoHTTPClient: a static http client solution to handle the streaming of the local HLS video format.
19
+
20
+
21
+
22
+ # iOS
23
+
24
+ ## requirements
25
+
26
+ - iOS 10 +
27
+
28
+
29
+ ## setup
30
+
31
+ Add the Penthera repository source to the Podfile:
32
+
33
+
34
+
35
+ source 'https://github.com/penthera/Download2Go-specs.git'
36
+
37
+
38
+
39
+
40
+ Add the framework to the Podfile:
41
+
42
+ ```ruby
43
+ source 'https://cdn.cocoapods.org/'
44
+ source 'https://github.com/penthera/Download2Go-specs.git'
45
+
46
+ pod 'VirtuosoClientDownloadEngine', :git => 'https://github.com/penthera/Download2Go-ios', :branch => 'master'
47
+
48
+ #ALTERNATIVE - Specify a specific version of Penthera SDK
49
+ #pod 'VirtuosoClientDownloadEngine', '~> 4.2'
50
+ ```
51
+
52
+ Run pod install command.
53
+
54
+ Then add to the AppDelegate.mm the VirtuosoClientDownloadEngine.
55
+
56
+ ```Objective-C
57
+ #import <React/RCTAppSetupUtils.h>
58
+
59
+ #import <VirtuosoClientDownloadEngine/VirtuosoClientDownloadEngine.h>
60
+
61
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
62
+
63
+ {
64
+
65
+ //…
66
+
67
+ // Initialize engine and fetch a handle to the singleton instance
68
+
69
+ VirtuosoDownloadEngine* engine = [VirtuosoDownloadEngine instance];
70
+
71
+ // Global “on switch” for downloading
72
+
73
+ [engine setEnabled:YES];
74
+
75
+ }
76
+ ```
77
+
78
+ ## Info.plist
79
+
80
+ In your app’s info.plist:
81
+
82
+ - Add “Application Uses Wifi” and set it to YES.
83
+
84
+ - In “Required Background Modes”, add the option “App downloads content in response to push notifications”.
85
+
86
+ - In “Required Background Modes”, add the option “App downloads content from the network”.
87
+
88
+
89
+ ## Initialization
90
+
91
+ In our wrapper solution we provided a method to instantiate the SDK, the next parameters are required:
92
+
93
+
94
+
95
+ userId: logged user identifier
96
+
97
+ backplaneUrl: the url of the Penthera Cloud
98
+
99
+ publicKey: provided by Penthera
100
+
101
+ privateKey: provided by penthera
102
+
103
+ externalDeviceID: Optional deviceID provided by us
104
+
105
+ This method will return a success message in case the initialization is successful otherwise it will return one of the following errors code:
106
+
107
+ | Fruit | Description |
108
+ |-------| -------|
109
+ | PENTHERA_ENGINE_AREADY_STARTED | Virtuoso is already started. |
110
+ | PENTHERA_ENGINE_NO_BACKPLANE | Virtuoso started up, but couldn’t connect to the Cloud. |
111
+ | PENTHERA_ENGINE_INVALID_OPTIONS | Wrong parameters |
112
+ | PENTHERA_ENGINE_METHOD_IS_DEPRECATED | Error changing the user account. |
113
+ | PENTHERA_ENGINE_INTERNAL_EXCEPTION | Virtuoso exception. |
114
+ | PENTHERA_ENGINE_DATA_MIGRATION_ERROR | Error in the core data. |
115
+ | PENTHERA_ENGINE_UNKNOWN_ERROR | Error |
116
+
117
+
118
+ ## Get download files
119
+
120
+ This method will return an array object with all the downloaded or pending to download assets with this json format:
121
+
122
+
123
+
124
+
125
+ ```js
126
+ [{
127
+ "assetID": "",
128
+ "isDownloaded": true,
129
+ "thumbnail": ""
130
+ }]
131
+
132
+ ```
133
+
134
+
135
+
136
+ ## Get asset
137
+
138
+ This method will return the basic information of the asset, it requires an assetID to search within the database of the downloaded files, In case of success it will return a json object with this format:
139
+
140
+ ```js
141
+ {
142
+ "assetID": "",
143
+ "isDownloaded": true,
144
+ "thumbnail": "",
145
+ "streamURL": "",
146
+ "thumbnailTrack": "",
147
+ "subtitle": ""
148
+ }
149
+ ```
150
+
151
+
152
+ ## Download asset
153
+
154
+ This method will add to the download quote an asset, it required:
155
+
156
+
157
+ assetID: unique content identifier
158
+ title: title of the content
159
+ streamURL:
160
+ thumbnailURL:
161
+ thumbnailTrackURL:
162
+ subtitleURL:
163
+
164
+ It will return an success message or an error code
165
+
166
+ ## Play asset
167
+
168
+ This method will allow you to playback a downloaded content, just need to send the assetId as parameter and it will return a json object with asset information:
169
+
170
+
171
+ ## Delete asset
172
+
173
+ Delete a specific asset from the Penthera database, the assetID is required.
174
+
175
+ ## Delete all assets
176
+
177
+ Delete all the downloaded or pending to download assets in the Penthera database.
178
+
179
+ ## DRM
180
+
181
+ In case that the assets required DRM support, Penthera support the FairPlay playback offline, first we have to set the VirtuosoLicenseManager, this class will allow us to:
182
+
183
+ * Configure the license and certificate
184
+
185
+ * Manually induce the download of an offline license key for an asset,
186
+
187
+ * Manually induce the refresh of a license key,
188
+
189
+ * manually delete a license key from SDK management,
190
+
191
+ * Provide a license key to the SDK for management which you acquired in a custom manner, and
192
+
193
+ * Retrieve the managed license key for an asset, in case you need to manually provide it to a player in
194
+
195
+ * Some custom manner rather than letting the SDK provide it during playback.
196
+
197
+
198
+ The VirtuosoLicenseManager instance has 2 functions to set the License and the certificate:
199
+
200
+ - VirtuosoLicenseManager.downloadClientAppCertificate(fromURL: certificateURL, for: .vlm_FairPlay)
201
+
202
+ - VirtuosoLicenseManager.setLicenseServerURL(licenseURL, for: .vlm_FairPlay)
203
+
@@ -0,0 +1,105 @@
1
+ buildscript {
2
+ // Buildscript is evaluated before everything else so we can't use getExtOrDefault
3
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["Penthera_kotlinVersion"]
4
+
5
+ repositories {
6
+ google()
7
+ mavenCentral()
8
+ }
9
+
10
+ dependencies {
11
+ classpath "com.android.tools.build:gradle:7.2.1"
12
+ // noinspection DifferentKotlinGradleVersion
13
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
+ }
15
+ }
16
+
17
+ def isNewArchitectureEnabled() {
18
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
19
+ }
20
+
21
+ apply plugin: "com.android.library"
22
+ apply plugin: "kotlin-android"
23
+
24
+
25
+ def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') }
26
+
27
+ if (isNewArchitectureEnabled()) {
28
+ apply plugin: "com.facebook.react"
29
+ }
30
+
31
+ def getExtOrDefault(name) {
32
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["Penthera_" + name]
33
+ }
34
+
35
+ def getExtOrIntegerDefault(name) {
36
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["Penthera_" + name]).toInteger()
37
+ }
38
+
39
+ android {
40
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
41
+
42
+ defaultConfig {
43
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
44
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
45
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
46
+ }
47
+ buildTypes {
48
+ release {
49
+ minifyEnabled false
50
+ }
51
+ }
52
+
53
+ lintOptions {
54
+ disable "GradleCompatible"
55
+ }
56
+
57
+ compileOptions {
58
+ sourceCompatibility JavaVersion.VERSION_1_8
59
+ targetCompatibility JavaVersion.VERSION_1_8
60
+ }
61
+
62
+ }
63
+
64
+ repositories {
65
+ mavenCentral()
66
+ google()
67
+ //Penthera
68
+ maven { url 'https://clientbuilds.penthera.com/repository/releases/'
69
+ credentials {
70
+ username "britbox"
71
+ password "Br1tB0x"
72
+ }
73
+ }
74
+ maven { url 'https://artifacts.bitmovin.com/artifactory/public-releases' }
75
+
76
+ }
77
+
78
+ def kotlin_version = getExtOrDefault("kotlinVersion")
79
+
80
+ dependencies {
81
+ implementation "com.facebook.react:react-native:+"
82
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
83
+ //penthera
84
+ implementation 'com.penthera:cnc-android-sdk-debug:5.3.5'
85
+ implementation 'com.google.code.gson:gson:2.8.6'
86
+ implementation "com.penthera:cnc-android-bitmovin-support:5.3.6-beta"
87
+
88
+ implementation 'com.bitmovin.player:player:3.38.2'
89
+ implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
90
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
91
+
92
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:1.8.20"
93
+ implementation 'androidx.core:core-ktx:1.10.1'
94
+ implementation 'androidx.appcompat:appcompat:1.6.1'
95
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
96
+ implementation project(path: ':bitmovin-player-react-native')
97
+ }
98
+
99
+ if (isNewArchitectureEnabled()) {
100
+ react {
101
+ jsRootDir = file("../src/")
102
+ libraryName = "Penthera"
103
+ codegenJavaPackageName = "com.penthera"
104
+ }
105
+ }
@@ -0,0 +1,5 @@
1
+ Penthera_kotlinVersion=1.7.0
2
+ Penthera_minSdkVersion=21
3
+ Penthera_targetSdkVersion=31
4
+ Penthera_compileSdkVersion=31
5
+ Penthera_ndkversion=21.4.7075529
@@ -0,0 +1,51 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ xmlns:tools="http://schemas.android.com/tools"
3
+ package="com.takeoffmediareactnativepenthera">
4
+
5
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
6
+
7
+ <application
8
+ tools:replace="android:label"
9
+ android:allowBackup="true"
10
+ android:label="@string/app_name"
11
+ android:supportsRtl="true"
12
+ android:theme="@style/AppTheme">
13
+
14
+ <meta-data android:name="com.penthera.virtuososdk.notification.provider.impl" android:value="com.takeoffmediareactnativepenthera.virtuoso.notification.ServiceForegroundNotificationProvider" />
15
+
16
+ <!-- Meta Data to configure license manager for DRM -->
17
+ <meta-data tools:replace="android:value" android:name="com.penthera.virtuososdk.license.manager.impl" android:value="com.takeoffmediareactnativepenthera.virtuoso.DemoLicenseManager"/>
18
+
19
+ <!-- Service Starter -->
20
+ <receiver android:name=".virtuoso.ServiceStarter"
21
+ android:enabled="true"
22
+ android:exported="true"
23
+ android:label="SDKDemoKotlin Service Starter"
24
+ android:directBootAware="true">
25
+ <intent-filter>
26
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>
27
+ <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
28
+ <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
29
+ <action android:name="android.intent.action.PACKAGE_REMOVED" />
30
+ <data android:scheme="package"/>
31
+ </intent-filter>
32
+ <intent-filter>
33
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>
34
+ <category android:name="android.intent.category.DEFAULT" />
35
+ </intent-filter>
36
+
37
+ </receiver>
38
+
39
+ <!-- Catalog Provider -->
40
+ <meta-data
41
+ android:name="com.penthera.virtuososdk.client.pckg"
42
+ android:value="${applicationId}.virtuoso.provider" />
43
+
44
+ <provider
45
+ android:name="com.takeoffmediareactnativepenthera.virtuoso.PentheraContentProvider"
46
+ android:authorities="${applicationId}.virtuoso.provider"
47
+ android:process=":vservice"/>
48
+
49
+ </application>
50
+
51
+ </manifest>
@@ -0,0 +1,148 @@
1
+ package com.takeoffmediareactnativepenthera
2
+
3
+ import android.util.Log
4
+ import com.penthera.common.Common
5
+ import com.penthera.virtuososdk.client.IAsset
6
+ import com.penthera.virtuososdk.client.IAssetManager
7
+ import com.penthera.virtuososdk.client.IIdentifier
8
+ import com.penthera.virtuososdk.client.Observers
9
+ import com.takeoffmediareactnativepenthera.virtuoso.OfflineVideoEngine
10
+
11
+ class AssetQueueObserver(mOfflineVideo : OfflineVideoEngine) : Observers.IQueueObserver {
12
+
13
+ private var lastProgress : Int = -1
14
+ private var mOfflineVideo : OfflineVideoEngine = mOfflineVideo
15
+
16
+ override fun engineStartedDownloadingAsset(aAsset: IIdentifier) {
17
+ lastProgress = -1
18
+ updateItem(aAsset, true)
19
+ }
20
+
21
+ override fun enginePerformedProgressUpdateDuringDownload(aAsset: IIdentifier) {
22
+ updateItem(aAsset, true)
23
+ }
24
+
25
+ override fun engineCompletedDownloadingAsset(aAsset: IIdentifier) {
26
+ val updateAsset = aAsset as IAsset
27
+ val assetId = updateAsset.assetId
28
+ updateItem(aAsset, true)
29
+ EventEmitter.sharedInstance.dispatch("penthera", PentheraEvent.DOWNLOAD_COMPLETE, assetId, "")
30
+
31
+ }
32
+
33
+ override fun engineEncounteredErrorDownloadingAsset(aAsset: IIdentifier) {
34
+ // The base implementation does nothing. See class documentation.
35
+ }
36
+
37
+ override fun engineUpdatedQueue() {
38
+ // This indicates a change to the download queue - meaning either we added or removed something
39
+ Log.e("MiModulo","<<<<<<<<<<engineUpdatedQueue>>>>>>>>>>>>")
40
+
41
+ val assetManager: IAssetManager = mOfflineVideo.virtuoso!!.assetManager
42
+ val queued = assetManager.queue.size()
43
+ val downloaded = assetManager.downloaded.cursor.count
44
+ val curAsset = mOfflineVideo.asset
45
+ if (curAsset != null && (queued > 0 || downloaded > 0)) {
46
+ val asset = assetManager.get(curAsset.id) as IAsset
47
+ if (asset.downloadStatus != curAsset.downloadStatus) {
48
+ mOfflineVideo.asset = asset
49
+ updateItem(asset, true)
50
+ }
51
+ }
52
+ if (queued == 0) {
53
+ // The asset has been deleted or downloaded
54
+ Log.e("MiModulo","<<<<<<<<<<Asset deleted>>>>>>>>>>>>")
55
+ }
56
+ }
57
+
58
+ override fun engineEncounteredErrorParsingAsset(mAssetId: String) {
59
+ Log.e("MiModulo","<<<<<<<<<<engineEncounteredErrorParsingAsset>>>>>>>>>>>>")
60
+ }
61
+
62
+
63
+ private fun updateItem(aFile: IIdentifier, forceUpdate: Boolean) {
64
+ Log.e("MiModulo","<<<<<<<<<<updateItem>>>>>>>>>>>>")
65
+
66
+ val updateAsset = aFile as IAsset
67
+ val assetId = updateAsset.assetId
68
+
69
+ // Progress is for catalog item
70
+ if (assetId.isNotEmpty() && mOfflineVideo.assetId == assetId) {
71
+ //update our asset status
72
+ // mActivity.runOnUiThread{ updateItemStatus(updateAsset, forceUpdate) }
73
+ //mOfflineVideo { updateItemStatus(updateAsset, forceUpdate) }
74
+ updateItemStatus(updateAsset, forceUpdate)
75
+ }
76
+ }
77
+
78
+ private fun updateItemStatus(asset: IAsset?, forceUpdate: Boolean) {
79
+ Log.e("MiModulo","<<<<<<<<<<updateItemStatus>>>>>>>>>>>>")
80
+
81
+ asset?.let{
82
+ if(mOfflineVideo.assetId == it.assetId){
83
+ mOfflineVideo.asset = asset
84
+
85
+ var progress = (asset.fractionComplete * 100.0).toInt()
86
+ EventEmitter.sharedInstance.dispatch("penthera", PentheraEvent.PROGRESS_UPDATED, it.assetId, progress.toString())
87
+ // Not a repeated progress -- Keep context switches minimal due to frequency of messages, unless forced
88
+ if (forceUpdate || progress != lastProgress) {
89
+ val assetStatus : String
90
+ val value: String
91
+ when (asset.downloadStatus) {
92
+
93
+ Common.AssetStatus.DOWNLOADING -> {
94
+ assetStatus = "Downloading"
95
+ value = "downloading"
96
+ }
97
+
98
+ Common.AssetStatus.DOWNLOAD_COMPLETE -> {
99
+ assetStatus = "Downloading"
100
+ value = "complete"
101
+ }
102
+
103
+ Common.AssetStatus.EXPIRED -> {
104
+ assetStatus = "Expired"
105
+ value = "expired"
106
+ }
107
+
108
+ Common.AssetStatus.DOWNLOAD_DENIED_ASSET -> {
109
+ assetStatus = "Queued"
110
+ value = "DENIED : MAD"
111
+ }
112
+
113
+ Common.AssetStatus.DOWNLOAD_DENIED_ACCOUNT -> {
114
+ assetStatus = "Queued"
115
+ value = "DENIED : MDA"
116
+ }
117
+
118
+ Common.AssetStatus.DOWNLOAD_DENIED_EXTERNAL_POLICY -> {
119
+ assetStatus = "Queued"
120
+ value = "DENIED : EXT"
121
+ }
122
+
123
+ Common.AssetStatus.DOWNLOAD_DENIED_MAX_DEVICE_DOWNLOADS -> {
124
+ assetStatus = "Queued"
125
+ value = "DENIED :MPD"
126
+ }
127
+
128
+ Common.AssetStatus.DOWNLOAD_BLOCKED_AWAITING_PERMISSION -> {
129
+ assetStatus = "Queued"
130
+ value = "AWAITING PERMISSION"
131
+ }
132
+
133
+ Common.AssetStatus.DOWNLOAD_DENIED_COPIES -> {
134
+ assetStatus = "Queued"
135
+ value = "DENIED : COPIES"
136
+ }
137
+
138
+ else -> {
139
+ assetStatus = "Queued"
140
+ value = "pending"
141
+ }
142
+ }
143
+
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
@@ -0,0 +1,53 @@
1
+ import com.facebook.react.bridge.Arguments
2
+ import com.facebook.react.bridge.ReactContext
3
+ import com.facebook.react.modules.core.DeviceEventManagerModule
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.google.gson.Gson
6
+ import com.takeoffmediareactnativepenthera.PentheraModule
7
+
8
+ object PentheraEvent {
9
+ const val DID_START_DOWNLOADING = "DID_START_DOWNLOADING"
10
+ const val PROGRESS_UPDATED = "PROGRESS_UPDATED"
11
+ const val DOWNLOAD_COMPLETE = "DOWNLOAD_COMPLETE"
12
+ const val CONFIG_ASSET_FAILED = "CONFIG_ASSET_FAILED"
13
+ const val ASSET_RESUME_DOWNLOAD_UPDATED = "ASSET_RESUME_DOWNLOAD_UPDATED"
14
+ const val ASSET_DELETED = "ASSET_DELETED"
15
+ const val FAIR_PLAY_FAILED_INIT_DELEGATE = "FAIR_PLAY_FAILED_INIT_DELEGATE"
16
+ const val FAIR_PLAY_EXTRACT_CID = "FAIR_PLAY_EXTRACT_CID"
17
+ const val FAIR_PLAY_PREPARE_SPC = "FAIR_PLAY_PREPARE_SPC"
18
+ const val FAIR_PLAY_EXTRACT_CKC = "FAIR_PLAY_EXTRACT_CKC"
19
+ const val FAIR_PLAY_LICENSE_DELEGATE_ERROR = "FAIR_PLAY_LICENSE_DELEGATE_ERROR"
20
+ const val PENDING_ASSET_FOUND = "PENDING_ASSET_FOUND"
21
+ const val ERROR_DOWNLOAD = "ERROR_DOWNLOAD"
22
+ }
23
+
24
+ class EventEmitter private constructor() {
25
+ companion object {
26
+ val sharedInstance: EventEmitter by lazy { EventEmitter() }
27
+ }
28
+
29
+ private var eventEmitter: PentheraModule? = null
30
+
31
+ fun registerEventEmitter(eventEmitter: PentheraModule) {
32
+ this.eventEmitter = eventEmitter
33
+ }
34
+
35
+ fun dispatch(name: String, code: String, assetId: String, body: String) {
36
+ val event = Event(code, assetId, body)
37
+ val gson = Gson()
38
+ val json = gson.toJson(event)
39
+ val reactContext = eventEmitter?.reactContext
40
+ reactContext!!.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
41
+ ?.emit(name, json)
42
+ }
43
+
44
+ val allEvents: List<String> by lazy {
45
+ val allEventNames: MutableList<String> = mutableListOf("penthera")
46
+
47
+ // Append all events here
48
+
49
+ allEventNames
50
+ }
51
+
52
+ private class Event(val code: String, val assetId: String, val body: String)
53
+ }
@@ -0,0 +1,104 @@
1
+ package com.takeoffmediareactnativepenthera
2
+
3
+ import EventEmitter
4
+ import android.app.Activity
5
+ import android.util.Log
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.LifecycleEventListener
8
+ import com.facebook.react.bridge.ReactApplicationContext
9
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
10
+ import com.facebook.react.bridge.ReactMethod
11
+ import com.facebook.react.bridge.Promise
12
+ import com.facebook.react.bridge.ReadableMap
13
+ import com.facebook.react.bridge.WritableMap
14
+ import com.takeoffmediareactnativepenthera.virtuoso.OfflineVideoEngine
15
+ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
16
+
17
+
18
+ class PentheraModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
19
+
20
+ private var offlineVideoEngine: OfflineVideoEngine? = OfflineVideoEngine(reactContext)
21
+ private var activity: Activity? = null
22
+ private var appState: String = "active"
23
+ val reactContext: ReactApplicationContext = reactContext
24
+
25
+ override fun getName(): String = NAME
26
+ override fun initialize() {
27
+ super.initialize()
28
+
29
+ EventEmitter.sharedInstance.registerEventEmitter(this)
30
+ activity = currentActivity
31
+ }
32
+
33
+ // Example method
34
+ // See https://reactnative.dev/docs/native-modules-android
35
+ @ReactMethod
36
+ fun multiply(a: Double, b: Double, promise: Promise) {
37
+ promise.resolve(a * b)
38
+ }
39
+
40
+ @ReactMethod
41
+ fun initializeSdk(user: String, backplaneUrl: String, publicKey: String, privateKey: String, promise: Promise) {
42
+ promise.resolve(offlineVideoEngine?.setup(user, backplaneUrl, publicKey, privateKey, activity!!))
43
+ }
44
+
45
+ @ReactMethod
46
+ fun download(data: String){
47
+ offlineVideoEngine?.downloadAsset(data, activity!!)
48
+ }
49
+ @ReactMethod
50
+ fun getDownloads(blank: String, promise: Promise) {
51
+ promise.resolve(offlineVideoEngine?.getDownloads())
52
+ }
53
+
54
+ @ReactMethod
55
+ fun getByAssetId(assetId: String, promise: Promise) {
56
+ promise.resolve(offlineVideoEngine?.getByAssetId(assetId))
57
+ }
58
+ @ReactMethod
59
+ fun delete(assetId: String) {
60
+ offlineVideoEngine?.deleteAsset(assetId)
61
+ }
62
+
63
+ @ReactMethod
64
+ fun loadBitmovinSourceManager(assetId: String, nativeId: String, promise: Promise) {
65
+ val bitmovinSourceItem = offlineVideoEngine?.loadBitmovinSourceManager(assetId, nativeId)
66
+ promise.resolve(bitmovinSourceItem)
67
+ }
68
+ @ReactMethod
69
+ fun startAppStateListener() {
70
+ val appStateListener = { nextAppState: String ->
71
+ if (appState != nextAppState && nextAppState == "active") {
72
+ Log.e("MiModulo", "active")
73
+ }
74
+ if (appState != nextAppState && nextAppState == "background") {
75
+ Log.e("MiModulo", "background")
76
+ }
77
+ appState = nextAppState
78
+ }
79
+
80
+ reactContext.addLifecycleEventListener(object : LifecycleEventListener {
81
+ override fun onHostResume() {
82
+ offlineVideoEngine!!.onResume()
83
+ appStateListener("active")
84
+
85
+ }
86
+
87
+
88
+
89
+ override fun onHostPause() {
90
+ offlineVideoEngine!!.onPause()
91
+ appStateListener("background")
92
+ }
93
+
94
+ override fun onHostDestroy() {
95
+ appStateListener("inactive")
96
+ }
97
+ })
98
+ }
99
+
100
+
101
+ companion object {
102
+ const val NAME = "Penthera"
103
+ }
104
+ }