@100mslive/react-native-hms 0.9.1 → 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.
Files changed (124) hide show
  1. package/README.md +239 -26
  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/build.gradle +1 -1
  10. package/android/src/main/java/com/reactnativehmssdk/HmsDecoder.kt +22 -0
  11. package/android/src/main/java/com/reactnativehmssdk/HmsHelper.kt +197 -6
  12. package/android/src/main/java/com/reactnativehmssdk/HmsModule.kt +2 -2
  13. package/android/src/main/java/com/reactnativehmssdk/HmsSDK.kt +36 -77
  14. package/android/src/main/java/com/reactnativehmssdk/HmsScreenshareActivity.kt +16 -0
  15. package/android/src/main/java/com/reactnativehmssdk/HmsView.kt +24 -33
  16. package/android/src/main/java/com/reactnativehmssdk/HmssdkViewManager.kt +15 -2
  17. package/ios/HmsDecoder.swift +47 -4
  18. package/ios/HmsHelper.swift +14 -0
  19. package/ios/HmsSDK.swift +13 -7
  20. package/lib/commonjs/classes/HMSConfig.js +3 -0
  21. package/lib/commonjs/classes/HMSConfig.js.map +1 -1
  22. package/lib/commonjs/classes/HMSEncoder.js +33 -2
  23. package/lib/commonjs/classes/HMSEncoder.js.map +1 -1
  24. package/lib/commonjs/classes/HMSHLSConfig.js +3 -0
  25. package/lib/commonjs/classes/HMSHLSConfig.js.map +1 -1
  26. package/lib/commonjs/classes/HMSHLSRecordingConfig.js +23 -0
  27. package/lib/commonjs/classes/HMSHLSRecordingConfig.js.map +1 -0
  28. package/lib/commonjs/classes/HMSHLSRecordingState.js +29 -0
  29. package/lib/commonjs/classes/HMSHLSRecordingState.js.map +1 -0
  30. package/lib/commonjs/classes/HMSLocalPeer.js.map +1 -1
  31. package/lib/commonjs/classes/HMSLogger.js +21 -21
  32. package/lib/commonjs/classes/HMSLogger.js.map +1 -1
  33. package/lib/commonjs/classes/HMSMessage.js +4 -1
  34. package/lib/commonjs/classes/HMSMessage.js.map +1 -1
  35. package/lib/commonjs/classes/HMSMessageRecipient.js +26 -0
  36. package/lib/commonjs/classes/HMSMessageRecipient.js.map +1 -0
  37. package/lib/commonjs/classes/HMSMessageRecipientType.js +15 -0
  38. package/lib/commonjs/classes/HMSMessageRecipientType.js.map +1 -0
  39. package/lib/commonjs/classes/HMSNetworkQuality.js +20 -0
  40. package/lib/commonjs/classes/HMSNetworkQuality.js.map +1 -0
  41. package/lib/commonjs/classes/HMSPeer.js +3 -0
  42. package/lib/commonjs/classes/HMSPeer.js.map +1 -1
  43. package/lib/commonjs/classes/HMSPeerUpdate.js +1 -8
  44. package/lib/commonjs/classes/HMSPeerUpdate.js.map +1 -1
  45. package/lib/commonjs/classes/HMSRemotePeer.js.map +1 -1
  46. package/lib/commonjs/classes/HMSRoom.js +3 -0
  47. package/lib/commonjs/classes/HMSRoom.js.map +1 -1
  48. package/lib/commonjs/classes/HMSSDK.js +22 -7
  49. package/lib/commonjs/classes/HMSSDK.js.map +1 -1
  50. package/lib/commonjs/classes/HmsView.js +10 -6
  51. package/lib/commonjs/classes/HmsView.js.map +1 -1
  52. package/lib/commonjs/index.js +70 -0
  53. package/lib/commonjs/index.js.map +1 -1
  54. package/lib/module/classes/HMSConfig.js +3 -0
  55. package/lib/module/classes/HMSConfig.js.map +1 -1
  56. package/lib/module/classes/HMSEncoder.js +31 -2
  57. package/lib/module/classes/HMSEncoder.js.map +1 -1
  58. package/lib/module/classes/HMSHLSConfig.js +3 -0
  59. package/lib/module/classes/HMSHLSConfig.js.map +1 -1
  60. package/lib/module/classes/HMSHLSRecordingConfig.js +14 -0
  61. package/lib/module/classes/HMSHLSRecordingConfig.js.map +1 -0
  62. package/lib/module/classes/HMSHLSRecordingState.js +20 -0
  63. package/lib/module/classes/HMSHLSRecordingState.js.map +1 -0
  64. package/lib/module/classes/HMSLocalPeer.js.map +1 -1
  65. package/lib/module/classes/HMSLogger.js +21 -21
  66. package/lib/module/classes/HMSLogger.js.map +1 -1
  67. package/lib/module/classes/HMSMessage.js +4 -1
  68. package/lib/module/classes/HMSMessage.js.map +1 -1
  69. package/lib/module/classes/HMSMessageRecipient.js +17 -0
  70. package/lib/module/classes/HMSMessageRecipient.js.map +1 -0
  71. package/lib/module/classes/HMSMessageRecipientType.js +8 -0
  72. package/lib/module/classes/HMSMessageRecipientType.js.map +1 -0
  73. package/lib/module/classes/HMSNetworkQuality.js +11 -0
  74. package/lib/module/classes/HMSNetworkQuality.js.map +1 -0
  75. package/lib/module/classes/HMSPeer.js +3 -0
  76. package/lib/module/classes/HMSPeer.js.map +1 -1
  77. package/lib/module/classes/HMSPeerUpdate.js +1 -8
  78. package/lib/module/classes/HMSPeerUpdate.js.map +1 -1
  79. package/lib/module/classes/HMSRemotePeer.js.map +1 -1
  80. package/lib/module/classes/HMSRoom.js +3 -0
  81. package/lib/module/classes/HMSRoom.js.map +1 -1
  82. package/lib/module/classes/HMSSDK.js +22 -6
  83. package/lib/module/classes/HMSSDK.js.map +1 -1
  84. package/lib/module/classes/HmsView.js +10 -6
  85. package/lib/module/classes/HmsView.js.map +1 -1
  86. package/lib/module/index.js +5 -0
  87. package/lib/module/index.js.map +1 -1
  88. package/lib/typescript/classes/HMSConfig.d.ts +2 -0
  89. package/lib/typescript/classes/HMSEncoder.d.ts +4 -0
  90. package/lib/typescript/classes/HMSHLSConfig.d.ts +5 -2
  91. package/lib/typescript/classes/HMSHLSRecordingConfig.d.ts +8 -0
  92. package/lib/typescript/classes/HMSHLSRecordingState.d.ts +12 -0
  93. package/lib/typescript/classes/HMSLocalPeer.d.ts +2 -0
  94. package/lib/typescript/classes/HMSMessage.d.ts +8 -4
  95. package/lib/typescript/classes/HMSMessageRecipient.d.ts +13 -0
  96. package/lib/typescript/classes/HMSMessageRecipientType.d.ts +5 -0
  97. package/lib/typescript/classes/HMSNetworkQuality.d.ts +6 -0
  98. package/lib/typescript/classes/HMSPeer.d.ts +3 -0
  99. package/lib/typescript/classes/HMSPeerUpdate.d.ts +1 -8
  100. package/lib/typescript/classes/HMSRemotePeer.d.ts +2 -0
  101. package/lib/typescript/classes/HMSRoom.d.ts +3 -0
  102. package/lib/typescript/classes/HMSSDK.d.ts +299 -10
  103. package/lib/typescript/classes/HmsView.d.ts +4 -2
  104. package/lib/typescript/index.d.ts +5 -0
  105. package/package.json +1 -1
  106. package/react-native-hms.podspec +1 -1
  107. package/src/classes/HMSConfig.ts +3 -0
  108. package/src/classes/HMSEncoder.ts +62 -17
  109. package/src/classes/HMSHLSConfig.ts +8 -2
  110. package/src/classes/HMSHLSRecordingConfig.ts +9 -0
  111. package/src/classes/HMSHLSRecordingState.ts +18 -0
  112. package/src/classes/HMSLocalPeer.ts +2 -0
  113. package/src/classes/HMSLogger.ts +3 -3
  114. package/src/classes/HMSMessage.ts +11 -5
  115. package/src/classes/HMSMessageRecipient.ts +19 -0
  116. package/src/classes/HMSMessageRecipientType.ts +5 -0
  117. package/src/classes/HMSNetworkQuality.ts +7 -0
  118. package/src/classes/HMSPeer.ts +4 -2
  119. package/src/classes/HMSPeerUpdate.ts +1 -8
  120. package/src/classes/HMSRemotePeer.ts +2 -0
  121. package/src/classes/HMSRoom.ts +4 -0
  122. package/src/classes/HMSSDK.tsx +306 -11
  123. package/src/classes/HmsView.tsx +14 -6
  124. package/src/index.ts +5 -0
package/README.md CHANGED
@@ -19,6 +19,16 @@
19
19
 
20
20
  React native wrapper for 100ms SDK
21
21
 
22
+ ## Run Example App
23
+
24
+ To run the example app on your system, follow these steps -
25
+
26
+ 1. In the project root, run `npm install`
27
+ 2. Go to the example folder, `cd example`
28
+ 3. In the example folder, run `npm install`
29
+ 4. To run on Android, run `npx react-native run-android`
30
+ 5. To run on iOS, first install the pods in iOS folder, `cd ios; pod install`. Then, in example folder, run `npx react-native run-ios`
31
+
22
32
  ## Installation
23
33
 
24
34
  ```bash
@@ -62,7 +72,7 @@ We suggest using [react-native-permission](https://www.npmjs.com/package/react-n
62
72
 
63
73
  The package exports all the classes and a HMSSDK class that manages everything.
64
74
 
65
- # Setting up the HMS Instance:
75
+ ## Setting up the HMS Instance
66
76
 
67
77
  first we'll have to call build method, that method returns an instance of HMSSDK class and the same is used to perform all the operations
68
78
 
@@ -76,7 +86,7 @@ const hmsInstance = await HMSSDK.build();
76
86
  ...
77
87
  ```
78
88
 
79
- # Add event listeners
89
+ ## Add event listeners
80
90
 
81
91
  add event listeners for all the events such as onPreview, onJoin, onPeerUpdate etc. the actions can be found in HMSUpdateListenerActions class
82
92
 
@@ -95,7 +105,16 @@ hmsInstance.addEventListener(
95
105
 
96
106
  The event handlers are the way of handling any update happening in hms all events can be found in HMSUpdateListenerActions class
97
107
 
98
- # Join the room
108
+ ## Error handling
109
+
110
+ ```js
111
+ import { HMSUpdateListenerActions } from '@100mslive/react-native-hms';
112
+
113
+ // add an error event listener
114
+ hmsInstance.addEventListener(HMSUpdateListenerActions.ON_ERROR, onError);
115
+ ```
116
+
117
+ ## Join the room
99
118
 
100
119
  Joining the room connects you to the remote peer and broadcasts your stream to other peers, we need instance of HMSConfig in order to pass the details of room and user to join function
101
120
 
@@ -115,7 +134,23 @@ hmsInstance.join(HmsConfig); // to join a room
115
134
 
116
135
  don't forget to add ON_JOIN listener before calling join to receive an event callback
117
136
 
118
- # Viewing the video of a peer
137
+ ## Calling various functions of HMS
138
+
139
+ ```js
140
+ // Mute Audio
141
+ hmsInstance?.localPeer?.localAudioTrack()?.setMute(true);
142
+
143
+ // Stop Video
144
+ hmsInstance?.localPeer?.localVideoTrack()?.setMute(true);
145
+
146
+ // Switch Camera
147
+ hmsInstance?.localPeer?.localVideoTrack()?.switchCamera();
148
+
149
+ // Leave the call (async function)
150
+ await hmsInstance?.leave();
151
+ ```
152
+
153
+ ## Viewing the video of a peer
119
154
 
120
155
  To display a video on screen the package provide a UI component named HmsView that takes the video track ID and displays the video in that component, this component requires on _width_ and _height_ in _style_ prop to set bounds of the tile that will show the video stream
121
156
 
@@ -141,7 +176,7 @@ remotePeers.map((remotePeer: HMSRemotePeer) => {
141
176
  ...
142
177
  ```
143
178
 
144
- # Display a video in HmsView
179
+ ## Display a video in HmsView
145
180
 
146
181
  ```js
147
182
  import { HMSVideoViewMode } from '@100mslive/react-native-hms';
@@ -165,23 +200,44 @@ const styles = StyleSheet.create({
165
200
  ...
166
201
  ```
167
202
 
168
- # Calling various functions of HMS
203
+ ## Mute/Unmute others
169
204
 
170
205
  ```js
171
- // Mute Audio
172
- hmsInstance?.localPeer?.localAudioTrack()?.setMute(true);
206
+ const mute: boolean = true;
173
207
 
174
- // Stop Video
175
- hmsInstance?.localPeer?.localVideoTrack()?.setMute(true);
208
+ // hms instance acquired by build methodhmsInstance?.changeTrackState(audioTrack as HMSTrack, mute);
209
+ hmsInstance?.changeTrackState(videoTrack as HMSTrack, mute);
176
210
 
177
- // Switch Camera
178
- hmsInstance?.localPeer?.localVideoTrack()?.switchCamera();
211
+ const unmute: boolean = false;
179
212
 
180
- // Leave the call (async function)
181
- await hmsInstance?.leave();
213
+ hmsInstance?.changeTrackState(audioTrack as HMSTrack, unmute);
214
+ hmsInstance?.changeTrackState(videoTrack as HMSTrack, unmute);
182
215
  ```
183
216
 
184
- # Sending messages
217
+ ## End Room for all
218
+
219
+ ```js
220
+ const reason = 'Host ended the room';
221
+ const lock = false; // optional parameter
222
+
223
+ // hms instance acquired by build method
224
+ hmsInstance.endRoom(reason, lock);
225
+ ```
226
+
227
+ ## Remove Peer
228
+
229
+ ```js
230
+ import { HMSPeer } from '@100mslive/react-native-hms';
231
+
232
+ const reason = 'removed from room';
233
+
234
+ // hms instance acquired by build method
235
+ const peer: HMSPeer = hmsInstance?.remotePeers[0];
236
+
237
+ hmsInstance.removePeer(peer, reason);
238
+ ```
239
+
240
+ ## Sending messages
185
241
 
186
242
  ```js
187
243
  import { HMSRole, HMSPeer } from '@100mslive/react-native-hms';
@@ -197,20 +253,177 @@ hmsInstance?.sendGroupMessage(message, [role[0]);
197
253
  hmsInstance?.sendDirectMessage(message, peer);
198
254
  ```
199
255
 
200
- # Error handling
256
+ ## Role Change
201
257
 
202
258
  ```js
203
- import { HMSUpdateListenerActions } from '@100mslive/react-native-hms';
259
+ import { HMSRole, HMSRemotePeer } from '@100mslive/react-native-hms';
260
+ // hms instance acquired by build method
261
+ const roles: HMSRole[] = hmsInstance?.knownRoles;
262
+ const newRole: HMSRole = roles[0];
204
263
 
205
- // add an error event listener
206
- hmsInstance.addEventListener(HMSUpdateListenerActions.ON_ERROR, onError);
264
+ // can any remote peer
265
+ const peer: HMSRemotePeer = hmsInstance?.remotePeers[0];
266
+
267
+ const force = false;
268
+
269
+ hmsInstance.changeRole(peer, newRole, force); // request role change
270
+ hmsInstance.changeRole(peer, newRole, !force); // force role change
207
271
  ```
208
272
 
209
- # Run Example App
210
- To run the example app on your system, follow these steps -
211
- 1. In the project root, run `npm install`
212
- 2. Go to the example folder, `cd example`
213
- 3. In the example folder, run `npm install`
214
- 4. To run on Android, run `npx react-native run-android`
215
- 5. To run on iOS, first install the pods in iOS folder, `cd ios; pod install`. Then, in example folder, run `npx react-native run-ios`
273
+ ## Raise Hand & BRB
274
+
275
+ ```js
276
+ const parsedMetadata = JSON.parse(hmsInstance?.localPeer?.metadata);
277
+
278
+ // Raise Hand
279
+ // hms instance acquired by build method
280
+ hmsInstance?.changeMetadata(
281
+ JSON.stringify({
282
+ ...parsedMetadata,
283
+ isHandRaised: true,
284
+ })
285
+ );
286
+
287
+ // BRB
288
+ // hms instance acquired by build method
289
+ hmsInstance?.changeMetadata(
290
+ JSON.stringify({
291
+ ...parsedMetadata,
292
+ isBRBOn: true,
293
+ })
294
+ );
295
+ ```
296
+
297
+ ## HLS Streaming
298
+
299
+ ```js
300
+ import {
301
+ HMSHLSMeetingURLVariant,
302
+ HMSHLSConfig,
303
+ } from '@100mslive/react-native-hms';
304
+
305
+ const startHLSStreaming = () => {
306
+ const hmsHLSMeetingURLVariant = new HMSHLSMeetingURLVariant({
307
+ meetingUrl:
308
+ 'https://yogi.app.100ms.live/preview/nih-bkn-vek?token=beam_recording',
309
+ metadata: '',
310
+ });
311
+
312
+ const hmsHLSConfig = new HMSHLSConfig({
313
+ meetingURLVariants: [hlsStreamingDetails],
314
+ });
315
+
316
+ // hms instance acquired by build method
317
+ hmsInstance
318
+ .startHLSStreaming(hmsHLSConfig)
319
+ .then((r) => console.log(r))
320
+ .catch((e) => console.log(e));
321
+ };
322
+ ```
323
+
324
+ ## Start Streaming / Recording
325
+
326
+ ```js
327
+ import { HMSRTMPConfig } from '@100mslive/react-native-hms';
328
+
329
+ const recordingDetails = HMSRTMPConfig({
330
+ record: true,
331
+ meetingURL: roomID + '/viewer?token=beam_recording',
332
+ rtmpURLs: [],
333
+ });
334
+
335
+ // hms instance acquired by build method
336
+ const result = await hmsInstance?.startRTMPOrRecording(recordingDetails);
337
+ ```
338
+
339
+ ## Get RTC Stats
340
+
341
+ ```js
342
+ // hms instance acquired by build method
343
+ hmsInstance?.enableRTCStats();
344
+ ```
345
+
346
+ ## Screenshare
347
+
348
+ ```js
349
+ // hms instance acquired by build method
350
+ hmsInstance?.startScreenshare();
351
+ ```
352
+
353
+ ## Getting Audio Levels for all speaking peers
354
+
355
+ ```js
356
+ import {
357
+ HMSUpdateListenerActions,
358
+ HMSSpeakerUpdate,
359
+ HMSSpeaker,
360
+ } from '@100mslive/react-native-hms';
361
+
362
+ // hms instance acquired by build method
363
+ hmsInstance?.addEventListener(HMSUpdateListenerActions.ON_SPEAKER, onSpeaker);
364
+
365
+ const onSpeaker = (data: HMSSpeakerUpdate) => {
366
+ data?.peers?.map((speaker: HMSSpeaker) =>
367
+ console.log('speaker audio level: ', speaker?.level)
368
+ );
369
+ };
370
+ ```
371
+
372
+ ## Local mute others
373
+
374
+ ```js
375
+ const remotePeer: HMSRemotePeer;
376
+ const isAudioPlaybackAllowed = remotePeer.remoteAudioTrack().setPlaybackAllowed(false);
377
+ const isVideoPlaybackAllowed = remotePeer.remoteVideoTrack().setPlaybackAllowed(true);
378
+
379
+ // hms instance acquired by build method
380
+ hmsInstance.muteAllPeersAudio(true) // mute
381
+ hmsInstance.muteAllPeersAudio(false) // unmute
382
+ ```
216
383
 
384
+ ## Locally Set Volume
385
+
386
+ ```js
387
+ const volume: Float = 1.0;
388
+ const track: HMSTrack = remotePeer.audioTrack as HMSTrack;
389
+
390
+ // hms instance acquired by build method
391
+ hmsInstance?.setVolume(track, volume);
392
+ ```
393
+
394
+ ## Change name
395
+
396
+ ```js
397
+ const newName: string = 'new name';
398
+
399
+ // hms instance acquired by build method
400
+ hmsInstance.changeName(newName);
401
+ ```
402
+
403
+ ## Join with specific Track Settings
404
+
405
+ ```js
406
+ const getTrackSettings = () => {
407
+ let audioSettings = new HMSAudioTrackSettings({
408
+ maxBitrate: 32,
409
+ trackDescription: 'Simple Audio Track',
410
+ });
411
+ let videoSettings = new HMSVideoTrackSettings({
412
+ codec: HMSVideoCodec.vp8,
413
+ maxBitrate: 512,
414
+ maxFrameRate: 25,
415
+ cameraFacing: HMSCameraFacing.FRONT,
416
+ trackDescription: 'Simple Video Track',
417
+ resolution: new HMSVideoResolution({ height: 180, width: 320 }),
418
+ });
419
+
420
+ return new HMSTrackSettings({ video: videoSettings, audio: audioSettings });
421
+ };
422
+
423
+ const setupBuild = async () => {
424
+ const trackSettings = getTrackSettings();
425
+ const build = await HmsManager.build({ trackSettings });
426
+ setInstance(build);
427
+ updateHms({ hmsInstance: build });
428
+ };
429
+ ```
@@ -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.1'
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,6 +1,7 @@
1
1
  package com.reactnativehmssdk
2
2
 
3
3
  import com.facebook.react.bridge.*
4
+ import live.hms.video.connection.stats.quality.HMSNetworkQuality
4
5
  import live.hms.video.error.HMSException
5
6
  import live.hms.video.media.settings.HMSAudioTrackSettings
6
7
  import live.hms.video.media.settings.HMSVideoResolution
@@ -47,6 +48,7 @@ object HmsDecoder {
47
48
  peer.putBoolean("isLocal", hmsPeer.isLocal)
48
49
  peer.putString("customerUserID", hmsPeer.customerUserID)
49
50
  peer.putString("metadata", hmsPeer.metadata)
51
+ peer.putMap("networkQuality", this.getHmsNetworkQuality(hmsPeer.networkQuality))
50
52
  peer.putMap("audioTrack", this.getHmsAudioTrack(hmsPeer.audioTrack))
51
53
  peer.putMap("videoTrack", this.getHmsVideoTrack(hmsPeer.videoTrack))
52
54
  peer.putMap("role", this.getHmsRole(hmsPeer.hmsRole))
@@ -182,6 +184,7 @@ object HmsDecoder {
182
184
  peer.putBoolean("isLocal", hmsLocalPeer.isLocal)
183
185
  peer.putString("customerUserID", hmsLocalPeer.customerUserID)
184
186
  peer.putString("metadata", hmsLocalPeer.metadata)
187
+ peer.putMap("networkQuality", this.getHmsNetworkQuality(hmsLocalPeer.networkQuality))
185
188
  peer.putMap("audioTrack", this.getHmsAudioTrack(hmsLocalPeer.audioTrack))
186
189
  peer.putMap("videoTrack", this.getHmsVideoTrack(hmsLocalPeer.videoTrack))
187
190
  peer.putMap("role", this.getHmsRole(hmsLocalPeer.hmsRole))
@@ -276,6 +279,7 @@ object HmsDecoder {
276
279
  peer.putBoolean("isLocal", hmsRemotePeer.isLocal)
277
280
  peer.putString("customerUserID", hmsRemotePeer.customerUserID)
278
281
  peer.putString("metadata", hmsRemotePeer.metadata)
282
+ peer.putMap("networkQuality", this.getHmsNetworkQuality(hmsRemotePeer.networkQuality))
279
283
  peer.putMap("audioTrack", this.getHmsAudioTrack(hmsRemotePeer.audioTrack))
280
284
  peer.putMap("videoTrack", this.getHmsVideoTrack(hmsRemotePeer.videoTrack))
281
285
  peer.putMap("role", this.getHmsRole(hmsRemotePeer.hmsRole))
@@ -498,4 +502,22 @@ object HmsDecoder {
498
502
  }
499
503
  return decodedTracks
500
504
  }
505
+
506
+ fun getHmsMessageRecipient(recipient: HMSMessageRecipient?): WritableMap {
507
+ val hmsRecipient: WritableMap = Arguments.createMap()
508
+ if (recipient != null) {
509
+ hmsRecipient.putMap("recipientPeer", this.getHmsPeer(recipient.recipientPeer))
510
+ hmsRecipient.putArray("recipientRoles", this.getAllRoles(recipient.recipientRoles))
511
+ hmsRecipient.putString("recipientType", recipient.recipientType.name)
512
+ }
513
+ return hmsRecipient
514
+ }
515
+
516
+ private fun getHmsNetworkQuality(networkQuality: HMSNetworkQuality?): WritableMap {
517
+ val hmsNetworkQuality: WritableMap = Arguments.createMap()
518
+ if (networkQuality != null) {
519
+ hmsNetworkQuality.putInt("downlinkQuality", networkQuality.downlinkQuality)
520
+ }
521
+ return hmsNetworkQuality
522
+ }
501
523
  }
@@ -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
 
@@ -107,7 +123,7 @@ object HmsHelper {
107
123
 
108
124
  fun getTrackFromTrackId(trackId: String?, room: HMSRoom?): HMSTrack? {
109
125
  if (trackId != null && room != null) {
110
- HmsUtilities.getTrack(trackId, room)
126
+ return HmsUtilities.getTrack(trackId, room)
111
127
  }
112
128
  return null
113
129
  }
@@ -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
  }
@@ -270,6 +284,26 @@ object HmsHelper {
270
284
  return meetingURLVariants
271
285
  }
272
286
 
287
+ fun getHlsRecordingConfig(data: ReadableMap): HMSHlsRecordingConfig? {
288
+ if (areAllRequiredKeysAvailable(data, arrayOf(Pair("hlsRecordingConfig", "Map")))) {
289
+ val hmsHlsRecordingConfig = data.getMap("hlsRecordingConfig")
290
+ if (hmsHlsRecordingConfig != null) {
291
+ var singleFilePerLayer = false
292
+ var videoOnDemand = false
293
+ if (areAllRequiredKeysAvailable(
294
+ hmsHlsRecordingConfig, arrayOf(Pair("singleFilePerLayer", "Boolean")))) {
295
+ singleFilePerLayer = hmsHlsRecordingConfig.getBoolean("singleFilePerLayer")
296
+ }
297
+ if (areAllRequiredKeysAvailable(
298
+ hmsHlsRecordingConfig, arrayOf(Pair("videoOnDemand", "Boolean")))) {
299
+ videoOnDemand = hmsHlsRecordingConfig.getBoolean("videoOnDemand")
300
+ }
301
+ return HMSHlsRecordingConfig(singleFilePerLayer, videoOnDemand)
302
+ }
303
+ }
304
+ return null
305
+ }
306
+
273
307
  private fun getHMSHLSMeetingURLVariant(
274
308
  hmsMeetingURLVariant: HashMap<String, String>?
275
309
  ): HMSHLSMeetingURLVariant {
@@ -281,4 +315,161 @@ object HmsHelper {
281
315
  }
282
316
  return meetingURLVariant
283
317
  }
318
+
319
+ fun getHmsConfig(credentials: ReadableMap): HMSConfig {
320
+ var config =
321
+ HMSConfig(
322
+ credentials.getString("username") as String,
323
+ credentials.getString("authToken") as String,
324
+ )
325
+
326
+ when {
327
+ areAllRequiredKeysAvailable(
328
+ credentials,
329
+ arrayOf(
330
+ Pair("endpoint", "String"),
331
+ Pair("metadata", "String"),
332
+ Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
333
+ config =
334
+ HMSConfig(
335
+ credentials.getString("username") as String,
336
+ credentials.getString("authToken") as String,
337
+ initEndpoint = credentials.getString("endpoint") as String,
338
+ metadata = credentials.getString("metadata") as String,
339
+ captureNetworkQualityInPreview =
340
+ credentials.getBoolean("captureNetworkQualityInPreview"),
341
+ )
342
+ }
343
+ areAllRequiredKeysAvailable(
344
+ credentials, arrayOf(Pair("endpoint", "String"), Pair("metadata", "String"))) -> {
345
+ config =
346
+ HMSConfig(
347
+ credentials.getString("username") as String,
348
+ credentials.getString("authToken") as String,
349
+ initEndpoint = credentials.getString("endpoint") as String,
350
+ metadata = credentials.getString("metadata") as String,
351
+ )
352
+ }
353
+ areAllRequiredKeysAvailable(
354
+ credentials,
355
+ arrayOf(
356
+ Pair("endpoint", "String"), Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
357
+ config =
358
+ HMSConfig(
359
+ credentials.getString("username") as String,
360
+ credentials.getString("authToken") as String,
361
+ initEndpoint = credentials.getString("endpoint") as String,
362
+ captureNetworkQualityInPreview =
363
+ credentials.getBoolean("captureNetworkQualityInPreview"),
364
+ )
365
+ }
366
+ areAllRequiredKeysAvailable(
367
+ credentials,
368
+ arrayOf(
369
+ Pair("metadata", "String"), Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
370
+ config =
371
+ HMSConfig(
372
+ credentials.getString("username") as String,
373
+ credentials.getString("authToken") as String,
374
+ metadata = credentials.getString("metadata") as String,
375
+ captureNetworkQualityInPreview =
376
+ credentials.getBoolean("captureNetworkQualityInPreview"),
377
+ )
378
+ }
379
+ areAllRequiredKeysAvailable(credentials, arrayOf(Pair("endpoint", "String"))) -> {
380
+ config =
381
+ HMSConfig(
382
+ credentials.getString("username") as String,
383
+ credentials.getString("authToken") as String,
384
+ initEndpoint = credentials.getString("endpoint") as String,
385
+ )
386
+ }
387
+ areAllRequiredKeysAvailable(credentials, arrayOf(Pair("metadata", "String"))) -> {
388
+ config =
389
+ HMSConfig(
390
+ credentials.getString("username") as String,
391
+ credentials.getString("authToken") as String,
392
+ metadata = credentials.getString("metadata") as String,
393
+ )
394
+ }
395
+ areAllRequiredKeysAvailable(
396
+ credentials, arrayOf(Pair("captureNetworkQualityInPreview", "Boolean"))) -> {
397
+ config =
398
+ HMSConfig(
399
+ credentials.getString("username") as String,
400
+ credentials.getString("authToken") as String,
401
+ captureNetworkQualityInPreview =
402
+ credentials.getBoolean("captureNetworkQualityInPreview"))
403
+ }
404
+ }
405
+ return config
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
+ }
284
475
  }
@@ -216,11 +216,11 @@ class HmsModule(reactContext: ReactApplicationContext) :
216
216
  }
217
217
 
218
218
  @ReactMethod
219
- fun startScreenshare(data: ReadableMap) {
219
+ fun startScreenshare(data: ReadableMap, callback: Promise?) {
220
220
  currentActivity?.application?.registerActivityLifecycleCallbacks(this)
221
221
  val hms = HmsHelper.getHms(data, hmsCollection)
222
222
 
223
- hms?.startScreenshare()
223
+ hms?.startScreenshare(callback)
224
224
  }
225
225
 
226
226
  @ReactMethod