@takeoffmedia/react-native-penthera 0.2.65 → 0.2.67
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/android/src/main/java/com/takeoffmediareactnativepenthera/virtuoso/OfflineVideoEngine.kt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
package com.takeoffmediareactnativepenthera.virtuoso
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.app.Activity
|
|
5
5
|
import android.content.Context
|
|
@@ -7,7 +7,7 @@ import android.util.Log
|
|
|
7
7
|
import com.bitmovin.player.api.media.subtitle.SubtitleTrack
|
|
8
8
|
import com.bitmovin.player.reactnative.PlayerModule
|
|
9
9
|
import com.bitmovin.player.reactnative.converter.JsonConverter
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
12
12
|
import com.google.gson.Gson
|
|
13
13
|
import com.penthera.common.Common.AuthenticationStatus
|
|
@@ -37,12 +37,10 @@ import java.io.IOException
|
|
|
37
37
|
import java.net.HttpURLConnection
|
|
38
38
|
import java.text.SimpleDateFormat
|
|
39
39
|
import java.util.Calendar
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
42
|
-
|
|
43
42
|
lateinit var virtuoso : Virtuoso
|
|
44
43
|
private lateinit var queueObserver: AssetQueueObserver
|
|
45
|
-
|
|
46
44
|
var asset: IAsset? = null
|
|
47
45
|
var assetId: MutableList<String> = mutableListOf()
|
|
48
46
|
private val gson = Gson()
|
|
@@ -52,32 +50,32 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
52
50
|
var valuePublicKey: String = ""
|
|
53
51
|
var valuePrivateKey: String = ""
|
|
54
52
|
private val client = OkHttpClient()
|
|
55
|
-
|
|
53
|
+
|
|
56
54
|
private val enginePauseObserver: Observers.IEngineObserver = object : EngineObserver() {
|
|
57
55
|
override fun engineStatusChanged(status: Int) {
|
|
58
56
|
Log.e("MiModulo", "<<<<<<<<<<status $status>>>>>>>>>>>>")
|
|
59
57
|
}
|
|
60
58
|
}
|
|
61
|
-
|
|
59
|
+
|
|
62
60
|
private fun getInstanceVirtuoso(): Virtuoso {
|
|
63
61
|
virtuoso = Virtuoso(context)
|
|
64
62
|
queueObserver = AssetQueueObserver(this, virtuoso)
|
|
65
63
|
onResume()
|
|
66
64
|
return virtuoso
|
|
67
65
|
}
|
|
68
|
-
|
|
66
|
+
|
|
69
67
|
fun onResume() {
|
|
70
68
|
virtuoso.onResume()
|
|
71
69
|
virtuoso.addObserver(queueObserver)
|
|
72
70
|
virtuoso.addObserver(enginePauseObserver)
|
|
73
71
|
}
|
|
74
|
-
|
|
72
|
+
|
|
75
73
|
fun onPause() {
|
|
76
74
|
virtuoso.onPause()
|
|
77
75
|
virtuoso.removeObserver(queueObserver)
|
|
78
76
|
virtuoso.removeObserver(enginePauseObserver)
|
|
79
77
|
}
|
|
80
|
-
|
|
78
|
+
|
|
81
79
|
fun setup(
|
|
82
80
|
userId: String = valueUserId,
|
|
83
81
|
backplaneUrl: String = valueBackPlaneUrl,
|
|
@@ -90,9 +88,9 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
90
88
|
valueBackPlaneUrl = backplaneUrl
|
|
91
89
|
valuePrivateKey = privateKey
|
|
92
90
|
valuePublicKey = publicKey
|
|
93
|
-
|
|
91
|
+
|
|
94
92
|
val nameDevice = android.os.Build.MODEL
|
|
95
|
-
|
|
93
|
+
|
|
96
94
|
vir.startup(
|
|
97
95
|
URL(valueBackPlaneUrl),
|
|
98
96
|
valueUserId,
|
|
@@ -110,9 +108,9 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
110
108
|
).let {
|
|
111
109
|
promise?.resolve("Penthera initialization successfully")
|
|
112
110
|
}
|
|
113
|
-
|
|
111
|
+
|
|
114
112
|
}
|
|
115
|
-
|
|
113
|
+
|
|
116
114
|
fun downloadAsset(newItem: String) {
|
|
117
115
|
setup()
|
|
118
116
|
val data = JSONObject(newItem)
|
|
@@ -140,7 +138,7 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
140
138
|
URL(url)
|
|
141
139
|
)
|
|
142
140
|
)
|
|
143
|
-
|
|
141
|
+
|
|
144
142
|
val subtitles = JSONArray(item["subtitles"] as String)
|
|
145
143
|
for (i in 0 until subtitles.length()) {
|
|
146
144
|
val subtitle = subtitles.getJSONObject(i)
|
|
@@ -156,7 +154,7 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
156
154
|
)
|
|
157
155
|
)
|
|
158
156
|
}
|
|
159
|
-
|
|
157
|
+
|
|
160
158
|
val params = MPDAssetBuilder().apply {
|
|
161
159
|
assetId(item["id"].toString())
|
|
162
160
|
manifestUrl(URL(url))
|
|
@@ -167,10 +165,10 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
167
165
|
setClientSideAdSupport(true)
|
|
168
166
|
withAncillaryFiles(fileList)
|
|
169
167
|
}.build()
|
|
170
|
-
|
|
168
|
+
|
|
171
169
|
virtuoso.assetManager.createMPDSegmentedAssetAsync(params)
|
|
172
170
|
}
|
|
173
|
-
|
|
171
|
+
|
|
174
172
|
fun getDownloads(): String? {
|
|
175
173
|
val completedList = mutableListOf<MutableMap<String, Any>>()
|
|
176
174
|
val cursor = virtuoso.assetManager?.cursor
|
|
@@ -180,8 +178,7 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
180
178
|
return gson.toJson(completedList)
|
|
181
179
|
}
|
|
182
180
|
val columnNames = cursor?.columnNames
|
|
183
|
-
|
|
184
|
-
while (cursor?.moveToNext() == true && columnNames != null) {
|
|
181
|
+
while (cursor?.moveToNext() == true && columnNames != null) {
|
|
185
182
|
val dataMap = mutableMapOf<String, Any>()
|
|
186
183
|
var eap = ""
|
|
187
184
|
var ead = ""
|
|
@@ -229,29 +226,28 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
229
226
|
put("effectiveExpiryDate", if (value == "0") eadFormated else eapFormated)
|
|
230
227
|
}
|
|
231
228
|
}
|
|
232
|
-
|
|
233
229
|
}
|
|
234
230
|
}
|
|
235
231
|
dataMap["isPaused"] = false
|
|
236
232
|
completedList.add(dataMap)
|
|
237
233
|
}
|
|
238
234
|
cursor?.close()
|
|
239
|
-
|
|
235
|
+
|
|
240
236
|
return gson.toJson(completedList)
|
|
241
237
|
}
|
|
242
|
-
|
|
238
|
+
|
|
243
239
|
private fun dateToString(seconds: String): String {
|
|
244
240
|
val secondsLong = seconds.toLong()
|
|
245
241
|
val calendar = Calendar.getInstance()
|
|
246
242
|
calendar.add(Calendar.SECOND, secondsLong.toInt())
|
|
247
|
-
|
|
243
|
+
|
|
248
244
|
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
|
|
249
245
|
return dateFormat.format(calendar.time)
|
|
250
246
|
}
|
|
251
|
-
|
|
247
|
+
|
|
252
248
|
class AssetParseObserver(activity: Context) : ISegmentedAssetFromParserObserver {
|
|
253
249
|
private val mActivity: Context = activity
|
|
254
|
-
|
|
250
|
+
|
|
255
251
|
@SuppressLint("ShowToast")
|
|
256
252
|
override fun complete(asset: ISegmentedAsset?, error: Int, addedToQueue: Boolean) {
|
|
257
253
|
// Show a process when the asset to parsed and added to queue
|
|
@@ -266,17 +262,16 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
266
262
|
// }
|
|
267
263
|
}
|
|
268
264
|
}
|
|
269
|
-
|
|
270
|
-
|
|
265
|
+
|
|
266
|
+
|
|
271
267
|
fun deleteMany(assetIds: ReadableArray, promise: Promise) {
|
|
272
268
|
val assetManager = virtuoso.assetManager
|
|
273
269
|
val result = Arguments.createMap()
|
|
274
|
-
|
|
270
|
+
|
|
275
271
|
for (i in 0 until assetIds.size()) {
|
|
276
272
|
val idValue = assetIds.getString(i)
|
|
277
273
|
val asset = assetManager.getByAssetId(idValue)
|
|
278
274
|
.firstOrNull() as? IAsset
|
|
279
|
-
|
|
280
275
|
if (asset != null) {
|
|
281
276
|
assetManager.delete(asset)
|
|
282
277
|
result.putBoolean(idValue, true)
|
|
@@ -286,15 +281,15 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
286
281
|
assetId.remove(idValue)
|
|
287
282
|
}
|
|
288
283
|
}
|
|
289
|
-
|
|
284
|
+
|
|
290
285
|
promise.resolve(result);
|
|
291
286
|
}
|
|
292
|
-
|
|
293
|
-
|
|
287
|
+
|
|
288
|
+
|
|
294
289
|
fun getByAssetId(assetId: String): String? {
|
|
295
290
|
//load asset if it has already been downloaded
|
|
296
291
|
val list: MutableList<IIdentifier>? = getInstanceVirtuoso().assetManager.getByAssetId(assetId)
|
|
297
|
-
|
|
292
|
+
|
|
298
293
|
list?.let {
|
|
299
294
|
if (it.isNotEmpty()) {
|
|
300
295
|
asset = list[0] as VirtuosoSegmentedFile
|
|
@@ -307,13 +302,13 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
307
302
|
client.newCall(request).execute().use { response ->
|
|
308
303
|
if (!response.isSuccessful) throw IOException("Unexpected code $response")
|
|
309
304
|
}
|
|
310
|
-
|
|
305
|
+
|
|
311
306
|
val keyValueMap = HashMap<String, Any>()
|
|
312
307
|
keyValueMap["offlineUrl"] = offlineUrl.toString()
|
|
313
308
|
keyValueMap["metadata"] = asset?.metadata.toString()
|
|
314
|
-
|
|
309
|
+
|
|
315
310
|
val ancillaryFiles = (asset as ISegmentedAsset).getAncillaryFiles(context)
|
|
316
|
-
|
|
311
|
+
|
|
317
312
|
//HERE THE ASSET MANIFEST IS REQUESTED
|
|
318
313
|
keyValueMap["ancillary"] = ancillaryFiles
|
|
319
314
|
return gson.toJson(keyValueMap)
|
|
@@ -321,50 +316,44 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
321
316
|
}
|
|
322
317
|
return null
|
|
323
318
|
}
|
|
324
|
-
|
|
325
319
|
fun updateUI() {}
|
|
326
|
-
|
|
320
|
+
|
|
327
321
|
fun loadBitmovinSourceManager(assetId: String, nativeId: String, startOffset: Double?, ancillaries: String , promise: Promise) {
|
|
328
|
-
|
|
329
322
|
getInstanceVirtuoso().assetManager?.getByAssetId(assetId)?.firstOrNull()?.let { asset ->
|
|
330
|
-
|
|
331
323
|
val sourceManager = BitmovinSourceManager(context, asset as ISegmentedAsset)
|
|
332
324
|
val sourceItem = sourceManager.bitmovinSourceItem
|
|
333
325
|
val playerModule = context.getNativeModule(PlayerModule::class.java)
|
|
334
326
|
if (playerModule != null && sourceItem != null) {
|
|
335
|
-
|
|
336
327
|
var player = playerModule.getPlayer(nativeId)
|
|
337
328
|
while(player == null) {
|
|
338
329
|
Thread.sleep(100)
|
|
339
330
|
player = playerModule.getPlayer(nativeId) as Nothing?
|
|
340
331
|
}
|
|
341
|
-
|
|
342
332
|
if (player != null) {
|
|
343
333
|
val metadata = JSONObject(asset.metadata)
|
|
344
334
|
val subtitles = JSONArray(metadata["subtitles"] as String)
|
|
345
335
|
val ancillaryFiles = JSONArray(ancillaries)
|
|
346
336
|
for (i in 0 until subtitles.length()) {
|
|
337
|
+
val subtitleMap = Arguments.createMap()
|
|
347
338
|
val subtitle = subtitles.getJSONObject(i)
|
|
348
|
-
|
|
349
|
-
var url: String = ""
|
|
350
|
-
|
|
339
|
+
|
|
351
340
|
for (j in 0 until ancillaryFiles.length()) {
|
|
352
341
|
val ancillary = ancillaryFiles.getJSONObject(j)
|
|
353
342
|
if(ancillary.getString("description") == subtitle.getString("language")) {
|
|
354
|
-
|
|
343
|
+
subtitleMap.putString("url", ancillary.getString("playbackUrl").toString())
|
|
355
344
|
}
|
|
356
345
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
346
|
+
subtitleMap.putString("language",subtitle.getString("language"))
|
|
347
|
+
subtitleMap.putString("label",subtitle.getString("label"))
|
|
348
|
+
subtitleMap.putString("format","vtt")
|
|
349
|
+
|
|
350
|
+
JsonConverter.toSubtitleTrack(subtitleMap)?.let {
|
|
351
|
+
sourceItem.addSubtitleTrack(it)
|
|
352
|
+
}
|
|
362
353
|
}
|
|
363
|
-
|
|
364
354
|
if(startOffset != null) {
|
|
365
355
|
sourceItem.options.startOffset = startOffset
|
|
366
356
|
}
|
|
367
|
-
|
|
368
357
|
player.load(sourceItem)
|
|
369
358
|
promise.resolve(true)
|
|
370
359
|
}
|
|
@@ -372,9 +361,8 @@ class OfflineVideoEngine(private val context: ReactApplicationContext) {
|
|
|
372
361
|
}
|
|
373
362
|
promise.reject("Error", "Error loading asset")
|
|
374
363
|
}
|
|
375
|
-
|
|
364
|
+
|
|
376
365
|
private fun uiManager(): UIManagerModule? =
|
|
377
366
|
context.getNativeModule(UIManagerModule::class.java)
|
|
378
|
-
|
|
379
|
-
|
|
367
|
+
|
|
380
368
|
}
|