@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.
- package/README.md +50 -43
- package/android/.gradle/6.9/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/6.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/.gradle/checksums/checksums.lock +0 -0
- package/android/.gradle/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/checksums/sha1-checksums.bin +0 -0
- 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
- package/android/.idea/libraries/Gradle__com_github_100mslive_webrtc_m97_hms_1_1_aar.xml +11 -0
- package/android/.idea/modules/android.androidTest.iml +4 -4
- package/android/.idea/modules/android.main.iml +4 -4
- package/android/.idea/modules/android.unitTest.iml +4 -4
- package/android/build.gradle +2 -2
- package/android/src/main/java/com/reactnativehmssdk/HMSAudioshareActivity.kt +84 -0
- package/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt +77 -8
- package/android/src/main/java/com/reactnativehmssdk/HMSHelper.kt +95 -22
- package/android/src/main/java/com/reactnativehmssdk/HMSManager.kt +86 -0
- package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +255 -34
- package/ios/HMSDecoder.swift +9 -8
- package/ios/HMSHelper.swift +5 -8
- package/ios/HMSManager.swift +5 -4
- package/ios/HMSRNSDK.swift +27 -32
- package/lib/commonjs/classes/HMSAudioDevice.js +17 -0
- package/lib/commonjs/classes/HMSAudioDevice.js.map +1 -0
- package/lib/commonjs/classes/HMSAudioMixingMode.js +15 -0
- package/lib/commonjs/classes/HMSAudioMixingMode.js.map +1 -0
- package/lib/commonjs/classes/HMSAudioMode.js +17 -0
- package/lib/commonjs/classes/HMSAudioMode.js.map +1 -0
- package/lib/commonjs/classes/HMSEncoder.js +15 -0
- package/lib/commonjs/classes/HMSEncoder.js.map +1 -1
- package/lib/commonjs/classes/HMSException.js +18 -13
- package/lib/commonjs/classes/HMSException.js.map +1 -1
- package/lib/commonjs/classes/HMSHLSConfig.js.map +1 -1
- package/lib/commonjs/classes/HMSPermissions.js +7 -4
- package/lib/commonjs/classes/HMSPermissions.js.map +1 -1
- package/lib/commonjs/classes/HMSSDK.js +184 -9
- package/lib/commonjs/classes/HMSSDK.js.map +1 -1
- package/lib/commonjs/classes/HMSUpdateListenerActions.js +1 -0
- package/lib/commonjs/classes/HMSUpdateListenerActions.js.map +1 -1
- package/lib/commonjs/index.js +42 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/classes/HMSAudioDevice.js +10 -0
- package/lib/module/classes/HMSAudioDevice.js.map +1 -0
- package/lib/module/classes/HMSAudioMixingMode.js +8 -0
- package/lib/module/classes/HMSAudioMixingMode.js.map +1 -0
- package/lib/module/classes/HMSAudioMode.js +10 -0
- package/lib/module/classes/HMSAudioMode.js.map +1 -0
- package/lib/module/classes/HMSEncoder.js +14 -0
- package/lib/module/classes/HMSEncoder.js.map +1 -1
- package/lib/module/classes/HMSException.js +18 -13
- package/lib/module/classes/HMSException.js.map +1 -1
- package/lib/module/classes/HMSHLSConfig.js.map +1 -1
- package/lib/module/classes/HMSPermissions.js +7 -4
- package/lib/module/classes/HMSPermissions.js.map +1 -1
- package/lib/module/classes/HMSSDK.js +184 -9
- package/lib/module/classes/HMSSDK.js.map +1 -1
- package/lib/module/classes/HMSUpdateListenerActions.js +1 -0
- package/lib/module/classes/HMSUpdateListenerActions.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/classes/HMSAudioDevice.d.ts +7 -0
- package/lib/typescript/classes/HMSAudioMixingMode.d.ts +5 -0
- package/lib/typescript/classes/HMSAudioMode.d.ts +7 -0
- package/lib/typescript/classes/HMSEncoder.d.ts +2 -0
- package/lib/typescript/classes/HMSException.d.ts +8 -14
- package/lib/typescript/classes/HMSHLSConfig.d.ts +2 -2
- package/lib/typescript/classes/HMSPermissions.d.ts +6 -4
- package/lib/typescript/classes/HMSSDK.d.ts +105 -7
- package/lib/typescript/classes/HMSUpdateListenerActions.d.ts +2 -1
- package/lib/typescript/index.d.ts +3 -0
- package/package.json +1 -1
- package/react-native-hms.podspec +1 -1
- package/src/classes/HMSAudioDevice.ts +7 -0
- package/src/classes/HMSAudioMixingMode.ts +5 -0
- package/src/classes/HMSAudioMode.ts +7 -0
- package/src/classes/HMSEncoder.ts +12 -0
- package/src/classes/HMSException.ts +15 -24
- package/src/classes/HMSHLSConfig.ts +2 -2
- package/src/classes/HMSPermissions.ts +9 -6
- package/src/classes/HMSSDK.tsx +250 -16
- package/src/classes/HMSUpdateListenerActions.ts +1 -0
- package/src/index.ts +3 -0
- 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
|
|
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(
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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
|
|
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(
|
|
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(
|
|
60
|
-
|
|
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("
|
|
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
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
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
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
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
|
}
|
package/ios/HMSDecoder.swift
CHANGED
|
@@ -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
|
|
324
|
-
let
|
|
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
|
-
"
|
|
332
|
-
"
|
|
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, "
|
|
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
|
}
|
package/ios/HMSHelper.swift
CHANGED
|
@@ -228,18 +228,15 @@ class HMSHelper: NSObject {
|
|
|
228
228
|
return hlsVariants
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
-
static func getHlsRecordingConfig(_
|
|
232
|
-
guard let
|
|
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? {
|