@100mslive/react-native-hms 0.9.3 → 0.9.4

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.
@@ -63,7 +63,7 @@ dependencies {
63
63
  //noinspection GradleDynamicVersion
64
64
  implementation "com.facebook.react:react-native:+"
65
65
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // From node_modules
66
- implementation 'com.github.100mslive.android-sdk:lib:2.3.4'
66
+ implementation 'com.github.100mslive.android-sdk:lib:2.3.5'
67
67
  implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0'
68
68
  implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
69
69
  implementation 'androidx.appcompat:appcompat:1.3.1'
@@ -1,17 +1,33 @@
1
1
  package com.reactnativehmssdk
2
2
 
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.media.MediaScannerConnection
6
+ import android.os.Build
7
+ import android.os.Environment
8
+ import android.os.Handler
9
+ import android.util.Log
10
+ import android.view.PixelCopy
11
+ import androidx.annotation.RequiresApi
3
12
  import com.facebook.react.bridge.ReadableArray
4
13
  import com.facebook.react.bridge.ReadableMap
14
+ import live.hms.video.error.HMSException
5
15
  import live.hms.video.media.codec.HMSAudioCodec
6
16
  import live.hms.video.media.codec.HMSVideoCodec
7
17
  import live.hms.video.media.settings.HMSAudioTrackSettings
8
18
  import live.hms.video.media.settings.HMSTrackSettings
9
19
  import live.hms.video.media.settings.HMSVideoResolution
10
20
  import live.hms.video.media.settings.HMSVideoTrackSettings
11
- import live.hms.video.media.tracks.*
21
+ import live.hms.video.media.tracks.HMSRemoteAudioTrack
22
+ import live.hms.video.media.tracks.HMSRemoteVideoTrack
23
+ import live.hms.video.media.tracks.HMSTrack
12
24
  import live.hms.video.sdk.models.*
13
- import live.hms.video.sdk.models.role.*
25
+ import live.hms.video.sdk.models.role.HMSRole
14
26
  import live.hms.video.utils.HmsUtilities
27
+ import org.webrtc.SurfaceViewRenderer
28
+ import java.io.File
29
+ import java.io.FileOutputStream
30
+ import java.util.*
15
31
 
16
32
  object HmsHelper {
17
33
 
@@ -120,9 +136,7 @@ object HmsHelper {
120
136
  var useHardwareEchoCancellation = false
121
137
  val requiredKeysUseHardwareEchoCancellation =
122
138
  this.areAllRequiredKeysAvailable(
123
- data,
124
- arrayOf(Pair("useHardwareEchoCancellation", "Boolean"))
125
- )
139
+ data, arrayOf(Pair("useHardwareEchoCancellation", "Boolean")))
126
140
  if (requiredKeysUseHardwareEchoCancellation) {
127
141
  useHardwareEchoCancellation = data.getBoolean("useHardwareEchoCancellation")
128
142
  }
@@ -277,17 +291,11 @@ object HmsHelper {
277
291
  var singleFilePerLayer = false
278
292
  var videoOnDemand = false
279
293
  if (areAllRequiredKeysAvailable(
280
- hmsHlsRecordingConfig,
281
- arrayOf(Pair("singleFilePerLayer", "Boolean"))
282
- )
283
- ) {
294
+ hmsHlsRecordingConfig, arrayOf(Pair("singleFilePerLayer", "Boolean")))) {
284
295
  singleFilePerLayer = hmsHlsRecordingConfig.getBoolean("singleFilePerLayer")
285
296
  }
286
297
  if (areAllRequiredKeysAvailable(
287
- hmsHlsRecordingConfig,
288
- arrayOf(Pair("videoOnDemand", "Boolean"))
289
- )
290
- ) {
298
+ hmsHlsRecordingConfig, arrayOf(Pair("videoOnDemand", "Boolean")))) {
291
299
  videoOnDemand = hmsHlsRecordingConfig.getBoolean("videoOnDemand")
292
300
  }
293
301
  return HMSHlsRecordingConfig(singleFilePerLayer, videoOnDemand)
@@ -321,9 +329,7 @@ object HmsHelper {
321
329
  arrayOf(
322
330
  Pair("endpoint", "String"),
323
331
  Pair("metadata", "String"),
324
- Pair("captureNetworkQualityInPreview", "Boolean")
325
- )
326
- ) -> {
332
+ Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
327
333
  config =
328
334
  HMSConfig(
329
335
  credentials.getString("username") as String,
@@ -335,9 +341,7 @@ object HmsHelper {
335
341
  )
336
342
  }
337
343
  areAllRequiredKeysAvailable(
338
- credentials,
339
- arrayOf(Pair("endpoint", "String"), Pair("metadata", "String"))
340
- ) -> {
344
+ credentials, arrayOf(Pair("endpoint", "String"), Pair("metadata", "String"))) -> {
341
345
  config =
342
346
  HMSConfig(
343
347
  credentials.getString("username") as String,
@@ -348,8 +352,8 @@ object HmsHelper {
348
352
  }
349
353
  areAllRequiredKeysAvailable(
350
354
  credentials,
351
- arrayOf(Pair("endpoint", "String"), Pair("captureNetworkQualityInPreview", "Boolean"))
352
- ) -> {
355
+ arrayOf(
356
+ Pair("endpoint", "String"), Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
353
357
  config =
354
358
  HMSConfig(
355
359
  credentials.getString("username") as String,
@@ -361,8 +365,8 @@ object HmsHelper {
361
365
  }
362
366
  areAllRequiredKeysAvailable(
363
367
  credentials,
364
- arrayOf(Pair("metadata", "String"), Pair("captureNetworkQualityInPreview", "Boolean"))
365
- ) -> {
368
+ arrayOf(
369
+ Pair("metadata", "String"), Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
366
370
  config =
367
371
  HMSConfig(
368
372
  credentials.getString("username") as String,
@@ -389,18 +393,83 @@ object HmsHelper {
389
393
  )
390
394
  }
391
395
  areAllRequiredKeysAvailable(
392
- credentials,
393
- arrayOf(Pair("captureNetworkQualityInPreview", "Boolean"))
394
- ) -> {
396
+ credentials, arrayOf(Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
395
397
  config =
396
398
  HMSConfig(
397
399
  credentials.getString("username") as String,
398
400
  credentials.getString("authToken") as String,
399
401
  captureNetworkQualityInPreview =
400
- credentials.getBoolean("captureNetworkQualityInPreview")
401
- )
402
+ credentials.getBoolean("captureNetworkQualityInPreview"))
402
403
  }
403
404
  }
404
405
  return config
405
406
  }
407
+
408
+ @RequiresApi(Build.VERSION_CODES.N)
409
+ fun captureSurfaceView(surfaceView: SurfaceViewRenderer, context: Context, id: String?) {
410
+ try {
411
+ val bitmap: Bitmap =
412
+ Bitmap.createBitmap(surfaceView.width, surfaceView.height, Bitmap.Config.ARGB_8888)
413
+ PixelCopy.request(
414
+ surfaceView,
415
+ bitmap,
416
+ { copyResult ->
417
+ if (copyResult === PixelCopy.SUCCESS) {
418
+ Log.d("captureSurfaceView", "bitmap: $bitmap")
419
+ saveImage(bitmap, context, id)
420
+ } else {
421
+ HmsModule.hmsCollection[id]?.emitHMSError(
422
+ HMSException(
423
+ 103,
424
+ copyResult.toString(),
425
+ copyResult.toString(),
426
+ copyResult.toString(),
427
+ copyResult.toString()
428
+ )
429
+ )
430
+ Log.e("captureSurfaceView", "copyResult: $copyResult")
431
+ }
432
+ },
433
+ Handler()
434
+ )
435
+ } catch (e: Exception) {
436
+ Log.e("captureSurfaceView", "error: $e")
437
+ }
438
+ }
439
+
440
+ private fun saveImage(finalBitmap: Bitmap, context: Context, id: String?) {
441
+ val folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
442
+ if (!folder.exists()) {
443
+ folder.mkdir()
444
+ }
445
+ val generator = Random()
446
+ var n = 10000
447
+ n = generator.nextInt(n)
448
+ val fileName = "Image-$n.jpg"
449
+ val file = File(folder.absolutePath, fileName)
450
+ if (file.exists()) file.delete()
451
+ try {
452
+ val out = FileOutputStream(file)
453
+ finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
454
+ out.flush()
455
+ out.close()
456
+ } catch (e: Exception) {
457
+ HmsModule.hmsCollection[id]?.emitHMSError(
458
+ HMSException(
459
+ 103,
460
+ e.message.toString(),
461
+ e.message.toString(),
462
+ e.message.toString(),
463
+ e.message.toString()
464
+ )
465
+ )
466
+ Log.e("saveImage", "error: $e")
467
+ }
468
+ // Tell the media scanner about the new file so that it is
469
+ // immediately available to the user.
470
+ MediaScannerConnection.scanFile(context, arrayOf(file.toString()), null) { path, uri ->
471
+ Log.i("ExternalStorage", "Scanned $path:")
472
+ Log.i("ExternalStorage", "-> uri=$uri")
473
+ }
474
+ }
406
475
  }
@@ -37,10 +37,15 @@ class HmsScreenshareActivity : ComponentActivity() {
37
37
  )
38
38
  } else {
39
39
  val id = intent.getStringExtra("id")
40
- val data: WritableMap = Arguments.createMap()
41
- data.putBoolean("success", true)
42
- data.putString("message", "RESULT_CANCELED")
43
- HmsModule.hmsCollection[id]?.screenshareCallback?.resolve(data)
40
+ val error = HMSException(
41
+ 103,
42
+ "RESULT_CANCELED",
43
+ "RESULT_CANCELED",
44
+ "RESULT_CANCELED",
45
+ "RESULT_CANCELED"
46
+ )
47
+ HmsModule.hmsCollection[id]?.screenshareCallback?.reject(error)
48
+ HmsModule.hmsCollection[id]?.emitHMSError(error)
44
49
  finish()
45
50
  }
46
51
  }
@@ -2,8 +2,10 @@ package com.reactnativehmssdk
2
2
 
3
3
  import android.annotation.SuppressLint
4
4
  import android.content.Context
5
+ import android.os.Build
5
6
  import android.view.LayoutInflater
6
7
  import android.widget.FrameLayout
8
+ import androidx.annotation.RequiresApi
7
9
  import com.facebook.react.bridge.Arguments
8
10
  import com.facebook.react.bridge.ReactContext
9
11
  import com.facebook.react.bridge.WritableMap
@@ -19,17 +21,24 @@ class HmsView(context: ReactContext) : FrameLayout(context) {
19
21
  private var surfaceView: SurfaceViewRenderer = SurfaceViewRenderer(context)
20
22
  private var videoTrack: HMSVideoTrack? = null
21
23
  private var scaleTypeApplied: Boolean = false
24
+ private var sdkId: String = "12345"
22
25
  private var currentScaleType: RendererCommon.ScalingType =
23
- RendererCommon.ScalingType.SCALE_ASPECT_FILL
26
+ RendererCommon.ScalingType.SCALE_ASPECT_FILL
24
27
 
25
28
  init {
26
- val inflater = getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
29
+ val inflater =
30
+ getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
27
31
  val view = inflater.inflate(R.layout.hms_view, this)
28
32
 
29
33
  surfaceView = view.findViewById(R.id.surfaceView)
30
34
  surfaceView.setEnableHardwareScaler(true)
31
35
  }
32
36
 
37
+ @RequiresApi(Build.VERSION_CODES.N)
38
+ fun captureHmsView() {
39
+ HmsHelper.captureSurfaceView(surfaceView, context, sdkId)
40
+ }
41
+
33
42
  private fun onReceiveNativeEvent() {
34
43
  val event: WritableMap = Arguments.createMap()
35
44
  event.putString("message", "MyMessage")
@@ -55,6 +64,13 @@ class HmsView(context: ReactContext) : FrameLayout(context) {
55
64
  }
56
65
  }
57
66
 
67
+ fun updateZOrderMediaOverlay(setZOrderMediaOverlay: Boolean?) {
68
+ if (setZOrderMediaOverlay != null && setZOrderMediaOverlay) {
69
+ // surfaceView.setZOrderOnTop(true);
70
+ surfaceView.setZOrderMediaOverlay(setZOrderMediaOverlay)
71
+ }
72
+ }
73
+
58
74
  fun updateScaleType(scaleType: String?) {
59
75
  if (scaleType != null) {
60
76
  when (scaleType) {
@@ -81,12 +97,11 @@ class HmsView(context: ReactContext) : FrameLayout(context) {
81
97
  }
82
98
 
83
99
  fun setData(
84
- id: String?,
85
- trackId: String?,
86
- hmsCollection: MutableMap<String, HmsSDK>,
87
- mirror: Boolean?
100
+ id: String?,
101
+ trackId: String?,
102
+ hmsCollection: MutableMap<String, HmsSDK>,
103
+ mirror: Boolean?
88
104
  ) {
89
- var sdkId = "12345"
90
105
  if (id != null) {
91
106
  sdkId = id
92
107
  }
@@ -1,5 +1,7 @@
1
1
  package com.reactnativehmssdk
2
2
 
3
+ import android.os.Build
4
+ import androidx.annotation.RequiresApi
3
5
  import com.facebook.react.bridge.ReadableMap
4
6
  import com.facebook.react.common.MapBuilder
5
7
  import com.facebook.react.uimanager.SimpleViewManager
@@ -44,6 +46,19 @@ class HmssdkViewManager : SimpleViewManager<HmsView>() {
44
46
  view.updateScaleType(data)
45
47
  }
46
48
 
49
+ @ReactProp(name = "setZOrderMediaOverlay")
50
+ fun setZOrderMediaOverlay(view: HmsView, data: Boolean?) {
51
+ view.updateZOrderMediaOverlay(data)
52
+ }
53
+
54
+ @RequiresApi(Build.VERSION_CODES.N)
55
+ @ReactProp(name = "screenshot")
56
+ fun setCaptureHmsView(view: HmsView, screenshot: Boolean?) {
57
+ if(screenshot == true){
58
+ view.captureHmsView()
59
+ }
60
+ }
61
+
47
62
  private fun getHms(): MutableMap<String, HmsSDK>? {
48
63
  return reactContext?.getNativeModule(HmsModule::class.java)?.getHmsInstance()
49
64
  }
@@ -19,8 +19,6 @@ var _HMSHelper = require("./HMSHelper");
19
19
 
20
20
  var _HmsView = require("./HmsView");
21
21
 
22
- var _HMSVideoViewMode = require("./HMSVideoViewMode");
23
-
24
22
  var _HMSLocalAudioStats = require("./HMSLocalAudioStats");
25
23
 
26
24
  var _HMSLocalVideoStats = require("./HMSLocalVideoStats");
@@ -202,15 +200,19 @@ class HMSSDK {
202
200
  trackId,
203
201
  style,
204
202
  mirror,
205
- scaleType = _HMSVideoViewMode.HMSVideoViewMode.ASPECT_FIT
203
+ scaleType,
204
+ screenshot,
205
+ setZOrderMediaOverlay
206
206
  } = _ref;
207
207
  return /*#__PURE__*/_react.default.createElement(_HmsView.HmsView, {
208
208
  sink: sink,
209
209
  trackId: trackId,
210
210
  style: style,
211
+ setZOrderMediaOverlay: setZOrderMediaOverlay,
211
212
  mirror: mirror,
212
213
  scaleType: scaleType,
213
- id: this.id
214
+ id: this.id,
215
+ screenshot: screenshot
214
216
  });
215
217
  });
216
218