@fishjam-cloud/react-native-client 0.2.3 → 0.3.0
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/LICENSE +201 -0
- package/README.md +14 -401
- package/android/build.gradle +3 -3
- package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +25 -12
- package/android/src/main/java/io/fishjam/reactnative/Errors.kt +3 -2
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +122 -105
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +24 -33
- package/android/src/main/java/io/fishjam/reactnative/VideoPreviewView.kt +13 -3
- package/build/RNFishjamClientModule.d.ts +17 -15
- package/build/RNFishjamClientModule.d.ts.map +1 -1
- package/build/RNFishjamClientModule.js.map +1 -1
- package/build/common/client.d.ts +4 -4
- package/build/common/client.d.ts.map +1 -1
- package/build/common/client.js +5 -5
- package/build/common/client.js.map +1 -1
- package/build/common/metadata.d.ts +3 -3
- package/build/common/metadata.d.ts.map +1 -1
- package/build/common/metadata.js +4 -4
- package/build/common/metadata.js.map +1 -1
- package/build/common/webRTC.d.ts +0 -8
- package/build/common/webRTC.d.ts.map +1 -1
- package/build/common/webRTC.js +0 -9
- package/build/common/webRTC.js.map +1 -1
- package/build/components/VideoRendererView.d.ts +1 -1
- package/build/components/VideoRendererView.js +1 -1
- package/build/components/VideoRendererView.js.map +1 -1
- package/build/debug/common/webRTC.d.ts +9 -0
- package/build/debug/common/webRTC.d.ts.map +1 -0
- package/build/debug/common/webRTC.js +11 -0
- package/build/debug/common/webRTC.js.map +1 -0
- package/build/debug/index.d.ts +4 -0
- package/build/debug/index.d.ts.map +1 -0
- package/build/debug/index.js +3 -0
- package/build/debug/index.js.map +1 -0
- package/build/debug/stats/types.d.ts.map +1 -0
- package/build/debug/stats/types.js.map +1 -0
- package/build/debug/stats/useRTCStatistics.d.ts.map +1 -0
- package/build/{stats → debug/stats}/useRTCStatistics.js +1 -1
- package/build/debug/stats/useRTCStatistics.js.map +1 -0
- package/build/hooks/useCamera.d.ts +17 -0
- package/build/hooks/useCamera.d.ts.map +1 -1
- package/build/hooks/useCamera.js +1 -1
- package/build/hooks/useCamera.js.map +1 -1
- package/build/hooks/useFishjamEvent.d.ts +2 -1
- package/build/hooks/useFishjamEvent.d.ts.map +1 -1
- package/build/hooks/useFishjamEvent.js +2 -1
- package/build/hooks/useFishjamEvent.js.map +1 -1
- package/build/hooks/usePeerStatus.d.ts +19 -0
- package/build/hooks/usePeerStatus.d.ts.map +1 -0
- package/build/hooks/usePeerStatus.js +18 -0
- package/build/hooks/usePeerStatus.js.map +1 -0
- package/build/hooks/{useParticipants.d.ts → usePeers.d.ts} +11 -11
- package/build/hooks/usePeers.d.ts.map +1 -0
- package/build/hooks/usePeers.js +34 -0
- package/build/hooks/usePeers.js.map +1 -0
- package/build/hooks/useScreenShare.d.ts +57 -0
- package/build/hooks/useScreenShare.d.ts.map +1 -0
- package/build/hooks/useScreenShare.js +85 -0
- package/build/hooks/useScreenShare.js.map +1 -0
- package/build/index.d.ts +8 -7
- package/build/index.d.ts.map +1 -1
- package/build/index.js +4 -4
- package/build/index.js.map +1 -1
- package/debug/package.json +4 -0
- package/ios/Events.swift +29 -13
- package/ios/RNFishjamClient.podspec +1 -1
- package/ios/RNFishjamClient.swift +110 -107
- package/ios/RNFishjamClientModule.swift +22 -29
- package/ios/VideoPreviewView.swift +27 -9
- package/package.json +14 -11
- package/plugin/broadcastExtensionFiles/FishjamBroadcastSampleHandler.swift +1 -1
- package/plugin/build/withFishjamIos.js +3 -3
- package/build/hooks/useParticipants.d.ts.map +0 -1
- package/build/hooks/useParticipants.js +0 -34
- package/build/hooks/useParticipants.js.map +0 -1
- package/build/hooks/useScreencast.d.ts +0 -57
- package/build/hooks/useScreencast.d.ts.map +0 -1
- package/build/hooks/useScreencast.js +0 -85
- package/build/hooks/useScreencast.js.map +0 -1
- package/build/stats/types.d.ts.map +0 -1
- package/build/stats/types.js.map +0 -1
- package/build/stats/useRTCStatistics.d.ts.map +0 -1
- package/build/stats/useRTCStatistics.js.map +0 -1
- /package/build/{stats → debug/stats}/types.d.ts +0 -0
- /package/build/{stats → debug/stats}/types.js +0 -0
- /package/build/{stats → debug/stats}/useRTCStatistics.d.ts +0 -0
|
@@ -10,7 +10,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
10
10
|
|
|
11
11
|
var isMicrophoneOn = false
|
|
12
12
|
var isCameraOn = false
|
|
13
|
-
var
|
|
13
|
+
var isScreenShareOn = false
|
|
14
14
|
var isConnected = false
|
|
15
15
|
|
|
16
16
|
private var isCameraInitialized = false
|
|
@@ -20,17 +20,25 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
20
20
|
var videoSimulcastConfig: SimulcastConfig = SimulcastConfig()
|
|
21
21
|
var localUserMetadata: Metadata = .init()
|
|
22
22
|
|
|
23
|
-
var
|
|
24
|
-
var
|
|
23
|
+
var screenShareSimulcastConfig: SimulcastConfig = SimulcastConfig()
|
|
24
|
+
var screenShareMaxBandwidth: TrackBandwidthLimit = .BandwidthLimit(0)
|
|
25
25
|
|
|
26
26
|
var cameraId: String? = nil
|
|
27
27
|
|
|
28
28
|
var audioSessionMode: AVAudioSession.Mode = AVAudioSession.Mode.videoChat
|
|
29
29
|
var errorMessage: String?
|
|
30
30
|
|
|
31
|
+
private(set) var peerStatus: PeerStatus = .idle {
|
|
32
|
+
didSet {
|
|
33
|
+
let event = EmitableEvents.PeerStatusChanged
|
|
34
|
+
emit(event: event, data: [event.name: peerStatus.rawValue])
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
let sendEvent: (_ eventName: String, _ data: [String: Any]) -> Void
|
|
32
39
|
|
|
33
40
|
static var onTracksUpdateListeners: [OnTrackUpdateListener] = []
|
|
41
|
+
static var localCameraTrackListeners: [OnLocalCameraTrackChangedListener] = []
|
|
34
42
|
|
|
35
43
|
init(sendEvent: @escaping (_ eventName: String, _ data: [String: Any]) -> Void) {
|
|
36
44
|
self.sendEvent = sendEvent
|
|
@@ -72,7 +80,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
72
80
|
|
|
73
81
|
func getVideoParametersFromOptions(connectionOptions: CameraConfig) throws -> VideoParameters {
|
|
74
82
|
let videoQuality = connectionOptions.quality
|
|
75
|
-
let
|
|
83
|
+
let flipDimensions = connectionOptions.flipDimensions
|
|
76
84
|
let videoBandwidthLimit = getMaxBandwidthFromOptions(maxBandwidth: connectionOptions.maxBandwidth)
|
|
77
85
|
let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig: connectionOptions.simulcastConfig)
|
|
78
86
|
|
|
@@ -103,7 +111,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
103
111
|
}
|
|
104
112
|
}()
|
|
105
113
|
let videoParameters = VideoParameters(
|
|
106
|
-
dimensions:
|
|
114
|
+
dimensions: flipDimensions ? preset.dimensions.flip() : preset.dimensions,
|
|
107
115
|
maxBandwidth: videoBandwidthLimit,
|
|
108
116
|
simulcastConfig: simulcastConfig
|
|
109
117
|
)
|
|
@@ -120,9 +128,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
120
128
|
as? LocalAudioTrack
|
|
121
129
|
}
|
|
122
130
|
|
|
123
|
-
private func
|
|
124
|
-
return RNFishjamClient.fishjamClient?.getLocalEndpoint().tracks.first { $0.value is
|
|
125
|
-
.value as?
|
|
131
|
+
private func getLocalScreenShareTrack() -> LocalScreenShareTrack? {
|
|
132
|
+
return RNFishjamClient.fishjamClient?.getLocalEndpoint().tracks.first { $0.value is LocalScreenShareTrack }?
|
|
133
|
+
.value as? LocalScreenShareTrack
|
|
126
134
|
}
|
|
127
135
|
|
|
128
136
|
private func ensureCreated() throws {
|
|
@@ -159,11 +167,11 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
159
167
|
}
|
|
160
168
|
}
|
|
161
169
|
|
|
162
|
-
private func
|
|
163
|
-
if
|
|
170
|
+
private func ensureScreenShareTrack() throws {
|
|
171
|
+
if getLocalScreenShareTrack() == nil {
|
|
164
172
|
throw Exception(
|
|
165
|
-
name: "
|
|
166
|
-
description: "No local
|
|
173
|
+
name: "E_NO_LOCAL_SCREENSHARE_TRACK",
|
|
174
|
+
description: "No local screen share track. Make sure to toggle screen share on first!")
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
177
|
|
|
@@ -172,18 +180,16 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
172
180
|
connectPromise.reject("E_MEMBRANE_CONNECT", "Failed to connect: socket error")
|
|
173
181
|
}
|
|
174
182
|
connectPromise = nil
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
func onAuthSuccess() {
|
|
178
|
-
join()
|
|
183
|
+
peerStatus = .error
|
|
179
184
|
}
|
|
180
185
|
|
|
181
186
|
func joinRoom(
|
|
182
|
-
url: String,
|
|
187
|
+
url: String, peerToken: String, peerMetadata: [String: Any], config: ConnectConfig,
|
|
183
188
|
promise: Promise
|
|
184
189
|
) {
|
|
190
|
+
peerStatus = .connecting
|
|
185
191
|
connectPromise = promise
|
|
186
|
-
localUserMetadata =
|
|
192
|
+
localUserMetadata = peerMetadata.toMetadata()
|
|
187
193
|
|
|
188
194
|
let reconnectConfig = FishjamCloudClient.ReconnectConfig(
|
|
189
195
|
maxAttempts: config.reconnectConfig.maxAttempts, initialDelayMs: config.reconnectConfig.initialDelayMs,
|
|
@@ -191,30 +197,28 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
191
197
|
|
|
192
198
|
RNFishjamClient.fishjamClient?.connect(
|
|
193
199
|
config: FishjamCloudClient.ConnectConfig(
|
|
194
|
-
websocketUrl: url, token:
|
|
200
|
+
websocketUrl: url, token: peerToken, peerMetadata: .init(peerMetadata),
|
|
195
201
|
reconnectConfig: reconnectConfig
|
|
196
202
|
))
|
|
197
203
|
|
|
198
204
|
}
|
|
199
205
|
|
|
200
|
-
func join() {
|
|
201
|
-
RNFishjamClient.fishjamClient?.join(peerMetadata: localUserMetadata)
|
|
202
|
-
}
|
|
203
|
-
|
|
204
206
|
func leaveRoom() {
|
|
205
|
-
if
|
|
206
|
-
let
|
|
207
|
-
Bundle.main.infoDictionary?["
|
|
207
|
+
if isScreenShareOn {
|
|
208
|
+
let screenShareExtensionBundleId =
|
|
209
|
+
Bundle.main.infoDictionary?["ScreenShareExtensionBundleId"] as? String
|
|
208
210
|
DispatchQueue.main.async {
|
|
209
|
-
RPSystemBroadcastPickerView.show(for:
|
|
211
|
+
RPSystemBroadcastPickerView.show(for: screenShareExtensionBundleId)
|
|
210
212
|
}
|
|
211
213
|
}
|
|
212
214
|
isMicrophoneOn = false
|
|
213
215
|
isCameraOn = false
|
|
214
|
-
|
|
216
|
+
isScreenShareOn = false
|
|
215
217
|
isConnected = false
|
|
216
218
|
isCameraInitialized = false
|
|
217
|
-
RNFishjamClient.fishjamClient?.leave
|
|
219
|
+
RNFishjamClient.fishjamClient?.leave { [weak self] in
|
|
220
|
+
self?.emitEndpoints()
|
|
221
|
+
}
|
|
218
222
|
}
|
|
219
223
|
|
|
220
224
|
func startCamera(config: CameraConfig) throws {
|
|
@@ -245,9 +249,10 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
245
249
|
private func setCameraTrackState(_ cameraTrack: LocalVideoTrack, enabled: Bool) {
|
|
246
250
|
cameraTrack.enabled = enabled
|
|
247
251
|
isCameraOn = enabled
|
|
248
|
-
let
|
|
249
|
-
let isCameraEnabledMap = [
|
|
250
|
-
|
|
252
|
+
let event = EmitableEvents.IsCameraOn
|
|
253
|
+
let isCameraEnabledMap = [event.name: enabled]
|
|
254
|
+
emit(event: event, data: isCameraEnabledMap)
|
|
255
|
+
RNFishjamClient.localCameraTrackListeners.forEach { $0.onLocalCameraTrackChanged() }
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
func toggleCamera() throws -> Bool {
|
|
@@ -277,8 +282,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
277
282
|
}
|
|
278
283
|
|
|
279
284
|
func startMicrophone() throws {
|
|
280
|
-
let microphoneTrack = RNFishjamClient.fishjamClient!.createAudioTrack(
|
|
281
|
-
metadata: Metadata())
|
|
285
|
+
let microphoneTrack = RNFishjamClient.fishjamClient!.createAudioTrack(metadata: Metadata())
|
|
282
286
|
setAudioSessionMode()
|
|
283
287
|
setMicrophoneTrackState(microphoneTrack, enabled: true)
|
|
284
288
|
emitEndpoints()
|
|
@@ -287,10 +291,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
287
291
|
private func setMicrophoneTrackState(_ microphoneTrack: LocalAudioTrack, enabled: Bool) {
|
|
288
292
|
microphoneTrack.enabled = enabled
|
|
289
293
|
isMicrophoneOn = enabled
|
|
290
|
-
let
|
|
291
|
-
let isMicrophoneOnMap = [
|
|
292
|
-
|
|
293
|
-
emitEvent(name: eventName, data: isMicrophoneOnMap)
|
|
294
|
+
let event = EmitableEvents.IsMicrophoneOn
|
|
295
|
+
let isMicrophoneOnMap = [event.name: enabled]
|
|
296
|
+
emit(event: event, data: isMicrophoneOnMap)
|
|
294
297
|
}
|
|
295
298
|
|
|
296
299
|
func setAudioSessionMode() {
|
|
@@ -311,15 +314,15 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
311
314
|
}
|
|
312
315
|
}
|
|
313
316
|
|
|
314
|
-
func
|
|
317
|
+
func toggleScreenShare(screenShareOptions: ScreenShareOptions) throws {
|
|
315
318
|
try ensureCreated()
|
|
316
319
|
try ensureConnected()
|
|
317
|
-
guard let
|
|
320
|
+
guard let screenShareExtensionBundleId = Bundle.main.infoDictionary?["ScreenShareExtensionBundleId"] as? String
|
|
318
321
|
else {
|
|
319
322
|
throw Exception(
|
|
320
323
|
name: "E_NO_BUNDLE_ID_SET",
|
|
321
324
|
description:
|
|
322
|
-
"No
|
|
325
|
+
"No screen share extension bundle id set. Please set ScreenShareExtensionBundleId in Info.plist"
|
|
323
326
|
)
|
|
324
327
|
}
|
|
325
328
|
guard let appGroupName = Bundle.main.infoDictionary?["AppGroupName"] as? String
|
|
@@ -329,63 +332,59 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
329
332
|
description: "No app group name set. Please set AppGroupName in Info.plist")
|
|
330
333
|
}
|
|
331
334
|
|
|
332
|
-
guard !
|
|
335
|
+
guard !isScreenShareOn else {
|
|
333
336
|
DispatchQueue.main.async {
|
|
334
|
-
RPSystemBroadcastPickerView.show(for:
|
|
337
|
+
RPSystemBroadcastPickerView.show(for: screenShareExtensionBundleId)
|
|
335
338
|
}
|
|
336
339
|
return
|
|
337
340
|
}
|
|
338
341
|
|
|
339
|
-
let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig:
|
|
342
|
+
let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig: screenShareOptions.simulcastConfig)
|
|
340
343
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
maxBandwidth:
|
|
344
|
-
let
|
|
345
|
-
let videoParameters =
|
|
346
|
-
RNFishjamClient.fishjamClient!.
|
|
344
|
+
screenShareSimulcastConfig = simulcastConfig
|
|
345
|
+
screenShareMaxBandwidth = getMaxBandwidthFromOptions(
|
|
346
|
+
maxBandwidth: screenShareOptions.maxBandwidth)
|
|
347
|
+
let screenShareMetadata = screenShareOptions.screenShareMetadata.toMetadata()
|
|
348
|
+
let videoParameters = getScreenShareVideoParameters(options: screenShareOptions)
|
|
349
|
+
RNFishjamClient.fishjamClient!.prepareForScreenSharing(
|
|
347
350
|
appGroup: appGroupName,
|
|
348
351
|
videoParameters: videoParameters,
|
|
349
|
-
metadata:
|
|
350
|
-
onStart: { [weak self]
|
|
351
|
-
guard let self
|
|
352
|
+
metadata: screenShareMetadata,
|
|
353
|
+
onStart: { [weak self] in
|
|
354
|
+
guard let self else { return }
|
|
352
355
|
|
|
353
356
|
do {
|
|
354
|
-
|
|
355
|
-
try setScreencastTrackState(screencastTrack, enabled: true)
|
|
357
|
+
try setScreenShareTrackState(enabled: true)
|
|
356
358
|
} catch {
|
|
357
359
|
os_log(
|
|
358
|
-
"Error starting
|
|
360
|
+
"Error starting screen share: %{public}s", log: log, type: .error,
|
|
359
361
|
String(describing: error)
|
|
360
362
|
)
|
|
361
363
|
}
|
|
362
364
|
|
|
363
365
|
},
|
|
364
|
-
onStop: { [weak self]
|
|
365
|
-
guard let self
|
|
366
|
+
onStop: { [weak self] in
|
|
367
|
+
guard let self else { return }
|
|
366
368
|
do {
|
|
367
|
-
|
|
368
|
-
try setScreencastTrackState(screencastTrack, enabled: false)
|
|
369
|
+
try setScreenShareTrackState(enabled: false)
|
|
369
370
|
} catch {
|
|
370
371
|
os_log(
|
|
371
|
-
"Error stopping
|
|
372
|
+
"Error stopping screen share: %{public}s", log: log, type: .error,
|
|
372
373
|
String(describing: error)
|
|
373
374
|
)
|
|
374
375
|
}
|
|
375
376
|
}
|
|
376
377
|
)
|
|
377
378
|
DispatchQueue.main.async {
|
|
378
|
-
RPSystemBroadcastPickerView.show(for:
|
|
379
|
+
RPSystemBroadcastPickerView.show(for: screenShareExtensionBundleId)
|
|
379
380
|
}
|
|
380
381
|
}
|
|
381
382
|
|
|
382
|
-
private func
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
let isScreencastEnabled = [eventName: enabled]
|
|
388
|
-
emitEvent(name: eventName, data: isScreencastEnabled)
|
|
383
|
+
private func setScreenShareTrackState(enabled: Bool) throws {
|
|
384
|
+
isScreenShareOn = enabled
|
|
385
|
+
let event = EmitableEvents.IsScreenShareOn
|
|
386
|
+
let isScreenShareEnabled = [event.name: enabled]
|
|
387
|
+
emit(event: event, data: isScreenShareEnabled)
|
|
389
388
|
}
|
|
390
389
|
|
|
391
390
|
//returns local endpoint and remote endpoints
|
|
@@ -402,7 +401,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
402
401
|
"id": endpoint.id,
|
|
403
402
|
"isLocal": endpoint.id == RNFishjamClient.fishjamClient!.getLocalEndpoint().id,
|
|
404
403
|
"type": endpoint.type,
|
|
405
|
-
"metadata": endpoint.metadata,
|
|
404
|
+
"metadata": endpoint.metadata.toDict(),
|
|
406
405
|
"tracks": endpoint.tracks.values.compactMap { track -> [String: Any?]? in
|
|
407
406
|
switch track {
|
|
408
407
|
case let track as RemoteVideoTrack:
|
|
@@ -429,7 +428,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
429
428
|
"metadata": track.metadata.toDict(),
|
|
430
429
|
]
|
|
431
430
|
|
|
432
|
-
case let track as
|
|
431
|
+
case let track as LocalScreenShareTrack:
|
|
433
432
|
return [
|
|
434
433
|
"id": track.id,
|
|
435
434
|
"type": "Video",
|
|
@@ -492,9 +491,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
492
491
|
}
|
|
493
492
|
}
|
|
494
493
|
|
|
495
|
-
func
|
|
496
|
-
try
|
|
497
|
-
if let track =
|
|
494
|
+
func updateLocalScreenShareTrackMetadata(metadata: [String: Any]) throws {
|
|
495
|
+
try ensureScreenShareTrack()
|
|
496
|
+
if let track = getLocalScreenShareTrack() {
|
|
498
497
|
updateTrackMetadata(trackId: track.id, metadata: metadata)
|
|
499
498
|
}
|
|
500
499
|
}
|
|
@@ -518,25 +517,25 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
518
517
|
return SimulcastConfig(enabled: true, activeEncodings: updatedEncodings)
|
|
519
518
|
}
|
|
520
519
|
|
|
521
|
-
func
|
|
522
|
-
try
|
|
523
|
-
if let track =
|
|
524
|
-
|
|
525
|
-
encoding: encoding, trackId: track.id, simulcastConfig:
|
|
520
|
+
func toggleScreenShareTrackEncoding(encoding: String) throws -> [String: Any] {
|
|
521
|
+
try ensureScreenShareTrack()
|
|
522
|
+
if let track = getLocalScreenShareTrack() {
|
|
523
|
+
screenShareSimulcastConfig = try toggleTrackEncoding(
|
|
524
|
+
encoding: encoding, trackId: track.id, simulcastConfig: screenShareSimulcastConfig)
|
|
526
525
|
}
|
|
527
|
-
return getSimulcastConfigAsRNMap(
|
|
526
|
+
return getSimulcastConfigAsRNMap(screenShareSimulcastConfig)
|
|
528
527
|
}
|
|
529
528
|
|
|
530
|
-
func
|
|
531
|
-
try
|
|
532
|
-
if let track =
|
|
529
|
+
func setScreenShareTrackBandwidth(bandwidth: Int) throws {
|
|
530
|
+
try ensureScreenShareTrack()
|
|
531
|
+
if let track = getLocalScreenShareTrack() {
|
|
533
532
|
RNFishjamClient.fishjamClient?.setTrackBandwidth(trackId: track.id, bandwidthLimit: bandwidth)
|
|
534
533
|
}
|
|
535
534
|
}
|
|
536
535
|
|
|
537
|
-
func
|
|
538
|
-
try
|
|
539
|
-
if let track =
|
|
536
|
+
func setScreenShareTrackEncodingBandwidth(encoding: String, bandwidth: Int) throws {
|
|
537
|
+
try ensureScreenShareTrack()
|
|
538
|
+
if let track = getLocalScreenShareTrack() {
|
|
540
539
|
RNFishjamClient.fishjamClient?.setEncodingBandwidth(
|
|
541
540
|
trackId: track.id, encoding: encoding, bandwidthLimit: bandwidth)
|
|
542
541
|
}
|
|
@@ -556,9 +555,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
556
555
|
videoSimulcastConfig = try toggleTrackEncoding(
|
|
557
556
|
encoding: encoding, trackId: track.id, simulcastConfig: videoSimulcastConfig)
|
|
558
557
|
|
|
559
|
-
let
|
|
558
|
+
let event = EmitableEvents.SimulcastConfigUpdate
|
|
560
559
|
let simulcastConfigAsRNMap = getSimulcastConfigAsRNMap(videoSimulcastConfig)
|
|
561
|
-
|
|
560
|
+
emit(event: event, data: simulcastConfigAsRNMap)
|
|
562
561
|
|
|
563
562
|
return simulcastConfigAsRNMap
|
|
564
563
|
}
|
|
@@ -649,7 +648,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
649
648
|
return Dictionary(uniqueKeysWithValues: pairs)
|
|
650
649
|
}
|
|
651
650
|
|
|
652
|
-
private func
|
|
651
|
+
private func getScreenShareVideoParameters(options: ScreenShareOptions) -> VideoParameters {
|
|
653
652
|
let preset: VideoParameters
|
|
654
653
|
switch options.quality {
|
|
655
654
|
case "VGA":
|
|
@@ -667,24 +666,24 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
667
666
|
}
|
|
668
667
|
return VideoParameters(
|
|
669
668
|
dimensions: preset.dimensions.flip(),
|
|
670
|
-
maxBandwidth:
|
|
669
|
+
maxBandwidth: screenShareMaxBandwidth,
|
|
671
670
|
maxFps: preset.maxFps,
|
|
672
|
-
simulcastConfig:
|
|
671
|
+
simulcastConfig: screenShareSimulcastConfig
|
|
673
672
|
)
|
|
674
673
|
}
|
|
675
674
|
|
|
676
|
-
func
|
|
677
|
-
sendEvent(name, data)
|
|
675
|
+
func emit(event: EmitableEvents, data: [String: Any] = [:]) {
|
|
676
|
+
sendEvent(event.name, data)
|
|
678
677
|
}
|
|
679
678
|
|
|
680
679
|
func emit(warning: String) {
|
|
681
|
-
|
|
680
|
+
emit(event: .Warning, data: ["message": warning])
|
|
682
681
|
}
|
|
683
682
|
|
|
684
683
|
func emitEndpoints() {
|
|
685
|
-
let
|
|
686
|
-
let EndpointsUpdateMap = [
|
|
687
|
-
|
|
684
|
+
let event = EmitableEvents.PeersUpdate
|
|
685
|
+
let EndpointsUpdateMap = [event.name: (try? getPeers()) ?? []]
|
|
686
|
+
emit(event: event, data: EndpointsUpdateMap)
|
|
688
687
|
}
|
|
689
688
|
|
|
690
689
|
func onJoined(peerID: String, peersInRoom: [String: Endpoint]) {
|
|
@@ -692,6 +691,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
692
691
|
connectPromise?.resolve(nil)
|
|
693
692
|
connectPromise = nil
|
|
694
693
|
emitEndpoints()
|
|
694
|
+
peerStatus = .connected
|
|
695
695
|
}
|
|
696
696
|
|
|
697
697
|
func onJoinError(metadata: Any) {
|
|
@@ -753,6 +753,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
753
753
|
"E_MEMBRANE_CONNECT", "Failed to connect: socket close, code: \(code), reason: \(reason)")
|
|
754
754
|
}
|
|
755
755
|
connectPromise = nil
|
|
756
|
+
peerStatus = .error
|
|
756
757
|
}
|
|
757
758
|
|
|
758
759
|
func onSocketError() {
|
|
@@ -764,7 +765,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
764
765
|
|
|
765
766
|
func onSocketOpen() {}
|
|
766
767
|
|
|
767
|
-
func onDisconnected() {
|
|
768
|
+
func onDisconnected() {
|
|
769
|
+
peerStatus = .idle
|
|
770
|
+
}
|
|
768
771
|
|
|
769
772
|
func getSimulcastConfigAsRNMap(_ simulcastConfig: SimulcastConfig) -> [String: Any] {
|
|
770
773
|
return [
|
|
@@ -826,11 +829,11 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
826
829
|
default:
|
|
827
830
|
deviceTypeString = deviceType.rawValue
|
|
828
831
|
}
|
|
829
|
-
let
|
|
830
|
-
|
|
831
|
-
|
|
832
|
+
let event = EmitableEvents.AudioDeviceUpdate
|
|
833
|
+
emit(
|
|
834
|
+
event: event,
|
|
832
835
|
data: [
|
|
833
|
-
|
|
836
|
+
event.name: [
|
|
834
837
|
"selectedDevice": ["name": output.portName, "type": deviceTypeString],
|
|
835
838
|
"availableDevices": [],
|
|
836
839
|
]
|
|
@@ -838,20 +841,20 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
838
841
|
}
|
|
839
842
|
|
|
840
843
|
func onBandwidthEstimationChanged(estimation: Int) {
|
|
841
|
-
let
|
|
842
|
-
|
|
844
|
+
let event = EmitableEvents.BandwidthEstimation
|
|
845
|
+
emit(event: event, data: [event.name: estimation])
|
|
843
846
|
}
|
|
844
847
|
|
|
845
848
|
func onReconnectionStarted() {
|
|
846
|
-
|
|
849
|
+
emit(event: .ReconnectionStarted)
|
|
847
850
|
}
|
|
848
851
|
|
|
849
852
|
func onReconnected() {
|
|
850
|
-
|
|
853
|
+
emit(event: .Reconnected)
|
|
851
854
|
}
|
|
852
855
|
|
|
853
856
|
func onReconnectionRetriesLimitReached() {
|
|
854
|
-
|
|
857
|
+
emit(event: .ReconnectionRetriesLimitReached)
|
|
855
858
|
}
|
|
856
859
|
|
|
857
860
|
}
|
|
@@ -13,7 +13,7 @@ struct CameraConfig: Record {
|
|
|
13
13
|
var quality: String = "VGA169"
|
|
14
14
|
|
|
15
15
|
@Field
|
|
16
|
-
var
|
|
16
|
+
var flipDimensions: Bool = false
|
|
17
17
|
|
|
18
18
|
@Field
|
|
19
19
|
var videoTrackMetadata: [String: Any] = [:]
|
|
@@ -39,12 +39,12 @@ struct MicrophoneConfig: Record {
|
|
|
39
39
|
var microphoneEnabled: Bool = true
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
struct
|
|
42
|
+
struct ScreenShareOptions: Record {
|
|
43
43
|
@Field
|
|
44
44
|
var quality: String = "HD15"
|
|
45
45
|
|
|
46
46
|
@Field
|
|
47
|
-
var
|
|
47
|
+
var screenShareMetadata: [String: Any] = [:]
|
|
48
48
|
|
|
49
49
|
@Field
|
|
50
50
|
var simulcastConfig: RNSimulcastConfig = RNSimulcastConfig()
|
|
@@ -75,18 +75,7 @@ public class RNFishjamClientModule: Module {
|
|
|
75
75
|
public func definition() -> ModuleDefinition {
|
|
76
76
|
Name("RNFishjamClient")
|
|
77
77
|
|
|
78
|
-
Events(
|
|
79
|
-
"IsCameraOn",
|
|
80
|
-
"IsMicrophoneOn",
|
|
81
|
-
"IsScreencastOn",
|
|
82
|
-
"SimulcastConfigUpdate",
|
|
83
|
-
"PeersUpdate",
|
|
84
|
-
"AudioDeviceUpdate",
|
|
85
|
-
"SendMediaEvent",
|
|
86
|
-
"BandwidthEstimation",
|
|
87
|
-
"ReconnectionRetriesLimitReached",
|
|
88
|
-
"ReconnectionStarted",
|
|
89
|
-
"Reconnected")
|
|
78
|
+
Events(EmitableEvents.allEvents)
|
|
90
79
|
|
|
91
80
|
let rnFishjamClient: RNFishjamClient = {
|
|
92
81
|
let client = RNFishjamClient {
|
|
@@ -99,11 +88,11 @@ public class RNFishjamClientModule: Module {
|
|
|
99
88
|
|
|
100
89
|
AsyncFunction("joinRoom") {
|
|
101
90
|
(
|
|
102
|
-
url: String,
|
|
91
|
+
url: String, peerToken: String, peerMetadata: [String: Any], config: ConnectConfig,
|
|
103
92
|
promise: Promise
|
|
104
93
|
) in
|
|
105
94
|
rnFishjamClient.joinRoom(
|
|
106
|
-
url: url,
|
|
95
|
+
url: url, peerToken: peerToken, peerMetadata: peerMetadata, config: config,
|
|
107
96
|
promise: promise)
|
|
108
97
|
}
|
|
109
98
|
|
|
@@ -143,12 +132,12 @@ public class RNFishjamClientModule: Module {
|
|
|
143
132
|
rnFishjamClient.getCaptureDevices()
|
|
144
133
|
}
|
|
145
134
|
|
|
146
|
-
AsyncFunction("
|
|
147
|
-
try rnFishjamClient.
|
|
135
|
+
AsyncFunction("toggleScreenShare") { (screenShareOptions: ScreenShareOptions) in
|
|
136
|
+
try rnFishjamClient.toggleScreenShare(screenShareOptions: screenShareOptions)
|
|
148
137
|
}
|
|
149
138
|
|
|
150
|
-
Property("
|
|
151
|
-
return rnFishjamClient.
|
|
139
|
+
Property("isScreenShareOn") {
|
|
140
|
+
return rnFishjamClient.isScreenShareOn
|
|
152
141
|
}
|
|
153
142
|
|
|
154
143
|
AsyncFunction("getPeers") {
|
|
@@ -167,20 +156,20 @@ public class RNFishjamClientModule: Module {
|
|
|
167
156
|
try rnFishjamClient.updateLocalAudioTrackMetadata(metadata: metadata)
|
|
168
157
|
}
|
|
169
158
|
|
|
170
|
-
AsyncFunction("
|
|
171
|
-
try rnFishjamClient.
|
|
159
|
+
AsyncFunction("updateScreenShareTrackMetadata") { (metadata: [String: Any]) in
|
|
160
|
+
try rnFishjamClient.updateLocalScreenShareTrackMetadata(metadata: metadata)
|
|
172
161
|
}
|
|
173
162
|
|
|
174
|
-
AsyncFunction("
|
|
175
|
-
try rnFishjamClient.
|
|
163
|
+
AsyncFunction("toggleScreenShareTrackEncoding") { (encoding: String) in
|
|
164
|
+
try rnFishjamClient.toggleScreenShareTrackEncoding(encoding: encoding)
|
|
176
165
|
}
|
|
177
166
|
|
|
178
|
-
AsyncFunction("
|
|
179
|
-
try rnFishjamClient.
|
|
167
|
+
AsyncFunction("setScreenShareTrackBandwidth") { (bandwidth: Int) in
|
|
168
|
+
try rnFishjamClient.setScreenShareTrackBandwidth(bandwidth: bandwidth)
|
|
180
169
|
}
|
|
181
170
|
|
|
182
|
-
AsyncFunction("
|
|
183
|
-
try rnFishjamClient.
|
|
171
|
+
AsyncFunction("setScreenShareTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in
|
|
172
|
+
try rnFishjamClient.setScreenShareTrackEncodingBandwidth(
|
|
184
173
|
encoding: encoding, bandwidth: bandwidth)
|
|
185
174
|
}
|
|
186
175
|
|
|
@@ -220,5 +209,9 @@ public class RNFishjamClientModule: Module {
|
|
|
220
209
|
AsyncFunction("startAudioSwitcher") {
|
|
221
210
|
rnFishjamClient.startAudioSwitcher()
|
|
222
211
|
}
|
|
212
|
+
|
|
213
|
+
Property("peerStatus") {
|
|
214
|
+
return rnFishjamClient.peerStatus.rawValue
|
|
215
|
+
}
|
|
223
216
|
}
|
|
224
217
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import ExpoModulesCore
|
|
2
2
|
import FishjamCloudClient
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
protocol OnLocalCameraTrackChangedListener: AnyObject {
|
|
5
|
+
func onLocalCameraTrackChanged()
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
class VideoPreviewView: ExpoView, OnLocalCameraTrackChangedListener {
|
|
5
9
|
var videoView: VideoView? = nil
|
|
6
10
|
private var localVideoTrack: LocalVideoTrack? = nil
|
|
7
11
|
|
|
@@ -13,11 +17,9 @@ class VideoPreviewView: ExpoView {
|
|
|
13
17
|
addSubview(videoView!)
|
|
14
18
|
}
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
localVideoTrack?.stop()
|
|
20
|
-
} else {
|
|
20
|
+
private func trySetLocalCameraTrack() {
|
|
21
|
+
DispatchQueue.main.async { [weak self] in
|
|
22
|
+
guard let self else { return }
|
|
21
23
|
guard let tracks = RNFishjamClient.fishjamClient?.getLocalEndpoint().tracks else {
|
|
22
24
|
os_log(
|
|
23
25
|
"Error moving VideoPreviewView: %{public}s", log: log, type: .error,
|
|
@@ -26,12 +28,23 @@ class VideoPreviewView: ExpoView {
|
|
|
26
28
|
return
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
localVideoTrack =
|
|
31
|
+
self.localVideoTrack =
|
|
30
32
|
tracks.first(where: { (key, track) in
|
|
31
33
|
track is LocalVideoTrack
|
|
32
34
|
})?.value as? LocalVideoTrack
|
|
33
|
-
localVideoTrack?.start()
|
|
34
|
-
videoView?.track = localVideoTrack
|
|
35
|
+
self.localVideoTrack?.start()
|
|
36
|
+
self.videoView?.track = self.localVideoTrack
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
override func willMove(toSuperview newSuperview: UIView?) {
|
|
41
|
+
super.willMove(toSuperview: newSuperview)
|
|
42
|
+
if newSuperview == nil {
|
|
43
|
+
RNFishjamClient.localCameraTrackListeners.removeAll(where: { $0 === self })
|
|
44
|
+
localVideoTrack?.stop()
|
|
45
|
+
} else {
|
|
46
|
+
RNFishjamClient.localCameraTrackListeners.append(self)
|
|
47
|
+
trySetLocalCameraTrack()
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
|
|
@@ -61,4 +74,9 @@ class VideoPreviewView: ExpoView {
|
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
76
|
}
|
|
77
|
+
|
|
78
|
+
func onLocalCameraTrackChanged() {
|
|
79
|
+
guard localVideoTrack == nil else { return }
|
|
80
|
+
trySetLocalCameraTrack()
|
|
81
|
+
}
|
|
64
82
|
}
|