@100mslive/react-native-hms 0.9.9 → 0.9.91

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 (84) hide show
  1. package/README.md +50 -43
  2. package/android/.gradle/6.9/fileHashes/fileHashes.bin +0 -0
  3. package/android/.gradle/6.9/fileHashes/fileHashes.lock +0 -0
  4. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  5. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  6. package/android/.gradle/checksums/checksums.lock +0 -0
  7. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  8. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  9. package/android/.idea/libraries/{Gradle__com_github_100mslive_android_sdk_lib_2_4_2_aar.xml → Gradle__com_github_100mslive_android_sdk_lib_2_4_7_aar.xml} +4 -4
  10. package/android/.idea/libraries/Gradle__com_github_100mslive_webrtc_m97_hms_1_1_aar.xml +11 -0
  11. package/android/.idea/modules/android.androidTest.iml +4 -4
  12. package/android/.idea/modules/android.main.iml +4 -4
  13. package/android/.idea/modules/android.unitTest.iml +4 -4
  14. package/android/build.gradle +2 -2
  15. package/android/src/main/java/com/reactnativehmssdk/HMSAudioshareActivity.kt +84 -0
  16. package/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt +77 -8
  17. package/android/src/main/java/com/reactnativehmssdk/HMSHelper.kt +95 -22
  18. package/android/src/main/java/com/reactnativehmssdk/HMSManager.kt +86 -0
  19. package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +255 -34
  20. package/ios/HMSDecoder.swift +9 -8
  21. package/ios/HMSHelper.swift +5 -8
  22. package/ios/HMSManager.swift +5 -4
  23. package/ios/HMSRNSDK.swift +27 -32
  24. package/lib/commonjs/classes/HMSAudioDevice.js +17 -0
  25. package/lib/commonjs/classes/HMSAudioDevice.js.map +1 -0
  26. package/lib/commonjs/classes/HMSAudioMixingMode.js +15 -0
  27. package/lib/commonjs/classes/HMSAudioMixingMode.js.map +1 -0
  28. package/lib/commonjs/classes/HMSAudioMode.js +17 -0
  29. package/lib/commonjs/classes/HMSAudioMode.js.map +1 -0
  30. package/lib/commonjs/classes/HMSEncoder.js +15 -0
  31. package/lib/commonjs/classes/HMSEncoder.js.map +1 -1
  32. package/lib/commonjs/classes/HMSException.js +18 -13
  33. package/lib/commonjs/classes/HMSException.js.map +1 -1
  34. package/lib/commonjs/classes/HMSHLSConfig.js.map +1 -1
  35. package/lib/commonjs/classes/HMSPermissions.js +7 -4
  36. package/lib/commonjs/classes/HMSPermissions.js.map +1 -1
  37. package/lib/commonjs/classes/HMSSDK.js +184 -9
  38. package/lib/commonjs/classes/HMSSDK.js.map +1 -1
  39. package/lib/commonjs/classes/HMSUpdateListenerActions.js +1 -0
  40. package/lib/commonjs/classes/HMSUpdateListenerActions.js.map +1 -1
  41. package/lib/commonjs/index.js +42 -0
  42. package/lib/commonjs/index.js.map +1 -1
  43. package/lib/module/classes/HMSAudioDevice.js +10 -0
  44. package/lib/module/classes/HMSAudioDevice.js.map +1 -0
  45. package/lib/module/classes/HMSAudioMixingMode.js +8 -0
  46. package/lib/module/classes/HMSAudioMixingMode.js.map +1 -0
  47. package/lib/module/classes/HMSAudioMode.js +10 -0
  48. package/lib/module/classes/HMSAudioMode.js.map +1 -0
  49. package/lib/module/classes/HMSEncoder.js +14 -0
  50. package/lib/module/classes/HMSEncoder.js.map +1 -1
  51. package/lib/module/classes/HMSException.js +18 -13
  52. package/lib/module/classes/HMSException.js.map +1 -1
  53. package/lib/module/classes/HMSHLSConfig.js.map +1 -1
  54. package/lib/module/classes/HMSPermissions.js +7 -4
  55. package/lib/module/classes/HMSPermissions.js.map +1 -1
  56. package/lib/module/classes/HMSSDK.js +184 -9
  57. package/lib/module/classes/HMSSDK.js.map +1 -1
  58. package/lib/module/classes/HMSUpdateListenerActions.js +1 -0
  59. package/lib/module/classes/HMSUpdateListenerActions.js.map +1 -1
  60. package/lib/module/index.js +3 -0
  61. package/lib/module/index.js.map +1 -1
  62. package/lib/typescript/classes/HMSAudioDevice.d.ts +7 -0
  63. package/lib/typescript/classes/HMSAudioMixingMode.d.ts +5 -0
  64. package/lib/typescript/classes/HMSAudioMode.d.ts +7 -0
  65. package/lib/typescript/classes/HMSEncoder.d.ts +2 -0
  66. package/lib/typescript/classes/HMSException.d.ts +8 -14
  67. package/lib/typescript/classes/HMSHLSConfig.d.ts +2 -2
  68. package/lib/typescript/classes/HMSPermissions.d.ts +6 -4
  69. package/lib/typescript/classes/HMSSDK.d.ts +105 -7
  70. package/lib/typescript/classes/HMSUpdateListenerActions.d.ts +2 -1
  71. package/lib/typescript/index.d.ts +3 -0
  72. package/package.json +1 -1
  73. package/react-native-hms.podspec +1 -1
  74. package/src/classes/HMSAudioDevice.ts +7 -0
  75. package/src/classes/HMSAudioMixingMode.ts +5 -0
  76. package/src/classes/HMSAudioMode.ts +7 -0
  77. package/src/classes/HMSEncoder.ts +12 -0
  78. package/src/classes/HMSException.ts +15 -24
  79. package/src/classes/HMSHLSConfig.ts +2 -2
  80. package/src/classes/HMSPermissions.ts +9 -6
  81. package/src/classes/HMSSDK.tsx +250 -16
  82. package/src/classes/HMSUpdateListenerActions.ts +1 -0
  83. package/src/index.ts +3 -0
  84. package/android/.idea/libraries/Gradle__com_github_100mslive_webrtc_m97_aar.xml +0 -11
@@ -15,6 +15,7 @@ import com.facebook.react.bridge.ReadableMap
15
15
  import com.facebook.react.uimanager.events.RCTEventEmitter
16
16
  import java.io.ByteArrayOutputStream
17
17
  import java.util.*
18
+ import live.hms.video.audio.HMSAudioManager
18
19
  import live.hms.video.error.HMSException
19
20
  import live.hms.video.media.codec.HMSAudioCodec
20
21
  import live.hms.video.media.codec.HMSVideoCodec
@@ -23,6 +24,7 @@ import live.hms.video.media.tracks.HMSRemoteAudioTrack
23
24
  import live.hms.video.media.tracks.HMSRemoteVideoTrack
24
25
  import live.hms.video.media.tracks.HMSTrack
25
26
  import live.hms.video.sdk.models.*
27
+ import live.hms.video.sdk.models.enums.AudioMixingMode
26
28
  import live.hms.video.sdk.models.role.HMSRole
27
29
  import live.hms.video.utils.HmsUtilities
28
30
  import org.webrtc.SurfaceViewRenderer
@@ -248,6 +250,21 @@ object HMSHelper {
248
250
  }
249
251
  }
250
252
 
253
+ fun getAudioMixingMode(audioMixingMode: String?): AudioMixingMode {
254
+ when (audioMixingMode) {
255
+ "TALK_ONLY" -> {
256
+ return AudioMixingMode.TALK_ONLY
257
+ }
258
+ "MUSIC_ONLY" -> {
259
+ return AudioMixingMode.MUSIC_ONLY
260
+ }
261
+ "TALK_AND_MUSIC" -> {
262
+ return AudioMixingMode.TALK_AND_MUSIC
263
+ }
264
+ }
265
+ return AudioMixingMode.TALK_AND_MUSIC
266
+ }
267
+
251
268
  private fun getAudioCodec(codecString: String?): HMSAudioCodec {
252
269
  when (codecString) {
253
270
  "opus" -> {
@@ -304,7 +321,25 @@ object HMSHelper {
304
321
  return rtmpURLs
305
322
  }
306
323
 
307
- fun getHMSHLSMeetingURLVariants(
324
+ fun getHLSConfig(data: ReadableMap?): HMSHLSConfig? {
325
+ if (data === null) {
326
+ return data
327
+ }
328
+ var hlsMeetingUrlVariant: List<HMSHLSMeetingURLVariant>? = null
329
+ if (areAllRequiredKeysAvailable(data, arrayOf(Pair("meetingURLVariants", "Array")))) {
330
+ val meetingURLVariants =
331
+ data.getArray("meetingURLVariants")?.toArrayList() as? ArrayList<HashMap<String, String>>
332
+ hlsMeetingUrlVariant = getHMSHLSMeetingURLVariants(meetingURLVariants)
333
+ }
334
+ var hlsRecordingConfig: HMSHlsRecordingConfig? = null
335
+ if (areAllRequiredKeysAvailable(data, arrayOf(Pair("hlsRecordingConfig", "Map")))) {
336
+ val recordingConfig = data.getMap("hlsRecordingConfig")
337
+ hlsRecordingConfig = getHlsRecordingConfig(recordingConfig)
338
+ }
339
+ return HMSHLSConfig(hlsMeetingUrlVariant, hlsRecordingConfig)
340
+ }
341
+
342
+ private fun getHMSHLSMeetingURLVariants(
308
343
  hmsMeetingURLVariants: ArrayList<HashMap<String, String>>?
309
344
  ): List<HMSHLSMeetingURLVariant> {
310
345
  val meetingURLVariants = mutableListOf<HMSHLSMeetingURLVariant>()
@@ -317,28 +352,25 @@ object HMSHelper {
317
352
  return meetingURLVariants
318
353
  }
319
354
 
320
- fun getHlsRecordingConfig(data: ReadableMap): HMSHlsRecordingConfig? {
321
- if (areAllRequiredKeysAvailable(data, arrayOf(Pair("hlsRecordingConfig", "Map")))) {
322
- val hmsHlsRecordingConfig = data.getMap("hlsRecordingConfig")
323
- if (hmsHlsRecordingConfig != null) {
324
- var singleFilePerLayer = false
325
- var videoOnDemand = false
326
- if (areAllRequiredKeysAvailable(
327
- hmsHlsRecordingConfig,
328
- arrayOf(Pair("singleFilePerLayer", "Boolean"))
329
- )
330
- ) {
331
- singleFilePerLayer = hmsHlsRecordingConfig.getBoolean("singleFilePerLayer")
332
- }
333
- if (areAllRequiredKeysAvailable(
334
- hmsHlsRecordingConfig,
335
- arrayOf(Pair("videoOnDemand", "Boolean"))
336
- )
337
- ) {
338
- videoOnDemand = hmsHlsRecordingConfig.getBoolean("videoOnDemand")
339
- }
340
- return HMSHlsRecordingConfig(singleFilePerLayer, videoOnDemand)
355
+ private fun getHlsRecordingConfig(hmsHlsRecordingConfig: ReadableMap?): HMSHlsRecordingConfig? {
356
+ if (hmsHlsRecordingConfig !== null) {
357
+ var singleFilePerLayer = false
358
+ var videoOnDemand = false
359
+ if (areAllRequiredKeysAvailable(
360
+ hmsHlsRecordingConfig,
361
+ arrayOf(Pair("singleFilePerLayer", "Boolean"))
362
+ )
363
+ ) {
364
+ singleFilePerLayer = hmsHlsRecordingConfig.getBoolean("singleFilePerLayer")
341
365
  }
366
+ if (areAllRequiredKeysAvailable(
367
+ hmsHlsRecordingConfig,
368
+ arrayOf(Pair("videoOnDemand", "Boolean"))
369
+ )
370
+ ) {
371
+ videoOnDemand = hmsHlsRecordingConfig.getBoolean("videoOnDemand")
372
+ }
373
+ return HMSHlsRecordingConfig(singleFilePerLayer, videoOnDemand)
342
374
  }
343
375
  return null
344
376
  }
@@ -542,4 +574,45 @@ object HMSHelper {
542
574
  reactContext.getJSModule(RCTEventEmitter::class.java).receiveEvent(id, "captureFrame", output)
543
575
  }
544
576
  }
577
+
578
+ fun getAudioDevicesList(audioDevicesList: List<HMSAudioManager.AudioDevice>?): ReadableArray {
579
+ val hmsAudioDevicesList = Arguments.createArray()
580
+ if (audioDevicesList != null) {
581
+ for (audioDevice in audioDevicesList) {
582
+ hmsAudioDevicesList.pushString(audioDevice.name)
583
+ }
584
+ }
585
+ return hmsAudioDevicesList
586
+ }
587
+
588
+ fun getAudioDevicesSet(audioDevicesSet: Set<HMSAudioManager.AudioDevice>?): ReadableArray {
589
+ val hmsAudioDevicesSet = Arguments.createArray()
590
+ if (audioDevicesSet != null) {
591
+ for (audioDevice in audioDevicesSet) {
592
+ hmsAudioDevicesSet.pushString(audioDevice.name)
593
+ }
594
+ }
595
+ return hmsAudioDevicesSet
596
+ }
597
+
598
+ fun getAudioDevice(audioDevice: String?): HMSAudioManager.AudioDevice {
599
+ when (audioDevice) {
600
+ "AUTOMATIC" -> {
601
+ return HMSAudioManager.AudioDevice.AUTOMATIC
602
+ }
603
+ "BLUETOOTH" -> {
604
+ return HMSAudioManager.AudioDevice.BLUETOOTH
605
+ }
606
+ "EARPIECE" -> {
607
+ return HMSAudioManager.AudioDevice.EARPIECE
608
+ }
609
+ "SPEAKER_PHONE" -> {
610
+ return HMSAudioManager.AudioDevice.SPEAKER_PHONE
611
+ }
612
+ "WIRED_HEADSET" -> {
613
+ return HMSAudioManager.AudioDevice.WIRED_HEADSET
614
+ }
615
+ }
616
+ return HMSAudioManager.AudioDevice.SPEAKER_PHONE
617
+ }
545
618
  }
@@ -238,6 +238,43 @@ class HMSManager(reactContext: ReactApplicationContext) :
238
238
  hms?.stopScreenshare(callback)
239
239
  }
240
240
 
241
+ @ReactMethod
242
+ fun startAudioshare(data: ReadableMap, callback: Promise?) {
243
+ currentActivity?.application?.registerActivityLifecycleCallbacks(this)
244
+ val hms = HMSHelper.getHms(data, hmsCollection)
245
+
246
+ hms?.startAudioshare(data, callback)
247
+ }
248
+
249
+ @ReactMethod
250
+ fun isAudioShared(data: ReadableMap, callback: Promise?) {
251
+ val hms = HMSHelper.getHms(data, hmsCollection)
252
+
253
+ hms?.isAudioShared(callback)
254
+ }
255
+
256
+ @ReactMethod
257
+ fun stopAudioshare(data: ReadableMap, callback: Promise?) {
258
+ val hms = HMSHelper.getHms(data, hmsCollection)
259
+
260
+ currentActivity?.application?.unregisterActivityLifecycleCallbacks(this)
261
+ hms?.stopAudioshare(callback)
262
+ }
263
+
264
+ @ReactMethod
265
+ fun getAudioMixingMode(data: ReadableMap, callback: Promise?) {
266
+ val hms = HMSHelper.getHms(data, hmsCollection)
267
+
268
+ callback?.resolve(hms?.getAudioMixingMode()?.name)
269
+ }
270
+
271
+ @ReactMethod
272
+ fun setAudioMixingMode(data: ReadableMap, callback: Promise?) {
273
+ val hms = HMSHelper.getHms(data, hmsCollection)
274
+
275
+ hms?.setAudioMixingMode(data, callback)
276
+ }
277
+
241
278
  @ReactMethod
242
279
  fun startRTMPOrRecording(data: ReadableMap, callback: Promise?) {
243
280
  val hms = HMSHelper.getHms(data, hmsCollection)
@@ -290,6 +327,55 @@ class HMSManager(reactContext: ReactApplicationContext) :
290
327
  callback?.resolve(result)
291
328
  }
292
329
 
330
+ @ReactMethod
331
+ fun enableRTCStats(data: ReadableMap) {
332
+ val hms = HMSHelper.getHms(data, hmsCollection)
333
+
334
+ hms?.enableRTCStats()
335
+ }
336
+
337
+ @ReactMethod
338
+ fun disableRTCStats(data: ReadableMap) {
339
+ val hms = HMSHelper.getHms(data, hmsCollection)
340
+
341
+ hms?.disableRTCStats()
342
+ }
343
+
344
+ @ReactMethod
345
+ fun getAudioDevicesList(data: ReadableMap, callback: Promise?) {
346
+ val hms = HMSHelper.getHms(data, hmsCollection)
347
+
348
+ hms?.getAudioDevicesList(callback)
349
+ }
350
+
351
+ @ReactMethod
352
+ fun getAudioOutputRouteType(data: ReadableMap, callback: Promise?) {
353
+ val hms = HMSHelper.getHms(data, hmsCollection)
354
+
355
+ hms?.getAudioOutputRouteType(callback)
356
+ }
357
+
358
+ @ReactMethod
359
+ fun switchAudioOutput(data: ReadableMap) {
360
+ val hms = HMSHelper.getHms(data, hmsCollection)
361
+
362
+ hms?.switchAudioOutput(data)
363
+ }
364
+
365
+ @ReactMethod
366
+ fun setAudioMode(data: ReadableMap) {
367
+ val hms = HMSHelper.getHms(data, hmsCollection)
368
+
369
+ hms?.setAudioMode(data)
370
+ }
371
+
372
+ @ReactMethod
373
+ fun setAudioDeviceChangeListener(data: ReadableMap) {
374
+ val hms = HMSHelper.getHms(data, hmsCollection)
375
+
376
+ hms?.setAudioDeviceChangeListener()
377
+ }
378
+
293
379
  fun emitEvent(event: String, data: WritableMap) {
294
380
  reactApplicationContext
295
381
  .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
@@ -6,12 +6,13 @@ import com.facebook.react.bridge.*
6
6
  import com.facebook.react.bridge.UiThreadUtil.runOnUiThread
7
7
  import java.util.*
8
8
  import kotlinx.coroutines.launch
9
+ import live.hms.video.audio.HMSAudioManager
10
+ import live.hms.video.connection.stats.*
9
11
  import live.hms.video.error.HMSException
10
- import live.hms.video.media.tracks.HMSRemoteAudioTrack
11
- import live.hms.video.media.tracks.HMSTrack
12
- import live.hms.video.media.tracks.HMSTrackType
12
+ import live.hms.video.media.tracks.*
13
13
  import live.hms.video.sdk.*
14
14
  import live.hms.video.sdk.models.*
15
+ import live.hms.video.sdk.models.enums.AudioMixingMode
15
16
  import live.hms.video.sdk.models.enums.HMSPeerUpdate
16
17
  import live.hms.video.sdk.models.enums.HMSRoomUpdate
17
18
  import live.hms.video.sdk.models.enums.HMSTrackUpdate
@@ -27,11 +28,15 @@ class HMSRNSDK(
27
28
  ) {
28
29
  var hmsSDK: HMSSDK? = null
29
30
  var screenshareCallback: Promise? = null
31
+ var audioshareCallback: Promise? = null
32
+ var isAudioSharing: Boolean = false
30
33
  var delegate: HMSManager = HmsDelegate
31
34
  private var recentRoleChangeRequest: HMSRoleChangeRequest? = null
32
35
  private var context: ReactApplicationContext = reactApplicationContext
33
36
  private var previewInProgress: Boolean = false
34
37
  private var reconnectingStage: Boolean = false
38
+ private var rtcStatsAttached: Boolean = false
39
+ private var audioMixingMode: AudioMixingMode = AudioMixingMode.TALK_AND_MUSIC
35
40
  private var id: String = sdkId
36
41
  private var self = this
37
42
 
@@ -46,8 +51,7 @@ class HMSRNSDK(
46
51
 
47
52
  private fun emitCustomError(message: String) {
48
53
  val data: WritableMap = Arguments.createMap()
49
- val hmsError = HMSException(102, message, message, message, message)
50
- data.putString("event", "ON_ERROR")
54
+ val hmsError = HMSException(6002, message, message, message, message, null, false)
51
55
  data.putString("id", id)
52
56
  data.putMap("error", HMSDecoder.getError(hmsError))
53
57
  delegate.emitEvent("ON_ERROR", data)
@@ -56,20 +60,26 @@ class HMSRNSDK(
56
60
  private fun emitRequiredKeysError(message: String) {
57
61
  val data: WritableMap = Arguments.createMap()
58
62
  val hmsError =
59
- HMSException(102, "REQUIRED_KEYS_NOT_FOUND", "SEND_ALL_REQUIRED_KEYS", message, message)
60
- data.putString("event", "ON_ERROR")
63
+ HMSException(
64
+ 6002,
65
+ "REQUIRED_KEYS_NOT_FOUND",
66
+ "SEND_ALL_REQUIRED_KEYS",
67
+ message,
68
+ message,
69
+ null,
70
+ false
71
+ )
61
72
  data.putString("id", id)
62
73
  data.putMap("error", HMSDecoder.getError(hmsError))
63
74
  delegate.emitEvent("ON_ERROR", data)
64
75
  }
65
76
 
66
77
  private fun rejectCallback(callback: Promise?, message: String) {
67
- callback?.reject("102", message)
78
+ callback?.reject("6002", message)
68
79
  }
69
80
 
70
81
  fun emitHMSError(error: HMSException) {
71
82
  val data: WritableMap = Arguments.createMap()
72
- data.putString("event", "ON_ERROR")
73
83
  data.putString("id", id)
74
84
  data.putMap("error", HMSDecoder.getError(error))
75
85
  delegate.emitEvent("ON_ERROR", data)
@@ -361,6 +371,109 @@ class HMSRNSDK(
361
371
  }
362
372
  }
363
373
  )
374
+
375
+ hmsSDK?.addRtcStatsObserver(
376
+ object : HMSStatsObserver {
377
+ override fun onLocalAudioStats(
378
+ audioStats: HMSLocalAudioStats,
379
+ hmsTrack: HMSTrack?,
380
+ hmsPeer: HMSPeer?
381
+ ) {
382
+ if (!rtcStatsAttached) {
383
+ return
384
+ }
385
+ val localAudioStats = HMSDecoder.getLocalAudioStats(audioStats)
386
+ val track = HMSDecoder.getHmsLocalAudioTrack(hmsTrack as HMSLocalAudioTrack)
387
+ val peer = HMSDecoder.getHmsPeer(hmsPeer)
388
+
389
+ val data: WritableMap = Arguments.createMap()
390
+ data.putMap("localAudioStats", localAudioStats)
391
+ data.putMap("track", track)
392
+ data.putMap("peer", peer)
393
+ data.putString("id", id)
394
+ delegate.emitEvent("ON_LOCAL_AUDIO_STATS", data)
395
+ }
396
+
397
+ override fun onLocalVideoStats(
398
+ videoStats: HMSLocalVideoStats,
399
+ hmsTrack: HMSTrack?,
400
+ hmsPeer: HMSPeer?
401
+ ) {
402
+ if (!rtcStatsAttached) {
403
+ return
404
+ }
405
+
406
+ val localVideoStats = HMSDecoder.getLocalVideoStats(videoStats)
407
+ val track = HMSDecoder.getHmsLocalVideoTrack(hmsTrack as HMSLocalVideoTrack)
408
+ val peer = HMSDecoder.getHmsPeer(hmsPeer)
409
+
410
+ val data: WritableMap = Arguments.createMap()
411
+ data.putMap("localVideoStats", localVideoStats)
412
+ data.putMap("track", track)
413
+ data.putMap("peer", peer)
414
+ data.putString("id", id)
415
+ delegate.emitEvent("ON_LOCAL_VIDEO_STATS", data)
416
+ }
417
+
418
+ override fun onRTCStats(rtcStats: HMSRTCStatsReport) {
419
+ if (!rtcStatsAttached) {
420
+ return
421
+ }
422
+ val video = HMSDecoder.getHMSRTCStats(rtcStats.video)
423
+ val audio = HMSDecoder.getHMSRTCStats(rtcStats.audio)
424
+ val combined = HMSDecoder.getHMSRTCStats(rtcStats.combined)
425
+
426
+ val data: WritableMap = Arguments.createMap()
427
+ data.putMap("video", video)
428
+ data.putMap("audio", audio)
429
+ data.putMap("combined", combined)
430
+ data.putString("id", id)
431
+ delegate.emitEvent("ON_RTC_STATS", data)
432
+ }
433
+
434
+ override fun onRemoteAudioStats(
435
+ audioStats: HMSRemoteAudioStats,
436
+ hmsTrack: HMSTrack?,
437
+ hmsPeer: HMSPeer?
438
+ ) {
439
+ if (!rtcStatsAttached) {
440
+ return
441
+ }
442
+
443
+ val remoteAudioStats = HMSDecoder.getRemoteAudioStats(audioStats)
444
+ val track = HMSDecoder.getHmsRemoteAudioTrack(hmsTrack as HMSRemoteAudioTrack)
445
+ val peer = HMSDecoder.getHmsPeer(hmsPeer)
446
+
447
+ val data: WritableMap = Arguments.createMap()
448
+ data.putMap("remoteAudioStats", remoteAudioStats)
449
+ data.putMap("track", track)
450
+ data.putMap("peer", peer)
451
+ data.putString("id", id)
452
+ delegate.emitEvent("ON_REMOTE_AUDIO_STATS", data)
453
+ }
454
+
455
+ override fun onRemoteVideoStats(
456
+ videoStats: HMSRemoteVideoStats,
457
+ hmsTrack: HMSTrack?,
458
+ hmsPeer: HMSPeer?
459
+ ) {
460
+ if (!rtcStatsAttached) {
461
+ return
462
+ }
463
+
464
+ val remoteVideoStats = HMSDecoder.getRemoteVideoStats(videoStats)
465
+ val track = HMSDecoder.getHmsRemoteVideoTrack(hmsTrack as HMSRemoteVideoTrack)
466
+ val peer = HMSDecoder.getHmsPeer(hmsPeer)
467
+
468
+ val data: WritableMap = Arguments.createMap()
469
+ data.putMap("remoteVideoStats", remoteVideoStats)
470
+ data.putMap("track", track)
471
+ data.putMap("peer", peer)
472
+ data.putString("id", id)
473
+ delegate.emitEvent("ON_REMOTE_VIDEO_STATS", data)
474
+ }
475
+ }
476
+ )
364
477
  }
365
478
  } else {
366
479
  val errorMessage = "join: $requiredKeys"
@@ -391,7 +504,9 @@ class HMSRNSDK(
391
504
  hmsSDK?.leave(
392
505
  object : HMSActionResultListener {
393
506
  override fun onSuccess() {
507
+ isAudioSharing = false
394
508
  screenshareCallback = null
509
+ audioshareCallback = null
395
510
  callback?.resolve(emitHMSSuccess())
396
511
  }
397
512
 
@@ -991,32 +1106,19 @@ class HMSRNSDK(
991
1106
  }
992
1107
 
993
1108
  fun startHLSStreaming(data: ReadableMap, callback: Promise?) {
994
- val requiredKeys =
995
- HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("meetingURLVariants", "Array")))
996
- if (requiredKeys === null) {
997
- val meetingURLVariants =
998
- data.getArray("meetingURLVariants")?.toArrayList() as? ArrayList<HashMap<String, String>>
999
- val hlsMeetingUrlVariant = HMSHelper.getHMSHLSMeetingURLVariants(meetingURLVariants)
1000
- val hlsRecordingConfig = HMSHelper.getHlsRecordingConfig(data)
1001
- val config = HMSHLSConfig(hlsMeetingUrlVariant, hlsRecordingConfig)
1002
-
1003
- hmsSDK?.startHLSStreaming(
1004
- config,
1005
- object : HMSActionResultListener {
1006
- override fun onSuccess() {
1007
- callback?.resolve(emitHMSSuccess())
1008
- }
1009
- override fun onError(error: HMSException) {
1010
- callback?.reject(error.code.toString(), error.message)
1011
- self.emitHMSError(error)
1012
- }
1109
+ val hlsConfig = HMSHelper.getHLSConfig(data)
1110
+ hmsSDK?.startHLSStreaming(
1111
+ hlsConfig,
1112
+ object : HMSActionResultListener {
1113
+ override fun onSuccess() {
1114
+ callback?.resolve(emitHMSSuccess())
1013
1115
  }
1014
- )
1015
- } else {
1016
- val errorMessage = "startHLSStreaming: $requiredKeys"
1017
- self.emitRequiredKeysError(errorMessage)
1018
- rejectCallback(callback, errorMessage)
1019
- }
1116
+ override fun onError(error: HMSException) {
1117
+ callback?.reject(error.code.toString(), error.message)
1118
+ self.emitHMSError(error)
1119
+ }
1120
+ }
1121
+ )
1020
1122
  }
1021
1123
 
1022
1124
  fun stopHLSStreaming(callback: Promise?) {
@@ -1083,4 +1185,123 @@ class HMSRNSDK(
1083
1185
  rejectCallback(callback, errorMessage)
1084
1186
  }
1085
1187
  }
1188
+
1189
+ fun enableRTCStats() {
1190
+ rtcStatsAttached = true
1191
+ }
1192
+
1193
+ fun disableRTCStats() {
1194
+ rtcStatsAttached = false
1195
+ }
1196
+
1197
+ fun getAudioDevicesList(callback: Promise?) {
1198
+ callback?.resolve(HMSHelper.getAudioDevicesList(hmsSDK?.getAudioDevicesList()))
1199
+ }
1200
+
1201
+ fun getAudioOutputRouteType(callback: Promise?) {
1202
+ callback?.resolve(hmsSDK?.getAudioOutputRouteType()?.name)
1203
+ }
1204
+
1205
+ fun switchAudioOutput(data: ReadableMap) {
1206
+ val requiredKeys =
1207
+ HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("audioDevice", "String")))
1208
+ if (requiredKeys === null) {
1209
+ val audioDevice = data.getString("audioDevice")
1210
+ hmsSDK?.switchAudioOutput(HMSHelper.getAudioDevice(audioDevice))
1211
+ } else {
1212
+ val errorMessage = "switchAudioOutput: $requiredKeys"
1213
+ self.emitRequiredKeysError(errorMessage)
1214
+ }
1215
+ }
1216
+
1217
+ fun setAudioMode(data: ReadableMap) {
1218
+ val requiredKeys = HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("audioMode", "Int")))
1219
+ if (requiredKeys === null) {
1220
+ val audioMode = data.getInt("audioMode")
1221
+ hmsSDK?.setAudioMode(audioMode)
1222
+ } else {
1223
+ val errorMessage = "setAudioMode: $requiredKeys"
1224
+ self.emitRequiredKeysError(errorMessage)
1225
+ }
1226
+ }
1227
+
1228
+ fun setAudioDeviceChangeListener() {
1229
+ hmsSDK?.setAudioDeviceChangeListener(
1230
+ object : HMSAudioManager.AudioManagerDeviceChangeListener {
1231
+ override fun onAudioDeviceChanged(
1232
+ device: HMSAudioManager.AudioDevice?,
1233
+ audioDevicesList: Set<HMSAudioManager.AudioDevice>?
1234
+ ) {
1235
+ val data: WritableMap = Arguments.createMap()
1236
+ data.putString("device", device?.name)
1237
+ data.putArray("audioDevicesList", HMSHelper.getAudioDevicesSet(audioDevicesList))
1238
+ data.putString("id", id)
1239
+ delegate.emitEvent("ON_AUDIO_DEVICE_CHANGED", data)
1240
+ }
1241
+
1242
+ override fun onError(error: HMSException) {
1243
+ self.emitHMSError(error)
1244
+ }
1245
+ }
1246
+ )
1247
+ }
1248
+
1249
+ fun startAudioshare(data: ReadableMap, callback: Promise?) {
1250
+ val requiredKeys =
1251
+ HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("audioMixingMode", "String")))
1252
+ if (requiredKeys === null) {
1253
+ audioshareCallback = callback
1254
+ runOnUiThread {
1255
+ val intent = Intent(context, HMSAudioshareActivity::class.java)
1256
+ intent.flags = FLAG_ACTIVITY_NEW_TASK
1257
+ intent.putExtra("id", id)
1258
+ intent.putExtra("audioMixingMode", data.getString("audioMixingMode"))
1259
+ context.startActivity(intent)
1260
+ }
1261
+ } else {
1262
+ val errorMessage = "startAudioshare: $requiredKeys"
1263
+ self.emitRequiredKeysError(errorMessage)
1264
+ rejectCallback(callback, errorMessage)
1265
+ }
1266
+ }
1267
+
1268
+ fun isAudioShared(callback: Promise?) {
1269
+ callback?.resolve(isAudioSharing)
1270
+ }
1271
+
1272
+ fun stopAudioshare(callback: Promise?) {
1273
+ hmsSDK?.stopAudioshare(
1274
+ object : HMSActionResultListener {
1275
+ override fun onError(error: HMSException) {
1276
+ audioshareCallback = null
1277
+ callback?.reject(error.code.toString(), error.message)
1278
+ self.emitHMSError(error)
1279
+ }
1280
+ override fun onSuccess() {
1281
+ isAudioSharing = false
1282
+ audioshareCallback = null
1283
+ callback?.resolve(emitHMSSuccess())
1284
+ }
1285
+ }
1286
+ )
1287
+ }
1288
+
1289
+ fun getAudioMixingMode(): AudioMixingMode {
1290
+ return audioMixingMode
1291
+ }
1292
+
1293
+ fun setAudioMixingMode(data: ReadableMap, callback: Promise?) {
1294
+ val requiredKeys =
1295
+ HMSHelper.getUnavailableRequiredKey(data, arrayOf(Pair("audioMixingMode", "String")))
1296
+ if (requiredKeys === null) {
1297
+ val mode = HMSHelper.getAudioMixingMode(data.getString("audioMixingMode"))
1298
+ audioMixingMode = mode
1299
+ hmsSDK?.setAudioMixingMode(mode)
1300
+ callback?.resolve(emitHMSSuccess())
1301
+ } else {
1302
+ val errorMessage = "setAudioMixingMode: $requiredKeys"
1303
+ self.emitRequiredKeysError(errorMessage)
1304
+ rejectCallback(callback, errorMessage)
1305
+ }
1306
+ }
1086
1307
  }
@@ -320,16 +320,18 @@ class HMSDecoder: NSObject {
320
320
 
321
321
  let endRoom = permissions.endRoom ?? false
322
322
  let removeOthers = permissions.removeOthers ?? false
323
- let stopPresentation = permissions.stopPresentation ?? false
324
- let muteAll = permissions.muteAll ?? false
323
+ let browserRecording = permissions.browserRecording ?? false
324
+ let hlsStreaming = permissions.hlsStreaming ?? false
325
+ let rtmpStreaming = permissions.rtmpStreaming ?? false
325
326
  let mute = permissions.mute ?? false
326
327
  let unmute = permissions.unmute ?? false
327
328
  let changeRole = permissions.changeRole ?? false
328
329
 
329
330
  return ["endRoom": endRoom,
330
331
  "removeOthers": removeOthers,
331
- "stopPresentation": stopPresentation,
332
- "muteAll": muteAll,
332
+ "browserRecording": browserRecording,
333
+ "hlsStreaming": hlsStreaming,
334
+ "rtmpStreaming": rtmpStreaming,
333
335
  "mute": mute,
334
336
  "unmute": unmute,
335
337
  "changeRole": changeRole]
@@ -478,16 +480,15 @@ class HMSDecoder: NSObject {
478
480
 
479
481
  static func getError(_ errorObj: HMSError?) -> [String: Any]? {
480
482
  if let error = errorObj {
481
- let code = error.code
483
+ let code = error.code.rawValue
482
484
  let description = error.description
483
- let localizedDescription = error.localizedDescription
484
- let debugDescription = error.debugDescription
485
485
  let message = error.message
486
486
  let name = error.id
487
487
  let id = error.id
488
488
  let action = error.action
489
+ let isTerminal = false
489
490
 
490
- return ["code": code, "description": description, "localizedDescription": localizedDescription, "debugDescription": debugDescription, "message": message, "name": name, "action": action, "id": id]
491
+ return ["code": code, "description": description, "message": message, "name": name, "action": action, "id": id, "isTerminal": isTerminal]
491
492
  } else {
492
493
  return nil
493
494
  }
@@ -228,18 +228,15 @@ class HMSHelper: NSObject {
228
228
  return hlsVariants
229
229
  }
230
230
 
231
- static func getHlsRecordingConfig(_ data: NSDictionary) -> HMSHLSRecordingConfig? {
232
- guard let meetingURLVariants = data.value(forKey: "hlsRecordingConfig") as? NSDictionary
233
- else {
234
- return nil
235
- }
236
- guard let singleFilePerLayer = meetingURLVariants.value(forKey: "singleFilePerLayer") as? Bool ,
237
- let videoOnDemand = meetingURLVariants.value(forKey: "videoOnDemand") as? Bool
231
+ static func getHlsRecordingConfig(_ config: NSDictionary?) -> HMSHLSRecordingConfig? {
232
+ guard let hlsRecordingConfig = config
238
233
  else {
239
234
  return nil
240
235
  }
236
+ let singleFilePerLayer = hlsRecordingConfig.value(forKey: "singleFilePerLayer") as? Bool
237
+ let videoOnDemand = hlsRecordingConfig.value(forKey: "videoOnDemand") as? Bool
241
238
 
242
- return HMSHLSRecordingConfig(singleFilePerLayer: singleFilePerLayer, enableVOD: videoOnDemand)
239
+ return HMSHLSRecordingConfig(singleFilePerLayer: singleFilePerLayer ?? false, enableVOD: videoOnDemand ?? false)
243
240
  }
244
241
 
245
242
  static func getHMSHLSMeetingURLVariant(_ variant: [String: Any]) -> HMSHLSMeetingURLVariant? {