@fishjam-cloud/react-native-client 0.2.2 → 0.2.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.
- package/README.md +9 -397
- package/android/build.gradle +1 -1
- package/android/src/main/java/io/fishjam/reactnative/EmitableEvents.kt +2 -1
- package/android/src/main/java/io/fishjam/reactnative/Errors.kt +3 -2
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClient.kt +86 -73
- package/android/src/main/java/io/fishjam/reactnative/RNFishjamClientModule.kt +20 -19
- package/build/RNFishjamClientModule.d.ts +10 -8
- package/build/RNFishjamClientModule.d.ts.map +1 -1
- package/build/RNFishjamClientModule.js +2 -1
- package/build/RNFishjamClientModule.js.map +1 -1
- package/build/common/client.d.ts +8 -5
- package/build/common/client.d.ts.map +1 -1
- package/build/common/client.js +9 -6
- package/build/common/client.js.map +1 -1
- package/build/common/metadata.d.ts +4 -3
- package/build/common/metadata.d.ts.map +1 -1
- package/build/common/metadata.js +5 -4
- package/build/common/metadata.js.map +1 -1
- package/build/common/webRTC.d.ts +2 -0
- package/build/common/webRTC.d.ts.map +1 -1
- package/build/common/webRTC.js +2 -0
- package/build/common/webRTC.js.map +1 -1
- package/build/components/VideoPreviewView.d.ts +6 -3
- package/build/components/VideoPreviewView.d.ts.map +1 -1
- package/build/components/VideoPreviewView.js +5 -0
- package/build/components/VideoPreviewView.js.map +1 -1
- package/build/components/VideoRendererView.d.ts +5 -3
- package/build/components/VideoRendererView.d.ts.map +1 -1
- package/build/components/VideoRendererView.js +4 -0
- package/build/components/VideoRendererView.js.map +1 -1
- package/build/hooks/useAudioSettings.d.ts +15 -0
- package/build/hooks/useAudioSettings.d.ts.map +1 -1
- package/build/hooks/useAudioSettings.js +15 -13
- package/build/hooks/useAudioSettings.js.map +1 -1
- package/build/hooks/useBandwidthEstimation.d.ts +2 -0
- package/build/hooks/useBandwidthEstimation.d.ts.map +1 -1
- package/build/hooks/useBandwidthEstimation.js +2 -0
- package/build/hooks/useBandwidthEstimation.js.map +1 -1
- package/build/hooks/useCamera.d.ts +62 -1
- package/build/hooks/useCamera.d.ts.map +1 -1
- package/build/hooks/useCamera.js +46 -38
- 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 +4 -5
- package/build/hooks/useFishjamEvent.js.map +1 -1
- package/build/hooks/useMicrophone.d.ts +4 -0
- package/build/hooks/useMicrophone.d.ts.map +1 -1
- package/build/hooks/useMicrophone.js +8 -4
- package/build/hooks/useMicrophone.js.map +1 -1
- package/build/hooks/useParticipants.d.ts +2 -0
- package/build/hooks/useParticipants.d.ts.map +1 -1
- package/build/hooks/useParticipants.js +2 -0
- package/build/hooks/useParticipants.js.map +1 -1
- package/build/hooks/useReconnection.d.ts +6 -0
- package/build/hooks/useReconnection.d.ts.map +1 -1
- package/build/hooks/useReconnection.js +6 -0
- package/build/hooks/useReconnection.js.map +1 -1
- 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 +4 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/stats/useRTCStatistics.d.ts +1 -0
- package/build/stats/useRTCStatistics.d.ts.map +1 -1
- package/build/stats/useRTCStatistics.js +1 -0
- package/build/stats/useRTCStatistics.js.map +1 -1
- package/build/types.d.ts +6 -0
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/build/utils/errorListener.d.ts +2 -0
- package/build/utils/errorListener.d.ts.map +1 -0
- package/build/utils/errorListener.js +16 -0
- package/build/utils/errorListener.js.map +1 -0
- package/build/utils/foregroundService.d.ts +2 -0
- package/build/utils/foregroundService.d.ts.map +1 -1
- package/build/utils/foregroundService.js +2 -0
- package/build/utils/foregroundService.js.map +1 -1
- package/ios/Events.swift +2 -1
- package/ios/RNFishjamClient.podspec +1 -1
- package/ios/RNFishjamClient.swift +76 -62
- package/ios/RNFishjamClientModule.swift +18 -17
- package/package.json +13 -10
- package/plugin/broadcastExtensionFiles/FishjamBroadcastSampleHandler.swift +50 -0
- package/plugin/broadcastExtensionFiles/FishjamScreenBroadcastExtension.entitlements +10 -0
- package/plugin/broadcastExtensionFiles/Info.plist +27 -0
- package/plugin/build/types.d.ts +5 -5
- package/plugin/build/withFishjamAndroid.js +2 -2
- package/plugin/build/withFishjamIos.js +4 -4
- package/build/hooks/useScreencast.d.ts +0 -38
- package/build/hooks/useScreencast.d.ts.map +0 -1
- package/build/hooks/useScreencast.js +0 -77
- package/build/hooks/useScreencast.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foregroundService.d.ts","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEpD
|
|
1
|
+
{"version":3,"file":"foregroundService.d.ts","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;MAoBM;AACN,eAAO,MAAM,sBAAsB,YAAa,wBAAwB,SAKvE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,YAKjC,CAAC"}
|
|
@@ -19,6 +19,7 @@ import RNFishjamClientModule from '../RNFishjamClientModule';
|
|
|
19
19
|
```
|
|
20
20
|
<service android:name="io.fishjam.reactnative.FishjamForegroundService" android:foregroundServiceType="camera|microphone|mediaProjection"/>
|
|
21
21
|
```
|
|
22
|
+
* @category Screenshare
|
|
22
23
|
*/
|
|
23
24
|
export const startForegroundService = (options) => {
|
|
24
25
|
if (Platform.OS !== 'android') {
|
|
@@ -31,6 +32,7 @@ export const startForegroundService = (options) => {
|
|
|
31
32
|
* @see {@link startForegroundService} for further information.
|
|
32
33
|
*
|
|
33
34
|
* Does nothing on other platforms.
|
|
35
|
+
* @category Screenshare
|
|
34
36
|
*/
|
|
35
37
|
export const stopForegroundService = () => {
|
|
36
38
|
if (Platform.OS !== 'android') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"foregroundService.js","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAG7D
|
|
1
|
+
{"version":3,"file":"foregroundService.js","sourceRoot":"","sources":["../../src/utils/foregroundService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,qBAAqB,MAAM,0BAA0B,CAAC;AAG7D;;;;;;;;;;;;;;;;;;;;MAoBM;AACN,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAiC,EAAE,EAAE;IAC1E,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,EAAE;IACxC,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;IACT,CAAC;IACD,qBAAqB,CAAC,qBAAqB,EAAE,CAAC;AAChD,CAAC,CAAC","sourcesContent":["import { Platform } from 'react-native';\nimport RNFishjamClientModule from '../RNFishjamClientModule';\nimport { ForegroundServiceOptions } from '../types';\n\n/**\n * Launches a foreground service on Android.\n * Does nothing on other platforms.\n * \n * @remarks\n * You must have have the following permissions enabled before calling this function:\n * @example\n ```\n \"android.permission.FOREGROUND_SERVICE\"\n \"android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION\"\n \"android.permission.FOREGROUND_SERVICE_CAMERA\"\n \"android.permission.FOREGROUND_SERVICE_MICROPHONE\"\n \"android.permission.POST_NOTIFICATIONS\"\n *```\n * as well as FishjamForegroundService in your AndroidManifest:\n * @example\n ```\n <service android:name=\"io.fishjam.reactnative.FishjamForegroundService\" android:foregroundServiceType=\"camera|microphone|mediaProjection\"/>\n ```\n * @category Screenshare\n */\nexport const startForegroundService = (options: ForegroundServiceOptions) => {\n if (Platform.OS !== 'android') {\n return;\n }\n RNFishjamClientModule.startForegroundService(options);\n};\n\n/**\n * Stops previously launched Android foreground service.\n * @see {@link startForegroundService} for further information.\n *\n * Does nothing on other platforms.\n * @category Screenshare\n */\nexport const stopForegroundService = () => {\n if (Platform.OS !== 'android') {\n return;\n }\n RNFishjamClientModule.stopForegroundService();\n};\n"]}
|
package/ios/Events.swift
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
struct EmitableEvents {
|
|
2
2
|
static let IsCameraOn = "IsCameraOn"
|
|
3
3
|
static let IsMicrophoneOn = "IsMicrophoneOn"
|
|
4
|
-
static let
|
|
4
|
+
static let IsScreenShareOn = "IsScreenShareOn"
|
|
5
5
|
static let SimulcastConfigUpdate = "SimulcastConfigUpdate"
|
|
6
6
|
static let PeersUpdate = "PeersUpdate"
|
|
7
7
|
static let AudioDeviceUpdate = "AudioDeviceUpdate"
|
|
@@ -10,4 +10,5 @@ struct EmitableEvents {
|
|
|
10
10
|
static let ReconnectionRetriesLimitReached = "ReconnectionRetriesLimitReached"
|
|
11
11
|
static let ReconnectionStarted = "ReconnectionStarted"
|
|
12
12
|
static let Reconnected = "Reconnected"
|
|
13
|
+
static let Warning = "Warning"
|
|
13
14
|
}
|
|
@@ -10,16 +10,18 @@ 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
|
+
private var isCameraInitialized = false
|
|
17
|
+
|
|
16
18
|
var connectPromise: Promise? = nil
|
|
17
19
|
|
|
18
20
|
var videoSimulcastConfig: SimulcastConfig = SimulcastConfig()
|
|
19
21
|
var localUserMetadata: Metadata = .init()
|
|
20
22
|
|
|
21
|
-
var
|
|
22
|
-
var
|
|
23
|
+
var screenShareSimulcastConfig: SimulcastConfig = SimulcastConfig()
|
|
24
|
+
var screenShareMaxBandwidth: TrackBandwidthLimit = .BandwidthLimit(0)
|
|
23
25
|
|
|
24
26
|
var cameraId: String? = nil
|
|
25
27
|
|
|
@@ -70,7 +72,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
70
72
|
|
|
71
73
|
func getVideoParametersFromOptions(connectionOptions: CameraConfig) throws -> VideoParameters {
|
|
72
74
|
let videoQuality = connectionOptions.quality
|
|
73
|
-
let
|
|
75
|
+
let flipDimensions = connectionOptions.flipDimensions
|
|
74
76
|
let videoBandwidthLimit = getMaxBandwidthFromOptions(maxBandwidth: connectionOptions.maxBandwidth)
|
|
75
77
|
let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig: connectionOptions.simulcastConfig)
|
|
76
78
|
|
|
@@ -101,7 +103,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
101
103
|
}
|
|
102
104
|
}()
|
|
103
105
|
let videoParameters = VideoParameters(
|
|
104
|
-
dimensions:
|
|
106
|
+
dimensions: flipDimensions ? preset.dimensions.flip() : preset.dimensions,
|
|
105
107
|
maxBandwidth: videoBandwidthLimit,
|
|
106
108
|
simulcastConfig: simulcastConfig
|
|
107
109
|
)
|
|
@@ -118,9 +120,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
118
120
|
as? LocalAudioTrack
|
|
119
121
|
}
|
|
120
122
|
|
|
121
|
-
private func
|
|
122
|
-
return RNFishjamClient.fishjamClient?.getLocalEndpoint().tracks.first { $0.value is
|
|
123
|
-
.value as?
|
|
123
|
+
private func getLocalScreenShareTrack() -> LocalScreenShareTrack? {
|
|
124
|
+
return RNFishjamClient.fishjamClient?.getLocalEndpoint().tracks.first { $0.value is LocalScreenShareTrack }?
|
|
125
|
+
.value as? LocalScreenShareTrack
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
private func ensureCreated() throws {
|
|
@@ -157,11 +159,11 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
157
159
|
}
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
private func
|
|
161
|
-
if
|
|
162
|
+
private func ensureScreenShareTrack() throws {
|
|
163
|
+
if getLocalScreenShareTrack() == nil {
|
|
162
164
|
throw Exception(
|
|
163
|
-
name: "
|
|
164
|
-
description: "No local
|
|
165
|
+
name: "E_NO_LOCAL_SCREENSHARE_TRACK",
|
|
166
|
+
description: "No local screen share track. Make sure to toggle screen share on first!")
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
|
|
@@ -200,25 +202,33 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
200
202
|
}
|
|
201
203
|
|
|
202
204
|
func leaveRoom() {
|
|
203
|
-
if
|
|
204
|
-
let
|
|
205
|
-
Bundle.main.infoDictionary?["
|
|
205
|
+
if isScreenShareOn {
|
|
206
|
+
let screenShareExtensionBundleId =
|
|
207
|
+
Bundle.main.infoDictionary?["ScreenShareExtensionBundleId"] as? String
|
|
206
208
|
DispatchQueue.main.async {
|
|
207
|
-
RPSystemBroadcastPickerView.show(for:
|
|
209
|
+
RPSystemBroadcastPickerView.show(for: screenShareExtensionBundleId)
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
isMicrophoneOn = false
|
|
211
213
|
isCameraOn = false
|
|
212
|
-
|
|
214
|
+
isScreenShareOn = false
|
|
213
215
|
isConnected = false
|
|
216
|
+
isCameraInitialized = false
|
|
214
217
|
RNFishjamClient.fishjamClient?.leave()
|
|
215
218
|
}
|
|
216
219
|
|
|
217
220
|
func startCamera(config: CameraConfig) throws {
|
|
218
221
|
try ensureCreated()
|
|
222
|
+
|
|
223
|
+
guard !isCameraInitialized else {
|
|
224
|
+
emit(warning: "Camera already started. You may only call startCamera once before leaveRoom is called.")
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
|
|
219
228
|
let cameraTrack = try createCameraTrack(config: config)
|
|
220
229
|
setCameraTrackState(cameraTrack, enabled: config.cameraEnabled)
|
|
221
230
|
emitEndpoints()
|
|
231
|
+
isCameraInitialized = true
|
|
222
232
|
}
|
|
223
233
|
|
|
224
234
|
private func createCameraTrack(config: CameraConfig) throws -> LocalVideoTrack {
|
|
@@ -301,15 +311,15 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
301
311
|
}
|
|
302
312
|
}
|
|
303
313
|
|
|
304
|
-
func
|
|
314
|
+
func toggleScreenShare(screenShareOptions: ScreenShareOptions) throws {
|
|
305
315
|
try ensureCreated()
|
|
306
316
|
try ensureConnected()
|
|
307
|
-
guard let
|
|
317
|
+
guard let screenShareExtensionBundleId = Bundle.main.infoDictionary?["ScreenShareExtensionBundleId"] as? String
|
|
308
318
|
else {
|
|
309
319
|
throw Exception(
|
|
310
320
|
name: "E_NO_BUNDLE_ID_SET",
|
|
311
321
|
description:
|
|
312
|
-
"No
|
|
322
|
+
"No screen share extension bundle id set. Please set ScreenShareExtensionBundleId in Info.plist"
|
|
313
323
|
)
|
|
314
324
|
}
|
|
315
325
|
guard let appGroupName = Bundle.main.infoDictionary?["AppGroupName"] as? String
|
|
@@ -319,63 +329,63 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
319
329
|
description: "No app group name set. Please set AppGroupName in Info.plist")
|
|
320
330
|
}
|
|
321
331
|
|
|
322
|
-
guard !
|
|
332
|
+
guard !isScreenShareOn else {
|
|
323
333
|
DispatchQueue.main.async {
|
|
324
|
-
RPSystemBroadcastPickerView.show(for:
|
|
334
|
+
RPSystemBroadcastPickerView.show(for: screenShareExtensionBundleId)
|
|
325
335
|
}
|
|
326
336
|
return
|
|
327
337
|
}
|
|
328
338
|
|
|
329
|
-
let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig:
|
|
339
|
+
let simulcastConfig = try getSimulcastConfigFromOptions(simulcastConfig: screenShareOptions.simulcastConfig)
|
|
330
340
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
maxBandwidth:
|
|
334
|
-
let
|
|
335
|
-
let videoParameters =
|
|
336
|
-
RNFishjamClient.fishjamClient!.
|
|
341
|
+
screenShareSimulcastConfig = simulcastConfig
|
|
342
|
+
screenShareMaxBandwidth = getMaxBandwidthFromOptions(
|
|
343
|
+
maxBandwidth: screenShareOptions.maxBandwidth)
|
|
344
|
+
let screenShareMetadata = screenShareOptions.screenShareMetadata.toMetadata()
|
|
345
|
+
let videoParameters = getScreenShareVideoParameters(options: screenShareOptions)
|
|
346
|
+
RNFishjamClient.fishjamClient!.createScreenShareTrack(
|
|
337
347
|
appGroup: appGroupName,
|
|
338
348
|
videoParameters: videoParameters,
|
|
339
|
-
metadata:
|
|
340
|
-
onStart: { [weak self]
|
|
349
|
+
metadata: screenShareMetadata,
|
|
350
|
+
onStart: { [weak self] screenShareTrack in
|
|
341
351
|
guard let self = self else { return }
|
|
342
352
|
|
|
343
353
|
do {
|
|
344
354
|
//not sure should it be here, or outside or where?
|
|
345
|
-
try
|
|
355
|
+
try setScreenShareTrackState(screenShareTrack, enabled: true)
|
|
346
356
|
} catch {
|
|
347
357
|
os_log(
|
|
348
|
-
"Error starting
|
|
358
|
+
"Error starting screen share: %{public}s", log: log, type: .error,
|
|
349
359
|
String(describing: error)
|
|
350
360
|
)
|
|
351
361
|
}
|
|
352
362
|
|
|
353
363
|
},
|
|
354
|
-
onStop: { [weak self]
|
|
364
|
+
onStop: { [weak self] screenShareTrack in
|
|
355
365
|
guard let self = self else { return }
|
|
356
366
|
do {
|
|
357
367
|
//not sure should it be here, or outside or where?
|
|
358
|
-
try
|
|
368
|
+
try setScreenShareTrackState(screenShareTrack, enabled: false)
|
|
359
369
|
} catch {
|
|
360
370
|
os_log(
|
|
361
|
-
"Error stopping
|
|
371
|
+
"Error stopping screen share: %{public}s", log: log, type: .error,
|
|
362
372
|
String(describing: error)
|
|
363
373
|
)
|
|
364
374
|
}
|
|
365
375
|
}
|
|
366
376
|
)
|
|
367
377
|
DispatchQueue.main.async {
|
|
368
|
-
RPSystemBroadcastPickerView.show(for:
|
|
378
|
+
RPSystemBroadcastPickerView.show(for: screenShareExtensionBundleId)
|
|
369
379
|
}
|
|
370
380
|
}
|
|
371
381
|
|
|
372
|
-
private func
|
|
382
|
+
private func setScreenShareTrackState(_ screenShareTrack: LocalScreenShareTrack, enabled: Bool) throws {
|
|
373
383
|
//was not present before, test and maybe delete?
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
let eventName = EmitableEvents.
|
|
377
|
-
let
|
|
378
|
-
emitEvent(name: eventName, data:
|
|
384
|
+
screenShareTrack.enabled = enabled
|
|
385
|
+
isScreenShareOn = enabled
|
|
386
|
+
let eventName = EmitableEvents.IsScreenShareOn
|
|
387
|
+
let isScreenShareEnabled = [eventName: enabled]
|
|
388
|
+
emitEvent(name: eventName, data: isScreenShareEnabled)
|
|
379
389
|
}
|
|
380
390
|
|
|
381
391
|
//returns local endpoint and remote endpoints
|
|
@@ -419,7 +429,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
419
429
|
"metadata": track.metadata.toDict(),
|
|
420
430
|
]
|
|
421
431
|
|
|
422
|
-
case let track as
|
|
432
|
+
case let track as LocalScreenShareTrack:
|
|
423
433
|
return [
|
|
424
434
|
"id": track.id,
|
|
425
435
|
"type": "Video",
|
|
@@ -482,9 +492,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
482
492
|
}
|
|
483
493
|
}
|
|
484
494
|
|
|
485
|
-
func
|
|
486
|
-
try
|
|
487
|
-
if let track =
|
|
495
|
+
func updateLocalScreenShareTrackMetadata(metadata: [String: Any]) throws {
|
|
496
|
+
try ensureScreenShareTrack()
|
|
497
|
+
if let track = getLocalScreenShareTrack() {
|
|
488
498
|
updateTrackMetadata(trackId: track.id, metadata: metadata)
|
|
489
499
|
}
|
|
490
500
|
}
|
|
@@ -508,25 +518,25 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
508
518
|
return SimulcastConfig(enabled: true, activeEncodings: updatedEncodings)
|
|
509
519
|
}
|
|
510
520
|
|
|
511
|
-
func
|
|
512
|
-
try
|
|
513
|
-
if let track =
|
|
514
|
-
|
|
515
|
-
encoding: encoding, trackId: track.id, simulcastConfig:
|
|
521
|
+
func toggleScreenShareTrackEncoding(encoding: String) throws -> [String: Any] {
|
|
522
|
+
try ensureScreenShareTrack()
|
|
523
|
+
if let track = getLocalScreenShareTrack() {
|
|
524
|
+
screenShareSimulcastConfig = try toggleTrackEncoding(
|
|
525
|
+
encoding: encoding, trackId: track.id, simulcastConfig: screenShareSimulcastConfig)
|
|
516
526
|
}
|
|
517
|
-
return getSimulcastConfigAsRNMap(
|
|
527
|
+
return getSimulcastConfigAsRNMap(screenShareSimulcastConfig)
|
|
518
528
|
}
|
|
519
529
|
|
|
520
|
-
func
|
|
521
|
-
try
|
|
522
|
-
if let track =
|
|
530
|
+
func setScreenShareTrackBandwidth(bandwidth: Int) throws {
|
|
531
|
+
try ensureScreenShareTrack()
|
|
532
|
+
if let track = getLocalScreenShareTrack() {
|
|
523
533
|
RNFishjamClient.fishjamClient?.setTrackBandwidth(trackId: track.id, bandwidthLimit: bandwidth)
|
|
524
534
|
}
|
|
525
535
|
}
|
|
526
536
|
|
|
527
|
-
func
|
|
528
|
-
try
|
|
529
|
-
if let track =
|
|
537
|
+
func setScreenShareTrackEncodingBandwidth(encoding: String, bandwidth: Int) throws {
|
|
538
|
+
try ensureScreenShareTrack()
|
|
539
|
+
if let track = getLocalScreenShareTrack() {
|
|
530
540
|
RNFishjamClient.fishjamClient?.setEncodingBandwidth(
|
|
531
541
|
trackId: track.id, encoding: encoding, bandwidthLimit: bandwidth)
|
|
532
542
|
}
|
|
@@ -639,7 +649,7 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
639
649
|
return Dictionary(uniqueKeysWithValues: pairs)
|
|
640
650
|
}
|
|
641
651
|
|
|
642
|
-
private func
|
|
652
|
+
private func getScreenShareVideoParameters(options: ScreenShareOptions) -> VideoParameters {
|
|
643
653
|
let preset: VideoParameters
|
|
644
654
|
switch options.quality {
|
|
645
655
|
case "VGA":
|
|
@@ -657,9 +667,9 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
657
667
|
}
|
|
658
668
|
return VideoParameters(
|
|
659
669
|
dimensions: preset.dimensions.flip(),
|
|
660
|
-
maxBandwidth:
|
|
670
|
+
maxBandwidth: screenShareMaxBandwidth,
|
|
661
671
|
maxFps: preset.maxFps,
|
|
662
|
-
simulcastConfig:
|
|
672
|
+
simulcastConfig: screenShareSimulcastConfig
|
|
663
673
|
)
|
|
664
674
|
}
|
|
665
675
|
|
|
@@ -667,6 +677,10 @@ class RNFishjamClient: FishjamClientListener {
|
|
|
667
677
|
sendEvent(name, data)
|
|
668
678
|
}
|
|
669
679
|
|
|
680
|
+
func emit(warning: String) {
|
|
681
|
+
emitEvent(name: EmitableEvents.Warning, data: ["message": warning])
|
|
682
|
+
}
|
|
683
|
+
|
|
670
684
|
func emitEndpoints() {
|
|
671
685
|
let eventName = EmitableEvents.PeersUpdate
|
|
672
686
|
let EndpointsUpdateMap = [eventName: (try? getPeers()) ?? []]
|
|
@@ -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()
|
|
@@ -78,7 +78,7 @@ public class RNFishjamClientModule: Module {
|
|
|
78
78
|
Events(
|
|
79
79
|
"IsCameraOn",
|
|
80
80
|
"IsMicrophoneOn",
|
|
81
|
-
"
|
|
81
|
+
"IsScreenShareOn",
|
|
82
82
|
"SimulcastConfigUpdate",
|
|
83
83
|
"PeersUpdate",
|
|
84
84
|
"AudioDeviceUpdate",
|
|
@@ -86,7 +86,8 @@ public class RNFishjamClientModule: Module {
|
|
|
86
86
|
"BandwidthEstimation",
|
|
87
87
|
"ReconnectionRetriesLimitReached",
|
|
88
88
|
"ReconnectionStarted",
|
|
89
|
-
"Reconnected"
|
|
89
|
+
"Reconnected",
|
|
90
|
+
"Warning")
|
|
90
91
|
|
|
91
92
|
let rnFishjamClient: RNFishjamClient = {
|
|
92
93
|
let client = RNFishjamClient {
|
|
@@ -143,12 +144,12 @@ public class RNFishjamClientModule: Module {
|
|
|
143
144
|
rnFishjamClient.getCaptureDevices()
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
AsyncFunction("
|
|
147
|
-
try rnFishjamClient.
|
|
147
|
+
AsyncFunction("toggleScreenShare") { (screenShareOptions: ScreenShareOptions) in
|
|
148
|
+
try rnFishjamClient.toggleScreenShare(screenShareOptions: screenShareOptions)
|
|
148
149
|
}
|
|
149
150
|
|
|
150
|
-
Property("
|
|
151
|
-
return rnFishjamClient.
|
|
151
|
+
Property("isScreenShareOn") {
|
|
152
|
+
return rnFishjamClient.isScreenShareOn
|
|
152
153
|
}
|
|
153
154
|
|
|
154
155
|
AsyncFunction("getPeers") {
|
|
@@ -167,20 +168,20 @@ public class RNFishjamClientModule: Module {
|
|
|
167
168
|
try rnFishjamClient.updateLocalAudioTrackMetadata(metadata: metadata)
|
|
168
169
|
}
|
|
169
170
|
|
|
170
|
-
AsyncFunction("
|
|
171
|
-
try rnFishjamClient.
|
|
171
|
+
AsyncFunction("updateScreenShareTrackMetadata") { (metadata: [String: Any]) in
|
|
172
|
+
try rnFishjamClient.updateLocalScreenShareTrackMetadata(metadata: metadata)
|
|
172
173
|
}
|
|
173
174
|
|
|
174
|
-
AsyncFunction("
|
|
175
|
-
try rnFishjamClient.
|
|
175
|
+
AsyncFunction("toggleScreenShareTrackEncoding") { (encoding: String) in
|
|
176
|
+
try rnFishjamClient.toggleScreenShareTrackEncoding(encoding: encoding)
|
|
176
177
|
}
|
|
177
178
|
|
|
178
|
-
AsyncFunction("
|
|
179
|
-
try rnFishjamClient.
|
|
179
|
+
AsyncFunction("setScreenShareTrackBandwidth") { (bandwidth: Int) in
|
|
180
|
+
try rnFishjamClient.setScreenShareTrackBandwidth(bandwidth: bandwidth)
|
|
180
181
|
}
|
|
181
182
|
|
|
182
|
-
AsyncFunction("
|
|
183
|
-
try rnFishjamClient.
|
|
183
|
+
AsyncFunction("setScreenShareTrackEncodingBandwidth") { (encoding: String, bandwidth: Int) in
|
|
184
|
+
try rnFishjamClient.setScreenShareTrackEncodingBandwidth(
|
|
184
185
|
encoding: encoding, bandwidth: bandwidth)
|
|
185
186
|
}
|
|
186
187
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fishjam-cloud/react-native-client",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "A React Native client for Fishjam Cloud",
|
|
5
5
|
"author": "Fishjam Cloud Team",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,20 +22,22 @@
|
|
|
22
22
|
"keywords": [
|
|
23
23
|
"react-native",
|
|
24
24
|
"expo",
|
|
25
|
-
"
|
|
26
|
-
"fishjam-cloud",
|
|
25
|
+
"FishjamCloud",
|
|
27
26
|
"MembraneWebRTC",
|
|
28
|
-
"
|
|
27
|
+
"webRTC",
|
|
28
|
+
"streaming",
|
|
29
|
+
"video",
|
|
30
|
+
"audio"
|
|
29
31
|
],
|
|
30
|
-
"repository":
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/fishjam-cloud/mobile-client-sdk.git",
|
|
35
|
+
"directory": "packages/react-native-client"
|
|
36
|
+
},
|
|
31
37
|
"bugs": {
|
|
32
38
|
"url": "https://github.com/fishjam-cloud/mobile-client-sdk/issues"
|
|
33
39
|
},
|
|
34
40
|
"homepage": "https://fishjam.io",
|
|
35
|
-
"publishConfig": {
|
|
36
|
-
"registry": "https://registry.npmjs.org/",
|
|
37
|
-
"access": "public"
|
|
38
|
-
},
|
|
39
41
|
"dependencies": {
|
|
40
42
|
"phoenix": "^1.7.6",
|
|
41
43
|
"promise-fs": "^2.1.1",
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
"@types/lodash": "^4.17.7",
|
|
47
49
|
"@types/phoenix": "^1.6.5",
|
|
48
50
|
"@types/promise-fs": "^2.1.2",
|
|
49
|
-
"@types/react": "^18.3.
|
|
51
|
+
"@types/react": "^18.3.7",
|
|
50
52
|
"expo": "^51.0.32",
|
|
51
53
|
"expo-module-scripts": "^3.5.2",
|
|
52
54
|
"expo-modules-core": "^1.12.24",
|
|
@@ -84,6 +86,7 @@
|
|
|
84
86
|
"ios/*.swift",
|
|
85
87
|
"ios/RNFishjamClient.podspec",
|
|
86
88
|
"plugin/build/**",
|
|
89
|
+
"plugin/broadcastExtensionFiles/**",
|
|
87
90
|
"app.plugin.js",
|
|
88
91
|
"expo-module.config.json",
|
|
89
92
|
"README.md",
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import FishjamCloudClient
|
|
2
|
+
import Foundation
|
|
3
|
+
import ReplayKit
|
|
4
|
+
import WebRTC
|
|
5
|
+
import os.log
|
|
6
|
+
|
|
7
|
+
/// App Group used by the extension to exchange buffers with the target application
|
|
8
|
+
let appGroup = "{{GROUP_IDENTIFIER}}"
|
|
9
|
+
|
|
10
|
+
let logger = OSLog(subsystem: "{{BUNDLE_IDENTIFIER}}.FishjamBroadcastSampleHandler", category: "Broadcaster")
|
|
11
|
+
|
|
12
|
+
/// An example `SampleHandler` utilizing `BroadcastSampleSource` from `MembraneRTC` sending broadcast samples and necessary notification enabling device's screen share.
|
|
13
|
+
class FishjamBroadcastSampleHandler: RPBroadcastSampleHandler {
|
|
14
|
+
let broadcastSource = BroadcastSampleSource(appGroup: appGroup)
|
|
15
|
+
var started: Bool = false
|
|
16
|
+
|
|
17
|
+
override func broadcastStarted(withSetupInfo _: [String: NSObject]?) {
|
|
18
|
+
started = broadcastSource.connect()
|
|
19
|
+
|
|
20
|
+
guard started else {
|
|
21
|
+
os_log("failed to connect with ipc server", log: logger, type: .debug)
|
|
22
|
+
|
|
23
|
+
super.finishBroadcastWithError(NSError(domain: "", code: 0, userInfo: nil))
|
|
24
|
+
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
broadcastSource.started()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
override func broadcastPaused() {
|
|
32
|
+
broadcastSource.paused()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override func broadcastResumed() {
|
|
36
|
+
broadcastSource.resumed()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override func broadcastFinished() {
|
|
40
|
+
broadcastSource.finished()
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
|
|
44
|
+
guard started else {
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
broadcastSource.processFrame(sampleBuffer: sampleBuffer, ofType: sampleBufferType)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>com.apple.security.application-groups</key>
|
|
6
|
+
<array>
|
|
7
|
+
<string>{{GROUP_IDENTIFIER}}</string>
|
|
8
|
+
</array>
|
|
9
|
+
</dict>
|
|
10
|
+
</plist>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDisplayName</key>
|
|
6
|
+
<string>FishjamScreenBroadcast</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleName</key>
|
|
12
|
+
<string>$(PRODUCT_NAME)</string>
|
|
13
|
+
<key>CFBundlePackageType</key>
|
|
14
|
+
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
|
15
|
+
<key>CFBundleVersion</key>
|
|
16
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
17
|
+
<key>NSExtension</key>
|
|
18
|
+
<dict>
|
|
19
|
+
<key>NSExtensionPointIdentifier</key>
|
|
20
|
+
<string>com.apple.broadcast-services-upload</string>
|
|
21
|
+
<key>NSExtensionPrincipalClass</key>
|
|
22
|
+
<string>$(PRODUCT_MODULE_NAME).FishjamBroadcastSampleHandler</string>
|
|
23
|
+
<key>RPBroadcastProcessMode</key>
|
|
24
|
+
<string>RPBroadcastProcessModeSampleBuffer</string>
|
|
25
|
+
</dict>
|
|
26
|
+
</dict>
|
|
27
|
+
</plist>
|
package/plugin/build/types.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export type FishjamPluginOptions = {
|
|
2
|
-
android
|
|
3
|
-
enableForegroundService
|
|
2
|
+
android?: {
|
|
3
|
+
enableForegroundService?: boolean;
|
|
4
4
|
};
|
|
5
|
-
ios
|
|
5
|
+
ios?: {
|
|
6
6
|
iphoneDeploymentTarget?: string;
|
|
7
|
-
enableScreensharing
|
|
7
|
+
enableScreensharing?: boolean;
|
|
8
8
|
};
|
|
9
|
-
};
|
|
9
|
+
} | undefined;
|
|
@@ -23,8 +23,8 @@ const withFishjamForegroundService = (config) => {
|
|
|
23
23
|
return config;
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
|
-
const withFishjamAndroid = (config,
|
|
27
|
-
if (enableForegroundService) {
|
|
26
|
+
const withFishjamAndroid = (config, props) => {
|
|
27
|
+
if (props?.android?.enableForegroundService) {
|
|
28
28
|
config = withFishjamForegroundService(config);
|
|
29
29
|
}
|
|
30
30
|
return config;
|