@fishjam-cloud/react-native-client 0.1.1 → 0.2.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/README.md +403 -0
- package/android/build.gradle +6 -6
- package/app.plugin.js +1 -1
- package/build/RNFishjamClientModule.d.ts +7 -5
- package/build/RNFishjamClientModule.d.ts.map +1 -1
- package/build/RNFishjamClientModule.js.map +1 -1
- package/build/common/client.d.ts +8 -1
- package/build/common/client.d.ts.map +1 -1
- package/build/common/client.js +9 -2
- package/build/common/client.js.map +1 -1
- package/build/components/VideoPreviewView.d.ts +3 -3
- package/build/components/VideoPreviewView.d.ts.map +1 -1
- package/build/components/VideoPreviewView.js +1 -1
- package/build/components/VideoPreviewView.js.map +1 -1
- package/build/hooks/useAudioSettings.d.ts.map +1 -1
- package/build/hooks/useAudioSettings.js +4 -5
- package/build/hooks/useAudioSettings.js.map +1 -1
- package/build/hooks/useBandwidthEstimation.d.ts +0 -3
- package/build/hooks/useBandwidthEstimation.d.ts.map +1 -1
- package/build/hooks/useBandwidthEstimation.js +3 -6
- package/build/hooks/useBandwidthEstimation.js.map +1 -1
- package/build/hooks/useCamera.d.ts +12 -21
- package/build/hooks/useCamera.d.ts.map +1 -1
- package/build/hooks/useCamera.js +52 -52
- package/build/hooks/useCamera.js.map +1 -1
- package/build/{common/eventEmitter.d.ts → hooks/useFishjamEvent.d.ts} +2 -3
- package/build/hooks/useFishjamEvent.d.ts.map +1 -0
- package/build/{common/eventEmitter.js → hooks/useFishjamEvent.js} +11 -2
- package/build/hooks/useFishjamEvent.js.map +1 -0
- package/build/hooks/useMicrophone.d.ts.map +1 -1
- package/build/hooks/useMicrophone.js +3 -7
- package/build/hooks/useMicrophone.js.map +1 -1
- package/build/hooks/useParticipants.d.ts +0 -3
- package/build/hooks/useParticipants.d.ts.map +1 -1
- package/build/hooks/useParticipants.js +6 -6
- package/build/hooks/useParticipants.js.map +1 -1
- package/build/hooks/useReconnection.d.ts.map +1 -1
- package/build/hooks/useReconnection.js +8 -18
- package/build/hooks/useReconnection.js.map +1 -1
- package/build/hooks/useScreencast.d.ts.map +1 -1
- package/build/hooks/useScreencast.js +3 -7
- package/build/hooks/useScreencast.js.map +1 -1
- 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/types.d.ts +25 -0
- package/build/types.d.ts.map +1 -1
- package/build/types.js +10 -1
- package/build/types.js.map +1 -1
- package/build/utils/foregroundService.d.ts +30 -0
- package/build/utils/foregroundService.d.ts.map +1 -0
- package/build/utils/foregroundService.js +41 -0
- package/build/utils/foregroundService.js.map +1 -0
- package/ios/RNFishjamClient.swift +34 -29
- package/ios/RNFishjamClientModule.swift +11 -7
- package/package.json +19 -17
- package/.eslintignore +0 -7
- package/.eslintrc +0 -6
- package/.prettierrc +0 -9
- package/.watchmanconfig +0 -1
- package/android/.editorconfig +0 -9
- package/android/src/main/AndroidManifest.xml +0 -2
- package/android/src/main/java/org/membraneframework/reactnative/AudioDeviceKind.kt +0 -34
- package/android/src/main/java/org/membraneframework/reactnative/AudioSwitchManager.kt +0 -61
- package/android/src/main/java/org/membraneframework/reactnative/EmitableEvents.kt +0 -14
- package/android/src/main/java/org/membraneframework/reactnative/Errors.kt +0 -31
- package/android/src/main/java/org/membraneframework/reactnative/RNFishjamClient.kt +0 -866
- package/android/src/main/java/org/membraneframework/reactnative/RNFishjamClientModule.kt +0 -294
- package/android/src/main/java/org/membraneframework/reactnative/Utils.kt +0 -11
- package/android/src/main/java/org/membraneframework/reactnative/VideoPreviewView.kt +0 -40
- package/android/src/main/java/org/membraneframework/reactnative/VideoPreviewViewModule.kt +0 -17
- package/android/src/main/java/org/membraneframework/reactnative/VideoRendererView.kt +0 -58
- package/android/src/main/java/org/membraneframework/reactnative/VideoRendererViewModule.kt +0 -25
- package/android/src/main/java/org/membraneframework/reactnative/VideoView.kt +0 -77
- package/babel.config.js +0 -2
- package/build/common/eventEmitter.d.ts.map +0 -1
- package/build/common/eventEmitter.js.map +0 -1
- package/expo-module.config.json +0 -17
- package/ios/RNFishjamClient.podspec +0 -30
- package/ios/swift-format-config.json +0 -56
- package/plugin/broadcastExtensionFiles/Info.plist +0 -27
- package/plugin/broadcastExtensionFiles/MembraneBroadcastSampleHandler.swift +0 -50
- package/plugin/broadcastExtensionFiles/MembraneScreenBroadcastExtension.entitlements +0 -10
- package/plugin/src/withMembrane.ts +0 -310
- package/plugin/tsconfig.json +0 -9
- package/scripts/lint.sh +0 -18
- package/scripts/lint_check.sh +0 -14
- package/src/RNFishjamClientModule.ts +0 -73
- package/src/__tests__/index.test.tsx +0 -199
- package/src/common/client.ts +0 -33
- package/src/common/eventEmitter.ts +0 -21
- package/src/common/metadata.ts +0 -12
- package/src/common/webRTC.ts +0 -31
- package/src/components/VideoPreviewView.tsx +0 -33
- package/src/components/VideoRendererView.tsx +0 -31
- package/src/hooks/useAudioSettings.ts +0 -115
- package/src/hooks/useBandwidthEstimation.ts +0 -24
- package/src/hooks/useCamera.ts +0 -270
- package/src/hooks/useMicrophone.ts +0 -38
- package/src/hooks/useParticipants.ts +0 -118
- package/src/hooks/useReconnection.ts +0 -41
- package/src/hooks/useScreencast.ts +0 -146
- package/src/index.tsx +0 -63
- package/src/protos/fishjam/peer_notifications.ts +0 -299
- package/src/stats/types.ts +0 -56
- package/src/stats/useRTCStatistics.ts +0 -97
- package/src/types.ts +0 -49
- package/tsconfig.json +0 -9
- package/typedoc.json +0 -5
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import FishjamClient
|
|
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}}.MembraneBroadcastSampleHandler", category: "Broadcaster")
|
|
11
|
-
|
|
12
|
-
/// An example `SampleHandler` utilizing `BroadcastSampleSource` from `MembraneRTC` sending broadcast samples and necessary notification enabling device's screencast.
|
|
13
|
-
class MembraneBroadcastSampleHandler: 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
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
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>
|
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
// ios-related code was mostly copied from OneSignal expo plugin: https://github.com/OneSignal/onesignal-expo-plugin/blob/main/onesignal/withOneSignalIos.ts
|
|
2
|
-
import {
|
|
3
|
-
AndroidConfig,
|
|
4
|
-
ConfigPlugin,
|
|
5
|
-
withEntitlementsPlist,
|
|
6
|
-
withXcodeProject,
|
|
7
|
-
withInfoPlist,
|
|
8
|
-
withPodfileProperties,
|
|
9
|
-
} from '@expo/config-plugins';
|
|
10
|
-
import fs from 'promise-fs';
|
|
11
|
-
|
|
12
|
-
const SBE_TARGET_NAME = 'MembraneScreenBroadcastExtension';
|
|
13
|
-
const SBE_PODFILE_SNIPPET = `
|
|
14
|
-
target '${SBE_TARGET_NAME}' do
|
|
15
|
-
pod 'MembraneRTC/Broadcast'
|
|
16
|
-
end`;
|
|
17
|
-
const TARGETED_DEVICE_FAMILY = `"1,2"`;
|
|
18
|
-
const IPHONEOS_DEPLOYMENT_TARGET = '13.0';
|
|
19
|
-
const GROUP_IDENTIFIER_TEMPLATE_REGEX = /{{GROUP_IDENTIFIER}}/gm;
|
|
20
|
-
const BUNDLE_IDENTIFIER_TEMPLATE_REGEX = /{{BUNDLE_IDENTIFIER}}/gm;
|
|
21
|
-
const CAMERA_USAGE = 'Allow $(PRODUCT_NAME) to access your camera';
|
|
22
|
-
const MICROPHONE_USAGE = 'Allow $(PRODUCT_NAME) to access your microphone';
|
|
23
|
-
|
|
24
|
-
type MembranePluginOptions = {
|
|
25
|
-
cameraPermission?: string;
|
|
26
|
-
microphonePermission?: string;
|
|
27
|
-
iPhoneDeploymentTarget?: string;
|
|
28
|
-
setUpScreensharing?: boolean;
|
|
29
|
-
} | void;
|
|
30
|
-
|
|
31
|
-
const withAppGroupPermissions: ConfigPlugin = (config) => {
|
|
32
|
-
const APP_GROUP_KEY = 'com.apple.security.application-groups';
|
|
33
|
-
return withEntitlementsPlist(config, (newConfig) => {
|
|
34
|
-
if (!Array.isArray(newConfig.modResults[APP_GROUP_KEY])) {
|
|
35
|
-
newConfig.modResults[APP_GROUP_KEY] = [];
|
|
36
|
-
}
|
|
37
|
-
const modResultsArray = newConfig.modResults[APP_GROUP_KEY] as any[];
|
|
38
|
-
const entitlement = `group.${newConfig?.ios?.bundleIdentifier || ''}`;
|
|
39
|
-
if (modResultsArray.indexOf(entitlement) !== -1) {
|
|
40
|
-
return newConfig;
|
|
41
|
-
}
|
|
42
|
-
modResultsArray.push(entitlement);
|
|
43
|
-
|
|
44
|
-
return newConfig;
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const withMediaPermissions: ConfigPlugin<MembranePluginOptions> = (
|
|
49
|
-
config,
|
|
50
|
-
{ cameraPermission, microphonePermission } = {},
|
|
51
|
-
) => {
|
|
52
|
-
return withInfoPlist(config, (config) => {
|
|
53
|
-
config.modResults.NSCameraUsageDescription =
|
|
54
|
-
cameraPermission ||
|
|
55
|
-
config.modResults.NSCameraUsageDescription ||
|
|
56
|
-
CAMERA_USAGE;
|
|
57
|
-
|
|
58
|
-
config.modResults.NSMicrophoneUsageDescription =
|
|
59
|
-
microphonePermission ||
|
|
60
|
-
config.modResults.NSMicrophoneUsageDescription ||
|
|
61
|
-
MICROPHONE_USAGE;
|
|
62
|
-
|
|
63
|
-
if (!config.modResults.UIBackgroundModes) {
|
|
64
|
-
config.modResults.UIBackgroundModes = ['audio'];
|
|
65
|
-
} else {
|
|
66
|
-
config.modResults.UIBackgroundModes = [
|
|
67
|
-
...config.modResults.UIBackgroundModes,
|
|
68
|
-
'audio',
|
|
69
|
-
];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return config;
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const withInfoPlistConstants: ConfigPlugin = (config) => {
|
|
77
|
-
return withInfoPlist(config, (config) => {
|
|
78
|
-
const bundleIdentifier = config.ios?.bundleIdentifier || '';
|
|
79
|
-
config.modResults['AppGroupName'] = `group.${bundleIdentifier}`;
|
|
80
|
-
config.modResults['ScreencastExtensionBundleId'] =
|
|
81
|
-
`${bundleIdentifier}.${SBE_TARGET_NAME}`;
|
|
82
|
-
return config;
|
|
83
|
-
});
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
async function updateFileWithRegex(
|
|
87
|
-
iosPath: string,
|
|
88
|
-
fileName: string,
|
|
89
|
-
regex: RegExp,
|
|
90
|
-
value: string,
|
|
91
|
-
) {
|
|
92
|
-
const filePath = `${iosPath}/${SBE_TARGET_NAME}/${fileName}`;
|
|
93
|
-
let file = await fs.readFile(filePath, { encoding: 'utf-8' });
|
|
94
|
-
file = file.replace(regex, value);
|
|
95
|
-
await fs.writeFile(filePath, file);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
async function updatePodfile(iosPath: string) {
|
|
99
|
-
let matches;
|
|
100
|
-
try {
|
|
101
|
-
const podfile = await fs.readFile(`${iosPath}/Podfile`, {
|
|
102
|
-
encoding: 'utf-8',
|
|
103
|
-
});
|
|
104
|
-
matches = podfile.match(SBE_PODFILE_SNIPPET);
|
|
105
|
-
} catch (e) {
|
|
106
|
-
console.error('Error reading from Podfile: ', e);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (matches) {
|
|
110
|
-
console.log(
|
|
111
|
-
`${SBE_TARGET_NAME} target already added to Podfile. Skipping...`,
|
|
112
|
-
);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
try {
|
|
116
|
-
fs.appendFile(`${iosPath}/Podfile`, SBE_PODFILE_SNIPPET);
|
|
117
|
-
} catch (e) {
|
|
118
|
-
console.error('Error writing to Podfile: ', e);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const withMembraneSBE: ConfigPlugin<MembranePluginOptions> = (
|
|
123
|
-
config,
|
|
124
|
-
membraneProps,
|
|
125
|
-
) => {
|
|
126
|
-
return withXcodeProject(config, async (props) => {
|
|
127
|
-
const appName = props.modRequest.projectName || '';
|
|
128
|
-
const iosPath = props.modRequest.platformProjectRoot;
|
|
129
|
-
const bundleIdentifier = props.ios?.bundleIdentifier;
|
|
130
|
-
const extensionSourceDir =
|
|
131
|
-
'node_modules/@fishjam-cloud/react-native-client/plugin/broadcastExtensionFiles/';
|
|
132
|
-
const xcodeProject = props.modResults;
|
|
133
|
-
|
|
134
|
-
await updatePodfile(iosPath);
|
|
135
|
-
|
|
136
|
-
const projPath = `${iosPath}/${appName}.xcodeproj/project.pbxproj`;
|
|
137
|
-
const extFiles = [
|
|
138
|
-
'MembraneBroadcastSampleHandler.swift',
|
|
139
|
-
`${SBE_TARGET_NAME}.entitlements`,
|
|
140
|
-
`Info.plist`,
|
|
141
|
-
];
|
|
142
|
-
|
|
143
|
-
await xcodeProject.parse(async function (err: Error) {
|
|
144
|
-
if (err) {
|
|
145
|
-
console.error(`Error parsing iOS project: ${JSON.stringify(err)}`);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (xcodeProject.pbxTargetByName(`"${SBE_TARGET_NAME}"`)) {
|
|
150
|
-
console.log(
|
|
151
|
-
`${SBE_TARGET_NAME} already exists in project. Skipping...`,
|
|
152
|
-
);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
try {
|
|
156
|
-
// copy extension files
|
|
157
|
-
await fs.mkdir(`${iosPath}/${SBE_TARGET_NAME}`, { recursive: true });
|
|
158
|
-
for (let i = 0; i < extFiles.length; i++) {
|
|
159
|
-
const extFile = extFiles[i];
|
|
160
|
-
const targetFile = `${iosPath}/${SBE_TARGET_NAME}/${extFile}`;
|
|
161
|
-
await fs.copyFile(`${extensionSourceDir}${extFile}`, targetFile);
|
|
162
|
-
}
|
|
163
|
-
} catch (e) {
|
|
164
|
-
console.error('Error copying extension files: ', e);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// update extension files
|
|
168
|
-
await updateFileWithRegex(
|
|
169
|
-
iosPath,
|
|
170
|
-
`${SBE_TARGET_NAME}.entitlements`,
|
|
171
|
-
GROUP_IDENTIFIER_TEMPLATE_REGEX,
|
|
172
|
-
`group.${bundleIdentifier}`,
|
|
173
|
-
);
|
|
174
|
-
await updateFileWithRegex(
|
|
175
|
-
iosPath,
|
|
176
|
-
'MembraneBroadcastSampleHandler.swift',
|
|
177
|
-
GROUP_IDENTIFIER_TEMPLATE_REGEX,
|
|
178
|
-
`group.${bundleIdentifier}`,
|
|
179
|
-
);
|
|
180
|
-
await updateFileWithRegex(
|
|
181
|
-
iosPath,
|
|
182
|
-
'MembraneBroadcastSampleHandler.swift',
|
|
183
|
-
BUNDLE_IDENTIFIER_TEMPLATE_REGEX,
|
|
184
|
-
bundleIdentifier || '',
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
// Create new PBXGroup for the extension
|
|
188
|
-
const extGroup = xcodeProject.addPbxGroup(
|
|
189
|
-
extFiles,
|
|
190
|
-
SBE_TARGET_NAME,
|
|
191
|
-
SBE_TARGET_NAME,
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
// Add the new PBXGroup to the top level group. This makes the
|
|
195
|
-
// files / folder appear in the file explorer in Xcode.
|
|
196
|
-
const groups = xcodeProject.hash.project.objects['PBXGroup'];
|
|
197
|
-
Object.keys(groups).forEach(function (key) {
|
|
198
|
-
if (groups[key].name === undefined) {
|
|
199
|
-
xcodeProject.addToPbxGroup(extGroup.uuid, key);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
// WORK AROUND for codeProject.addTarget BUG
|
|
204
|
-
// Xcode projects don't contain these if there is only one target
|
|
205
|
-
// An upstream fix should be made to the code referenced in this link:
|
|
206
|
-
// - https://github.com/apache/cordova-node-xcode/blob/8b98cabc5978359db88dc9ff2d4c015cba40f150/lib/pbxProject.js#L860
|
|
207
|
-
const projObjects = xcodeProject.hash.project.objects;
|
|
208
|
-
projObjects['PBXTargetDependency'] =
|
|
209
|
-
projObjects['PBXTargetDependency'] || {};
|
|
210
|
-
projObjects['PBXContainerItemProxy'] =
|
|
211
|
-
projObjects['PBXTargetDependency'] || {};
|
|
212
|
-
|
|
213
|
-
// Add the SBE target
|
|
214
|
-
// This adds PBXTargetDependency and PBXContainerItemProxy for you
|
|
215
|
-
const sbeTarget = xcodeProject.addTarget(
|
|
216
|
-
SBE_TARGET_NAME,
|
|
217
|
-
'app_extension',
|
|
218
|
-
SBE_TARGET_NAME,
|
|
219
|
-
`${bundleIdentifier}.${SBE_TARGET_NAME}`,
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
// Add build phases to the new target
|
|
223
|
-
xcodeProject.addBuildPhase(
|
|
224
|
-
['MembraneBroadcastSampleHandler.swift'],
|
|
225
|
-
'PBXSourcesBuildPhase',
|
|
226
|
-
'Sources',
|
|
227
|
-
sbeTarget.uuid,
|
|
228
|
-
);
|
|
229
|
-
xcodeProject.addBuildPhase(
|
|
230
|
-
[],
|
|
231
|
-
'PBXResourcesBuildPhase',
|
|
232
|
-
'Resources',
|
|
233
|
-
sbeTarget.uuid,
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
xcodeProject.addBuildPhase(
|
|
237
|
-
[],
|
|
238
|
-
'PBXFrameworksBuildPhase',
|
|
239
|
-
'Frameworks',
|
|
240
|
-
sbeTarget.uuid,
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
xcodeProject.addFramework('ReplayKit.framework', {
|
|
244
|
-
target: sbeTarget.uuid,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
// Edit the Deployment info of the new Target, only IphoneOS and Targeted Device Family
|
|
248
|
-
// However, can be more
|
|
249
|
-
const configurations = xcodeProject.pbxXCBuildConfigurationSection();
|
|
250
|
-
for (const key in configurations) {
|
|
251
|
-
if (
|
|
252
|
-
typeof configurations[key].buildSettings !== 'undefined' &&
|
|
253
|
-
configurations[key].buildSettings.PRODUCT_NAME ===
|
|
254
|
-
`"${SBE_TARGET_NAME}"`
|
|
255
|
-
) {
|
|
256
|
-
const buildSettingsObj = configurations[key].buildSettings;
|
|
257
|
-
buildSettingsObj.IPHONEOS_DEPLOYMENT_TARGET =
|
|
258
|
-
membraneProps?.iPhoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
259
|
-
buildSettingsObj.TARGETED_DEVICE_FAMILY = TARGETED_DEVICE_FAMILY;
|
|
260
|
-
buildSettingsObj.CODE_SIGN_ENTITLEMENTS = `${SBE_TARGET_NAME}/${SBE_TARGET_NAME}.entitlements`;
|
|
261
|
-
buildSettingsObj.CODE_SIGN_STYLE = 'Automatic';
|
|
262
|
-
buildSettingsObj.INFOPLIST_FILE = `${SBE_TARGET_NAME}/Info.plist`;
|
|
263
|
-
buildSettingsObj.SWIFT_VERSION = '5.0';
|
|
264
|
-
buildSettingsObj.MARKETING_VERSION = '1.0.0';
|
|
265
|
-
buildSettingsObj.CURRENT_PROJECT_VERSION = '1';
|
|
266
|
-
buildSettingsObj.ENABLE_BITCODE = 'NO';
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
await fs.writeFile(projPath, xcodeProject.writeSync());
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
return props;
|
|
274
|
-
});
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
const withMembraneIOS: ConfigPlugin<MembranePluginOptions> = (
|
|
278
|
-
config,
|
|
279
|
-
props,
|
|
280
|
-
) => {
|
|
281
|
-
withMediaPermissions(config, props);
|
|
282
|
-
if (props?.setUpScreensharing) {
|
|
283
|
-
withAppGroupPermissions(config);
|
|
284
|
-
withInfoPlistConstants(config);
|
|
285
|
-
withMembraneSBE(config, props);
|
|
286
|
-
}
|
|
287
|
-
withPodfileProperties(config, (config) => {
|
|
288
|
-
config.modResults['ios.deploymentTarget'] =
|
|
289
|
-
props?.iPhoneDeploymentTarget ?? IPHONEOS_DEPLOYMENT_TARGET;
|
|
290
|
-
return config;
|
|
291
|
-
});
|
|
292
|
-
return config;
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
const withMembraneAndroid: ConfigPlugin = (config) => {
|
|
296
|
-
config = AndroidConfig.Permissions.withPermissions(config, [
|
|
297
|
-
'android.permission.CAMERA',
|
|
298
|
-
'android.permission.RECORD_AUDIO',
|
|
299
|
-
'android.permission.MODIFY_AUDIO_SETTINGS',
|
|
300
|
-
]);
|
|
301
|
-
return config;
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
const withMembrane: ConfigPlugin<MembranePluginOptions> = (config, props) => {
|
|
305
|
-
withMembraneIOS(config, props);
|
|
306
|
-
withMembraneAndroid(config);
|
|
307
|
-
return config;
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
export default withMembrane;
|
package/plugin/tsconfig.json
DELETED
package/scripts/lint.sh
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
echo "Running eslint for react-native javascript files \n"
|
|
5
|
-
eslint . --ext .ts,.tsx --fix --max-warnings 0
|
|
6
|
-
|
|
7
|
-
echo "Running prettier for react-native javascript files \n"
|
|
8
|
-
prettier --write . --ignore-path ./.eslintignore
|
|
9
|
-
|
|
10
|
-
echo "Running ktlint for react-native android files \n"
|
|
11
|
-
cd android
|
|
12
|
-
ktlint -F **/*.kt
|
|
13
|
-
cd ..
|
|
14
|
-
|
|
15
|
-
echo "Running swift-format for react-native ios files \n"
|
|
16
|
-
cd ios
|
|
17
|
-
swift-format format -i -r ./*.swift --configuration swift-format-config.json
|
|
18
|
-
cd ..
|
package/scripts/lint_check.sh
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
echo "Running eslint:check for react-native javascript files \n"
|
|
2
|
-
eslint . --ext .ts,.tsx --max-warnings 0
|
|
3
|
-
|
|
4
|
-
echo "Running prettier:check for react-native javascript files \n"
|
|
5
|
-
prettier --check . --ignore-path ./.eslintignore
|
|
6
|
-
|
|
7
|
-
echo "Running ktlint:check for react-native android files \n"
|
|
8
|
-
cd android
|
|
9
|
-
ktlint **/*.kt
|
|
10
|
-
cd ..
|
|
11
|
-
|
|
12
|
-
echo "Running swift-format:check for react-native ios files \n"
|
|
13
|
-
cd ios
|
|
14
|
-
swift-format lint -r -s ./*.swift --configuration swift-format-config.json
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { requireNativeModule } from 'expo-modules-core';
|
|
2
|
-
import { NativeModule } from 'react-native';
|
|
3
|
-
|
|
4
|
-
import type { RTCStats } from './stats/types';
|
|
5
|
-
import type { SimulcastConfig } from './types';
|
|
6
|
-
import type { CameraConfigInternal, CaptureDevice } from './hooks/useCamera';
|
|
7
|
-
import type { Participant } from './hooks/useParticipants';
|
|
8
|
-
import type { ScreencastOptionsInternal } from './hooks/useScreencast';
|
|
9
|
-
import type { ConnectionConfig } from './common/client';
|
|
10
|
-
|
|
11
|
-
type Metadata = { [key: string]: any };
|
|
12
|
-
|
|
13
|
-
type RNFishjamClient = {
|
|
14
|
-
connect: (
|
|
15
|
-
url: string,
|
|
16
|
-
peerToken: string,
|
|
17
|
-
peerMetadata: Metadata,
|
|
18
|
-
config: ConnectionConfig,
|
|
19
|
-
) => Promise<void>;
|
|
20
|
-
leaveRoom: () => Promise<void>;
|
|
21
|
-
startCamera: (config: CameraConfigInternal) => Promise<void>;
|
|
22
|
-
isMicrophoneOn: boolean;
|
|
23
|
-
toggleMicrophone: () => Promise<boolean>;
|
|
24
|
-
isCameraOn: boolean;
|
|
25
|
-
toggleCamera: () => Promise<boolean>;
|
|
26
|
-
flipCamera: () => Promise<void>;
|
|
27
|
-
switchCamera: (captureDeviceId: string) => Promise<void>;
|
|
28
|
-
getCaptureDevices: () => Promise<CaptureDevice[]>;
|
|
29
|
-
handleScreencastPermission: () => Promise<'granted' | 'denied'>;
|
|
30
|
-
toggleScreencast: (
|
|
31
|
-
screencastOptions: Partial<ScreencastOptionsInternal>,
|
|
32
|
-
) => Promise<void>;
|
|
33
|
-
isScreencastOn: boolean;
|
|
34
|
-
getPeers: <PeerMetadataType extends Metadata>() => Promise<
|
|
35
|
-
Participant<PeerMetadataType>[]
|
|
36
|
-
>;
|
|
37
|
-
updatePeerMetadata: <MetadataType extends Metadata>(
|
|
38
|
-
metadata: MetadataType,
|
|
39
|
-
) => Promise<void>;
|
|
40
|
-
updateVideoTrackMetadata: <MetadataType extends Metadata>(
|
|
41
|
-
metadata: MetadataType,
|
|
42
|
-
) => Promise<void>;
|
|
43
|
-
updateAudioTrackMetadata: <MetadataType extends Metadata>(
|
|
44
|
-
metadata: MetadataType,
|
|
45
|
-
) => Promise<void>;
|
|
46
|
-
updateScreencastTrackMetadata: <MetadataType extends Metadata>(
|
|
47
|
-
metadata: MetadataType,
|
|
48
|
-
) => Promise<void>;
|
|
49
|
-
setOutputAudioDevice: (audioDevice: string) => Promise<void>;
|
|
50
|
-
startAudioSwitcher: () => Promise<void>;
|
|
51
|
-
stopAudioSwitcher: () => Promise<void>;
|
|
52
|
-
selectAudioSessionMode: (sessionMode: string) => Promise<void>;
|
|
53
|
-
showAudioRoutePicker: () => Promise<void>;
|
|
54
|
-
toggleScreencastTrackEncoding: (encoding: string) => Promise<SimulcastConfig>;
|
|
55
|
-
setScreencastTrackBandwidth: (bandwidth: number) => Promise<void>;
|
|
56
|
-
setScreencastTrackEncodingBandwidth: (
|
|
57
|
-
encoding: string,
|
|
58
|
-
bandwidth: number,
|
|
59
|
-
) => Promise<void>;
|
|
60
|
-
setTargetTrackEncoding: (trackId: string, encoding: string) => Promise<void>;
|
|
61
|
-
toggleVideoTrackEncoding: (encoding: string) => Promise<SimulcastConfig>;
|
|
62
|
-
setVideoTrackEncodingBandwidth: (
|
|
63
|
-
encoding: string,
|
|
64
|
-
bandwidth: number,
|
|
65
|
-
) => Promise<void>;
|
|
66
|
-
setVideoTrackBandwidth: (bandwidth: number) => Promise<void>;
|
|
67
|
-
changeWebRTCLoggingSeverity: (severity: string) => Promise<void>;
|
|
68
|
-
getStatistics: () => Promise<RTCStats>;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const nativeModule = requireNativeModule('RNFishjamClient');
|
|
72
|
-
|
|
73
|
-
export default nativeModule as RNFishjamClient & NativeModule;
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { renderHook, act } from '@testing-library/react';
|
|
2
|
-
import * as membraneWebRTC from '../index';
|
|
3
|
-
import RNFishjamClientModule from '../RNFishjamClientModule';
|
|
4
|
-
|
|
5
|
-
jest.mock('expo-modules-core', () => ({
|
|
6
|
-
EventEmitter: jest.fn(),
|
|
7
|
-
requireNativeModule: jest.fn().mockReturnValue({}),
|
|
8
|
-
requireNativeViewManager: jest.fn(),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
jest.mock('react-native', () => ({
|
|
12
|
-
NativeEventEmitter: jest.fn().mockImplementation(() => ({
|
|
13
|
-
addListener: jest.fn(),
|
|
14
|
-
})),
|
|
15
|
-
}));
|
|
16
|
-
|
|
17
|
-
jest.mock('../RNFishjamClientModule', () => ({
|
|
18
|
-
getStatistics: jest.fn(),
|
|
19
|
-
addListener: jest.fn(),
|
|
20
|
-
removeEventListener: jest.fn(),
|
|
21
|
-
}));
|
|
22
|
-
|
|
23
|
-
function mockedStats(numCalled: number) {
|
|
24
|
-
return {
|
|
25
|
-
RTCOutboundTest_1: {
|
|
26
|
-
kind: 'test_out',
|
|
27
|
-
rid: 'h',
|
|
28
|
-
bytesSent: 1 + numCalled * 10,
|
|
29
|
-
targetBitrate: 2 + numCalled * 10,
|
|
30
|
-
packetsSent: 3 + numCalled * 10,
|
|
31
|
-
framesEncoded: 4 + numCalled * 10,
|
|
32
|
-
framesPerSecond: 5 + numCalled * 10,
|
|
33
|
-
frameWidth: 6 + numCalled * 10,
|
|
34
|
-
frameHeight: 7 + numCalled * 10,
|
|
35
|
-
qualityLimitationDurations: {
|
|
36
|
-
cpu: 8 + numCalled * 10,
|
|
37
|
-
bandwidth: 9 + numCalled * 10,
|
|
38
|
-
none: 10 + numCalled * 10,
|
|
39
|
-
other: 11 + numCalled * 10,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
RTCInboundTest_1: {
|
|
43
|
-
kind: 'test_in',
|
|
44
|
-
jitter: 1 + numCalled * 10,
|
|
45
|
-
packetsLost: 2 + numCalled * 10,
|
|
46
|
-
packetsReceived: 3 + numCalled * 10,
|
|
47
|
-
bytesReceived: 4 + numCalled * 10,
|
|
48
|
-
framesReceived: 5 + numCalled * 10,
|
|
49
|
-
frameWidth: 6 + numCalled * 10,
|
|
50
|
-
frameHeight: 7 + numCalled * 10,
|
|
51
|
-
framesPerSecond: 8 + numCalled * 10,
|
|
52
|
-
framesDropped: 9 + numCalled * 10,
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
test('processing statistics', async () => {
|
|
58
|
-
jest.useFakeTimers();
|
|
59
|
-
const getStatisticsMocked = RNFishjamClientModule.getStatistics as jest.Mock;
|
|
60
|
-
getStatisticsMocked.mockResolvedValueOnce(mockedStats(1));
|
|
61
|
-
|
|
62
|
-
const { result } = renderHook(() => membraneWebRTC.useRTCStatistics(1000));
|
|
63
|
-
expect(getStatisticsMocked.call.length).toBe(1);
|
|
64
|
-
|
|
65
|
-
expect(result.current.statistics).toEqual([]);
|
|
66
|
-
|
|
67
|
-
await act(async () => {
|
|
68
|
-
jest.advanceTimersByTime(1001);
|
|
69
|
-
});
|
|
70
|
-
expect(getStatisticsMocked.call.length).toBe(1);
|
|
71
|
-
|
|
72
|
-
expect(result.current.statistics).toEqual([
|
|
73
|
-
{
|
|
74
|
-
RTCOutboundTest_1: {
|
|
75
|
-
'kind': 'test_out',
|
|
76
|
-
'rid': 'h',
|
|
77
|
-
'bytesSent': 11,
|
|
78
|
-
'targetBitrate': 12,
|
|
79
|
-
'packetsSent': 13,
|
|
80
|
-
'framesEncoded': 14,
|
|
81
|
-
'framesPerSecond': 15,
|
|
82
|
-
'frameWidth': 16,
|
|
83
|
-
'frameHeight': 17,
|
|
84
|
-
'qualityLimitationDurations': {
|
|
85
|
-
cpu: 18,
|
|
86
|
-
bandwidth: 19,
|
|
87
|
-
none: 20,
|
|
88
|
-
other: 21,
|
|
89
|
-
},
|
|
90
|
-
'bytesSent/s': 0,
|
|
91
|
-
'packetsSent/s': 0,
|
|
92
|
-
'framesEncoded/s': 0,
|
|
93
|
-
},
|
|
94
|
-
RTCInboundTest_1: {
|
|
95
|
-
'kind': 'test_in',
|
|
96
|
-
'jitter': 11,
|
|
97
|
-
'packetsLost': 12,
|
|
98
|
-
'packetsReceived': 13,
|
|
99
|
-
'bytesReceived': 14,
|
|
100
|
-
'framesReceived': 15,
|
|
101
|
-
'frameWidth': 16,
|
|
102
|
-
'frameHeight': 17,
|
|
103
|
-
'framesPerSecond': 18,
|
|
104
|
-
'framesDropped': 19,
|
|
105
|
-
'packetsLost/s': 0,
|
|
106
|
-
'packetsReceived/s': 0,
|
|
107
|
-
'bytesReceived/s': 0,
|
|
108
|
-
'framesReceived/s': 0,
|
|
109
|
-
'framesDropped/s': 0,
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
]);
|
|
113
|
-
getStatisticsMocked.mockResolvedValueOnce(mockedStats(2));
|
|
114
|
-
|
|
115
|
-
await act(async () => {
|
|
116
|
-
jest.advanceTimersByTime(1001);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
expect(result.current.statistics).toEqual([
|
|
120
|
-
{
|
|
121
|
-
RTCOutboundTest_1: {
|
|
122
|
-
'kind': 'test_out',
|
|
123
|
-
'rid': 'h',
|
|
124
|
-
'bytesSent': 11,
|
|
125
|
-
'targetBitrate': 12,
|
|
126
|
-
'packetsSent': 13,
|
|
127
|
-
'framesEncoded': 14,
|
|
128
|
-
'framesPerSecond': 15,
|
|
129
|
-
'frameWidth': 16,
|
|
130
|
-
'frameHeight': 17,
|
|
131
|
-
'qualityLimitationDurations': {
|
|
132
|
-
cpu: 18,
|
|
133
|
-
bandwidth: 19,
|
|
134
|
-
none: 20,
|
|
135
|
-
other: 21,
|
|
136
|
-
},
|
|
137
|
-
'bytesSent/s': 0,
|
|
138
|
-
'packetsSent/s': 0,
|
|
139
|
-
'framesEncoded/s': 0,
|
|
140
|
-
},
|
|
141
|
-
RTCInboundTest_1: {
|
|
142
|
-
'kind': 'test_in',
|
|
143
|
-
'jitter': 11,
|
|
144
|
-
'packetsLost': 12,
|
|
145
|
-
'packetsReceived': 13,
|
|
146
|
-
'bytesReceived': 14,
|
|
147
|
-
'framesReceived': 15,
|
|
148
|
-
'frameWidth': 16,
|
|
149
|
-
'frameHeight': 17,
|
|
150
|
-
'framesPerSecond': 18,
|
|
151
|
-
'framesDropped': 19,
|
|
152
|
-
'packetsLost/s': 0,
|
|
153
|
-
'packetsReceived/s': 0,
|
|
154
|
-
'bytesReceived/s': 0,
|
|
155
|
-
'framesReceived/s': 0,
|
|
156
|
-
'framesDropped/s': 0,
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
RTCOutboundTest_1: {
|
|
161
|
-
'kind': 'test_out',
|
|
162
|
-
'rid': 'h',
|
|
163
|
-
'bytesSent': 21,
|
|
164
|
-
'targetBitrate': 22,
|
|
165
|
-
'packetsSent': 23,
|
|
166
|
-
'framesEncoded': 24,
|
|
167
|
-
'framesPerSecond': 25,
|
|
168
|
-
'frameWidth': 26,
|
|
169
|
-
'frameHeight': 27,
|
|
170
|
-
'qualityLimitationDurations': {
|
|
171
|
-
cpu: 28,
|
|
172
|
-
bandwidth: 29,
|
|
173
|
-
none: 30,
|
|
174
|
-
other: 31,
|
|
175
|
-
},
|
|
176
|
-
'bytesSent/s': 10,
|
|
177
|
-
'packetsSent/s': 10,
|
|
178
|
-
'framesEncoded/s': 10,
|
|
179
|
-
},
|
|
180
|
-
RTCInboundTest_1: {
|
|
181
|
-
'kind': 'test_in',
|
|
182
|
-
'jitter': 21,
|
|
183
|
-
'packetsLost': 22,
|
|
184
|
-
'packetsReceived': 23,
|
|
185
|
-
'bytesReceived': 24,
|
|
186
|
-
'framesReceived': 25,
|
|
187
|
-
'frameWidth': 26,
|
|
188
|
-
'frameHeight': 27,
|
|
189
|
-
'framesPerSecond': 28,
|
|
190
|
-
'framesDropped': 29,
|
|
191
|
-
'packetsLost/s': 10,
|
|
192
|
-
'packetsReceived/s': 10,
|
|
193
|
-
'bytesReceived/s': 10,
|
|
194
|
-
'framesReceived/s': 10,
|
|
195
|
-
'framesDropped/s': 10,
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
]);
|
|
199
|
-
});
|