@stream-io/video-react-native-sdk 1.30.5 → 1.31.1-beta.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/CHANGELOG.md +11 -0
- package/android/src/main/AndroidManifest.xml +8 -1
- package/android/src/main/AndroidManifestNew.xml +11 -0
- package/android/src/main/java/com/streamvideo/reactnative/StreamVideoReactNativeModule.kt +127 -5
- package/android/src/main/java/com/streamvideo/reactnative/audio/utils/WebRtcAudioUtils.kt +70 -6
- package/android/src/main/java/com/streamvideo/reactnative/callmanager/StreamInCallManagerModule.kt +6 -4
- package/android/src/main/java/com/streamvideo/reactnative/keepalive/KeepAliveNotification.kt +83 -0
- package/android/src/main/java/com/streamvideo/reactnative/keepalive/StreamCallKeepAliveHeadlessService.kt +149 -0
- package/android/src/main/java/com/streamvideo/reactnative/screenshare/ScreenAudioCapture.kt +111 -0
- package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js +3 -2
- package/dist/commonjs/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -1
- package/dist/commonjs/hooks/index.js +11 -0
- package/dist/commonjs/hooks/index.js.map +1 -1
- package/dist/commonjs/hooks/push/index.js +0 -2
- package/dist/commonjs/hooks/push/index.js.map +1 -1
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js +144 -0
- package/dist/commonjs/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +64 -97
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/commonjs/hooks/useScreenShareAudioMixing.js +126 -0
- package/dist/commonjs/hooks/useScreenShareAudioMixing.js.map +1 -0
- package/dist/commonjs/hooks/useScreenShareButton.js +57 -3
- package/dist/commonjs/hooks/useScreenShareButton.js.map +1 -1
- package/dist/commonjs/index.js +1 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/modules/ScreenShareAudioManager.js +54 -0
- package/dist/commonjs/modules/ScreenShareAudioManager.js.map +1 -0
- package/dist/commonjs/modules/call-manager/CallManager.js +26 -0
- package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
- package/dist/commonjs/providers/StreamCall/index.js +16 -6
- package/dist/commonjs/providers/StreamCall/index.js.map +1 -1
- package/dist/commonjs/utils/StreamVideoRN/index.js +35 -21
- package/dist/commonjs/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js +68 -0
- package/dist/commonjs/utils/internal/callingx/audioSessionPromise.js.map +1 -0
- package/dist/commonjs/utils/internal/callingx/callingx.js +150 -0
- package/dist/commonjs/utils/internal/callingx/callingx.js.map +1 -0
- package/dist/commonjs/utils/internal/registerSDKGlobals.js +53 -3
- package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/commonjs/utils/keepCallAliveHeadlessTask.js +48 -0
- package/dist/commonjs/utils/keepCallAliveHeadlessTask.js.map +1 -0
- package/dist/commonjs/utils/push/android.js +135 -202
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/internal/ios.js +17 -34
- package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
- package/dist/commonjs/utils/push/internal/rxSubjects.js +1 -45
- package/dist/commonjs/utils/push/internal/rxSubjects.js.map +1 -1
- package/dist/commonjs/utils/push/internal/utils.js +71 -53
- package/dist/commonjs/utils/push/internal/utils.js.map +1 -1
- package/dist/commonjs/utils/push/ios.js.map +1 -1
- package/dist/commonjs/utils/push/libs/callingx.js +75 -0
- package/dist/commonjs/utils/push/libs/callingx.js.map +1 -0
- package/dist/commonjs/utils/push/libs/index.js +8 -19
- package/dist/commonjs/utils/push/libs/index.js.map +1 -1
- package/dist/commonjs/utils/push/libs/notifee/index.js +0 -19
- package/dist/commonjs/utils/push/libs/notifee/index.js.map +1 -1
- package/dist/commonjs/utils/push/setupCallingExpEvents.js +105 -0
- package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -0
- package/dist/commonjs/utils/push/setupIosVoipPushEvents.js +7 -6
- package/dist/commonjs/utils/push/setupIosVoipPushEvents.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/commonjs/version.js.map +1 -1
- package/dist/module/components/Call/CallControls/ScreenShareToggleButton.js +3 -2
- package/dist/module/components/Call/CallControls/ScreenShareToggleButton.js.map +1 -1
- package/dist/module/hooks/index.js +1 -0
- package/dist/module/hooks/index.js.map +1 -1
- package/dist/module/hooks/push/index.js +0 -2
- package/dist/module/hooks/push/index.js.map +1 -1
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js +137 -0
- package/dist/module/hooks/push/useCallingExpWithCallingStateEffect.js.map +1 -0
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +18 -31
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +66 -99
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/module/hooks/useScreenShareAudioMixing.js +119 -0
- package/dist/module/hooks/useScreenShareAudioMixing.js.map +1 -0
- package/dist/module/hooks/useScreenShareButton.js +57 -3
- package/dist/module/hooks/useScreenShareButton.js.map +1 -1
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/modules/ScreenShareAudioManager.js +47 -0
- package/dist/module/modules/ScreenShareAudioManager.js.map +1 -0
- package/dist/module/modules/call-manager/CallManager.js +26 -0
- package/dist/module/modules/call-manager/CallManager.js.map +1 -1
- package/dist/module/providers/StreamCall/index.js +16 -6
- package/dist/module/providers/StreamCall/index.js.map +1 -1
- package/dist/module/utils/StreamVideoRN/index.js +35 -21
- package/dist/module/utils/StreamVideoRN/index.js.map +1 -1
- package/dist/module/utils/internal/callingx/audioSessionPromise.js +61 -0
- package/dist/module/utils/internal/callingx/audioSessionPromise.js.map +1 -0
- package/dist/module/utils/internal/callingx/callingx.js +140 -0
- package/dist/module/utils/internal/callingx/callingx.js.map +1 -0
- package/dist/module/utils/internal/registerSDKGlobals.js +53 -3
- package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/module/utils/keepCallAliveHeadlessTask.js +42 -0
- package/dist/module/utils/keepCallAliveHeadlessTask.js.map +1 -0
- package/dist/module/utils/push/android.js +137 -204
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/internal/ios.js +17 -34
- package/dist/module/utils/push/internal/ios.js.map +1 -1
- package/dist/module/utils/push/internal/rxSubjects.js +0 -44
- package/dist/module/utils/push/internal/rxSubjects.js.map +1 -1
- package/dist/module/utils/push/internal/utils.js +67 -50
- package/dist/module/utils/push/internal/utils.js.map +1 -1
- package/dist/module/utils/push/ios.js.map +1 -1
- package/dist/module/utils/push/libs/callingx.js +67 -0
- package/dist/module/utils/push/libs/callingx.js.map +1 -0
- package/dist/module/utils/push/libs/index.js +1 -2
- package/dist/module/utils/push/libs/index.js.map +1 -1
- package/dist/module/utils/push/libs/notifee/index.js +0 -18
- package/dist/module/utils/push/libs/notifee/index.js.map +1 -1
- package/dist/module/utils/push/setupCallingExpEvents.js +99 -0
- package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -0
- package/dist/module/utils/push/setupIosVoipPushEvents.js +7 -6
- package/dist/module/utils/push/setupIosVoipPushEvents.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/module/version.js.map +1 -1
- package/dist/typescript/components/Call/CallControls/ScreenShareToggleButton.d.ts +6 -1
- package/dist/typescript/components/Call/CallControls/ScreenShareToggleButton.d.ts.map +1 -1
- package/dist/typescript/hooks/index.d.ts +1 -0
- package/dist/typescript/hooks/index.d.ts.map +1 -1
- package/dist/typescript/hooks/push/index.d.ts.map +1 -1
- package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts +5 -0
- package/dist/typescript/hooks/push/useCallingExpWithCallingStateEffect.d.ts.map +1 -0
- package/dist/typescript/hooks/push/useIosVoipPushEventsSetupEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
- package/dist/typescript/hooks/useScreenShareAudioMixing.d.ts +14 -0
- package/dist/typescript/hooks/useScreenShareAudioMixing.d.ts.map +1 -0
- package/dist/typescript/hooks/useScreenShareButton.d.ts +39 -2
- package/dist/typescript/hooks/useScreenShareButton.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +1 -0
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/modules/ScreenShareAudioManager.d.ts +28 -0
- package/dist/typescript/modules/ScreenShareAudioManager.d.ts.map +1 -0
- package/dist/typescript/modules/call-manager/CallManager.d.ts +5 -0
- package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
- package/dist/typescript/providers/StreamCall/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/index.d.ts +22 -2
- package/dist/typescript/utils/StreamVideoRN/index.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +59 -25
- package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
- package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts +16 -0
- package/dist/typescript/utils/internal/callingx/audioSessionPromise.d.ts.map +1 -0
- package/dist/typescript/utils/internal/callingx/callingx.d.ts +18 -0
- package/dist/typescript/utils/internal/callingx/callingx.d.ts.map +1 -0
- package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
- package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts +10 -0
- package/dist/typescript/utils/keepCallAliveHeadlessTask.d.ts.map +1 -0
- package/dist/typescript/utils/push/android.d.ts +1 -2
- package/dist/typescript/utils/push/android.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/rxSubjects.d.ts +0 -33
- package/dist/typescript/utils/push/internal/rxSubjects.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/utils.d.ts +14 -8
- package/dist/typescript/utils/push/internal/utils.d.ts.map +1 -1
- package/dist/typescript/utils/push/ios.d.ts +1 -2
- package/dist/typescript/utils/push/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/callingx.d.ts +9 -0
- package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -0
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts +16 -2
- package/dist/typescript/utils/push/libs/firebaseMessaging/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/index.d.ts +1 -2
- package/dist/typescript/utils/push/libs/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/notifee/index.d.ts +0 -1
- package/dist/typescript/utils/push/libs/notifee/index.d.ts.map +1 -1
- package/dist/typescript/utils/push/setupCallingExpEvents.d.ts +8 -0
- package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +1 -0
- package/dist/typescript/utils/push/setupIosVoipPushEvents.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/dist/typescript/version.d.ts.map +1 -1
- package/expo-config-plugin/dist/withAndroidManifest.js +1 -33
- package/expo-config-plugin/dist/withAndroidPermissions.js +2 -7
- package/expo-config-plugin/dist/withAppDelegate.js +19 -197
- package/expo-config-plugin/dist/withMainActivity.js +1 -1
- package/expo-config-plugin/dist/withiOSInfoPlist.js +2 -3
- package/ios/StreamInCallManager.m +2 -0
- package/ios/StreamInCallManager.swift +19 -7
- package/ios/StreamVideoReactNative.h +7 -4
- package/ios/StreamVideoReactNative.m +282 -86
- package/package.json +13 -18
- package/src/components/Call/CallControls/ScreenShareToggleButton.tsx +11 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/push/index.ts +0 -2
- package/src/hooks/push/useCallingExpWithCallingStateEffect.ts +189 -0
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +21 -34
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +94 -120
- package/src/hooks/useScreenShareAudioMixing.ts +130 -0
- package/src/hooks/useScreenShareButton.ts +87 -2
- package/src/index.ts +1 -0
- package/src/modules/ScreenShareAudioManager.ts +49 -0
- package/src/modules/call-manager/CallManager.ts +36 -0
- package/src/modules/call-manager/native-module.d.ts +7 -0
- package/src/providers/StreamCall/index.tsx +17 -6
- package/src/utils/StreamVideoRN/index.ts +42 -30
- package/src/utils/StreamVideoRN/types.ts +61 -25
- package/src/utils/internal/callingx/audioSessionPromise.ts +65 -0
- package/src/utils/internal/callingx/callingx.ts +194 -0
- package/src/utils/internal/registerSDKGlobals.ts +52 -4
- package/src/utils/keepCallAliveHeadlessTask.ts +54 -0
- package/src/utils/push/android.ts +198 -311
- package/src/utils/push/internal/ios.ts +28 -44
- package/src/utils/push/internal/rxSubjects.ts +0 -61
- package/src/utils/push/internal/utils.ts +108 -64
- package/src/utils/push/ios.ts +1 -6
- package/src/utils/push/libs/callingx.ts +89 -0
- package/src/utils/push/libs/index.ts +1 -2
- package/src/utils/push/libs/notifee/index.ts +0 -27
- package/src/utils/push/setupCallingExpEvents.ts +135 -0
- package/src/utils/push/setupIosVoipPushEvents.ts +11 -7
- package/src/version.ts +1 -1
- package/android/src/main/java/com/streamvideo/reactnative/util/CallAliveServiceChecker.kt +0 -95
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -160
- package/dist/commonjs/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
- package/dist/commonjs/hooks/push/useProcessPushCallEffect.js +0 -67
- package/dist/commonjs/hooks/push/useProcessPushCallEffect.js.map +0 -1
- package/dist/commonjs/utils/push/libs/callkeep.js +0 -17
- package/dist/commonjs/utils/push/libs/callkeep.js.map +0 -1
- package/dist/commonjs/utils/push/libs/voipPushNotification.js +0 -17
- package/dist/commonjs/utils/push/libs/voipPushNotification.js.map +0 -1
- package/dist/commonjs/utils/push/setupIosCallKeepEvents.js +0 -205
- package/dist/commonjs/utils/push/setupIosCallKeepEvents.js.map +0 -1
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js +0 -153
- package/dist/module/hooks/push/useIosCallkeepWithCallingStateEffect.js.map +0 -1
- package/dist/module/hooks/push/useProcessPushCallEffect.js +0 -60
- package/dist/module/hooks/push/useProcessPushCallEffect.js.map +0 -1
- package/dist/module/utils/push/libs/callkeep.js +0 -11
- package/dist/module/utils/push/libs/callkeep.js.map +0 -1
- package/dist/module/utils/push/libs/voipPushNotification.js +0 -11
- package/dist/module/utils/push/libs/voipPushNotification.js.map +0 -1
- package/dist/module/utils/push/setupIosCallKeepEvents.js +0 -199
- package/dist/module/utils/push/setupIosCallKeepEvents.js.map +0 -1
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts +0 -5
- package/dist/typescript/hooks/push/useIosCallkeepWithCallingStateEffect.d.ts.map +0 -1
- package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts +0 -8
- package/dist/typescript/hooks/push/useProcessPushCallEffect.d.ts.map +0 -1
- package/dist/typescript/utils/push/libs/callkeep.d.ts +0 -3
- package/dist/typescript/utils/push/libs/callkeep.d.ts.map +0 -1
- package/dist/typescript/utils/push/libs/voipPushNotification.d.ts +0 -3
- package/dist/typescript/utils/push/libs/voipPushNotification.d.ts.map +0 -1
- package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts +0 -6
- package/dist/typescript/utils/push/setupIosCallKeepEvents.d.ts.map +0 -1
- package/src/hooks/push/useIosCallkeepWithCallingStateEffect.ts +0 -235
- package/src/hooks/push/useProcessPushCallEffect.ts +0 -108
- package/src/utils/push/libs/callkeep.ts +0 -16
- package/src/utils/push/libs/voipPushNotification.ts +0 -17
- package/src/utils/push/setupIosCallKeepEvents.ts +0 -252
|
@@ -1,93 +1,58 @@
|
|
|
1
1
|
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
3
|
import { StreamVideoRN } from '../utils';
|
|
4
|
-
import { AppState, NativeModules, Platform } from 'react-native';
|
|
4
|
+
import { AppState, NativeModules, PermissionsAndroid, Platform } from 'react-native';
|
|
5
5
|
import { CallingState, videoLoggerSystem } from '@stream-io/video-client';
|
|
6
|
-
import {
|
|
6
|
+
import { keepCallAliveCallRef } from '../utils/keepCallAliveHeadlessTask';
|
|
7
|
+
import { getNotifeeLibNoThrowForKeepCallAlive } from '../utils/push/libs/notifee';
|
|
8
|
+
import { getCallingxLibIfAvailable } from '../utils/push/libs';
|
|
7
9
|
const notifeeLib = getNotifeeLibNoThrowForKeepCallAlive();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const logger = videoLoggerSystem.getLogger('setForegroundService method');
|
|
16
|
-
logger.info('KeepCallAlive is not configured. Skipping foreground service setup.');
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
notifeeLib.default.registerForegroundService(() => {
|
|
20
|
-
const task = new Promise(resolve => {
|
|
21
|
-
const logger = videoLoggerSystem.getLogger('setForegroundService method');
|
|
22
|
-
logger.info('Foreground service running for call in progress');
|
|
23
|
-
// any task to run from SDK in the foreground service must be added
|
|
24
|
-
resolve(true);
|
|
25
|
-
});
|
|
26
|
-
const videoConfig = StreamVideoRN.getConfig();
|
|
27
|
-
const foregroundServiceConfig = videoConfig.foregroundService;
|
|
28
|
-
const {
|
|
29
|
-
taskToRun
|
|
30
|
-
} = foregroundServiceConfig.android;
|
|
31
|
-
const call = callToPassToForegroundService.current;
|
|
32
|
-
if (!call) {
|
|
33
|
-
const logger = videoLoggerSystem.getLogger('setForegroundService method');
|
|
34
|
-
logger.warn('No call to pass to foreground service');
|
|
35
|
-
return task.then(() => new Promise(() => {}));
|
|
36
|
-
}
|
|
37
|
-
callToPassToForegroundService.current = undefined;
|
|
38
|
-
return task.then(() => taskToRun(call));
|
|
39
|
-
});
|
|
40
|
-
});
|
|
10
|
+
async function stopForegroundServiceNoThrow() {
|
|
11
|
+
const logger = videoLoggerSystem.getLogger('stopForegroundServiceNoThrow');
|
|
12
|
+
try {
|
|
13
|
+
await NativeModules.StreamVideoReactNative.stopKeepCallAliveService();
|
|
14
|
+
} catch (e) {
|
|
15
|
+
logger.warn('Failed to stop keep-call-alive foreground service', e);
|
|
16
|
+
}
|
|
41
17
|
}
|
|
42
18
|
async function startForegroundService(call_cid) {
|
|
43
|
-
const
|
|
19
|
+
const logger = videoLoggerSystem.getLogger('startForegroundService');
|
|
20
|
+
const isCallAliveConfigured = await (async () => {
|
|
21
|
+
try {
|
|
22
|
+
return await NativeModules.StreamVideoReactNative.isCallAliveConfigured();
|
|
23
|
+
} catch (e) {
|
|
24
|
+
logger.warn('Failed to check whether KeepCallAlive is configured', e);
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
})();
|
|
44
28
|
if (!isCallAliveConfigured) {
|
|
45
|
-
const logger = videoLoggerSystem.getLogger('startForegroundService');
|
|
46
29
|
logger.info('KeepCallAlive is not configured. Skipping foreground service setup.');
|
|
47
30
|
return;
|
|
48
31
|
}
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (settings.authorizationStatus !== notifeeLib.AuthorizationStatus.AUTHORIZED) {
|
|
53
|
-
const logger = videoLoggerSystem.getLogger('startForegroundService');
|
|
32
|
+
// Check for notification permission (Android 13+) before starting the service.
|
|
33
|
+
const hasPostNotificationsPermission = Number(Platform.Version) < 33 || (await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS));
|
|
34
|
+
if (!hasPostNotificationsPermission) {
|
|
54
35
|
logger.info('Notification permission not granted, can not start foreground service to keep the call alive');
|
|
55
36
|
return;
|
|
56
37
|
}
|
|
57
38
|
const videoConfig = StreamVideoRN.getConfig();
|
|
58
39
|
const foregroundServiceConfig = videoConfig.foregroundService;
|
|
59
40
|
const notificationTexts = foregroundServiceConfig.android.notificationTexts;
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
41
|
+
const channel = foregroundServiceConfig.android.channel;
|
|
42
|
+
const smallIconName = videoConfig.push?.android.smallIcon;
|
|
43
|
+
|
|
63
44
|
// NOTE: we use requestAnimationFrame to ensure that the foreground service is started after all the current UI operations are done
|
|
64
45
|
// this is a workaround for the crash - android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground()
|
|
65
46
|
// this crash was reproducible only in some android devices
|
|
66
|
-
requestAnimationFrame(() => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
channelId,
|
|
73
|
-
smallIcon: videoConfig.push?.android.smallIcon,
|
|
74
|
-
foregroundServiceTypes,
|
|
75
|
-
asForegroundService: true,
|
|
76
|
-
ongoing: true,
|
|
77
|
-
// user cannot dismiss the notification
|
|
78
|
-
colorized: true,
|
|
79
|
-
pressAction: {
|
|
80
|
-
id: 'default',
|
|
81
|
-
launchActivity: 'default' // open the app when the notification is pressed
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
});
|
|
47
|
+
requestAnimationFrame(async () => {
|
|
48
|
+
try {
|
|
49
|
+
await NativeModules.StreamVideoReactNative.startKeepCallAliveService(call_cid, channel.id, channel.name, notificationTexts.title, notificationTexts.body, smallIconName ?? null);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
logger.warn('Failed to start keep-call-alive foreground service', e);
|
|
52
|
+
}
|
|
85
53
|
});
|
|
86
54
|
}
|
|
87
55
|
|
|
88
|
-
// flag to check if setForegroundService has already been run once
|
|
89
|
-
let isSetForegroundServiceRan = false;
|
|
90
|
-
|
|
91
56
|
/**
|
|
92
57
|
* This hook is used to keep the call alive in the background for Android.
|
|
93
58
|
* It starts a foreground service to keep the call alive as soon as the call is joined
|
|
@@ -97,7 +62,7 @@ let isSetForegroundServiceRan = false;
|
|
|
97
62
|
export const useAndroidKeepCallAliveEffect = () => {
|
|
98
63
|
const foregroundServiceStartedRef = useRef(false);
|
|
99
64
|
const call = useCall();
|
|
100
|
-
|
|
65
|
+
keepCallAliveCallRef.current = call;
|
|
101
66
|
const activeCallCid = call?.cid;
|
|
102
67
|
const {
|
|
103
68
|
useCallCallingState
|
|
@@ -105,12 +70,16 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
105
70
|
const callingState = useCallCallingState();
|
|
106
71
|
const isOutgoingCall = callingState === CallingState.RINGING && call?.isCreatedByMe;
|
|
107
72
|
const isCallJoined = callingState === CallingState.JOINED;
|
|
73
|
+
const isRingingCall = call?.ringing;
|
|
108
74
|
const shouldStartForegroundService = !foregroundServiceStartedRef.current && (isOutgoingCall || isCallJoined);
|
|
109
75
|
useEffect(() => {
|
|
110
76
|
if (Platform.OS === 'ios' || !activeCallCid) {
|
|
111
77
|
return undefined;
|
|
112
78
|
}
|
|
113
|
-
|
|
79
|
+
const callingx = getCallingxLibIfAvailable();
|
|
80
|
+
if (callingx?.isSetup && (isRingingCall || !isRingingCall && callingx?.isOngoingCallsEnabled)) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
114
83
|
|
|
115
84
|
// start foreground service as soon as the call is joined
|
|
116
85
|
if (shouldStartForegroundService) {
|
|
@@ -118,21 +87,18 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
118
87
|
if (foregroundServiceStartedRef.current) {
|
|
119
88
|
return;
|
|
120
89
|
}
|
|
121
|
-
if
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
notifee.cancelDisplayedNotification(activeCallCid);
|
|
90
|
+
// Optional compatibility cleanup: if the app uses Notifee for ringing push,
|
|
91
|
+
// we might have an incoming call notification running as a foreground service.
|
|
92
|
+
if (notifeeLib) {
|
|
93
|
+
const notifee = notifeeLib.default;
|
|
94
|
+
const displayedNotifications = await notifee.getDisplayedNotifications();
|
|
95
|
+
const activeCallNotification = displayedNotifications.find(notification => notification.id === activeCallCid);
|
|
96
|
+
if (activeCallNotification) {
|
|
97
|
+
// this means that we have a incoming call notification shown as foreground service and we must stop it
|
|
98
|
+
notifee.stopForegroundService();
|
|
99
|
+
notifee.cancelDisplayedNotification(activeCallCid);
|
|
100
|
+
}
|
|
133
101
|
}
|
|
134
|
-
// check for notification permission and then start the foreground service
|
|
135
|
-
|
|
136
102
|
await startForegroundService(activeCallCid);
|
|
137
103
|
foregroundServiceStartedRef.current = true;
|
|
138
104
|
};
|
|
@@ -140,7 +106,6 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
140
106
|
// ensure that app is active before running the function
|
|
141
107
|
if (AppState.currentState === 'active') {
|
|
142
108
|
run();
|
|
143
|
-
return undefined;
|
|
144
109
|
}
|
|
145
110
|
const sub = AppState.addEventListener('change', nextAppState => {
|
|
146
111
|
if (nextAppState === 'active') {
|
|
@@ -155,34 +120,36 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
155
120
|
return () => {
|
|
156
121
|
// cancel any notifee displayed notification when the call has transitioned out of ringing
|
|
157
122
|
// NOTE: cancels only the non fg service notifications
|
|
158
|
-
notifeeLib
|
|
123
|
+
if (notifeeLib) {
|
|
124
|
+
notifeeLib.default.cancelDisplayedNotification(activeCallCid);
|
|
125
|
+
}
|
|
159
126
|
};
|
|
160
127
|
} else if (callingState === CallingState.IDLE || callingState === CallingState.LEFT) {
|
|
161
128
|
if (foregroundServiceStartedRef.current) {
|
|
162
|
-
|
|
129
|
+
keepCallAliveCallRef.current = undefined;
|
|
163
130
|
// stop foreground service when the call is not active
|
|
164
|
-
|
|
131
|
+
stopForegroundServiceNoThrow();
|
|
165
132
|
foregroundServiceStartedRef.current = false;
|
|
166
133
|
} else {
|
|
167
|
-
notifeeLib
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
134
|
+
if (notifeeLib) {
|
|
135
|
+
notifeeLib.default.getDisplayedNotifications().then(displayedNotifications => {
|
|
136
|
+
const activeCallNotification = displayedNotifications.find(notification => notification.id === activeCallCid);
|
|
137
|
+
if (activeCallNotification) {
|
|
138
|
+
// this means that we have a incoming call notification shown as foreground service and we must stop it
|
|
139
|
+
notifeeLib.default.stopForegroundService();
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
}
|
|
175
143
|
}
|
|
176
144
|
}
|
|
177
145
|
return undefined;
|
|
178
|
-
}, [activeCallCid, callingState, shouldStartForegroundService]);
|
|
146
|
+
}, [activeCallCid, callingState, shouldStartForegroundService, isRingingCall]);
|
|
179
147
|
useEffect(() => {
|
|
180
148
|
return () => {
|
|
181
149
|
// stop foreground service when this effect is unmounted
|
|
182
150
|
if (foregroundServiceStartedRef.current) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
notifeeLib.default.stopForegroundService();
|
|
151
|
+
keepCallAliveCallRef.current = undefined;
|
|
152
|
+
stopForegroundServiceNoThrow();
|
|
186
153
|
foregroundServiceStartedRef.current = false;
|
|
187
154
|
}
|
|
188
155
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCall","useCallStateHooks","useEffect","useRef","StreamVideoRN","AppState","NativeModules","Platform","CallingState","videoLoggerSystem","
|
|
1
|
+
{"version":3,"names":["useCall","useCallStateHooks","useEffect","useRef","StreamVideoRN","AppState","NativeModules","PermissionsAndroid","Platform","CallingState","videoLoggerSystem","keepCallAliveCallRef","getNotifeeLibNoThrowForKeepCallAlive","getCallingxLibIfAvailable","notifeeLib","stopForegroundServiceNoThrow","logger","getLogger","StreamVideoReactNative","stopKeepCallAliveService","e","warn","startForegroundService","call_cid","isCallAliveConfigured","info","hasPostNotificationsPermission","Number","Version","check","PERMISSIONS","POST_NOTIFICATIONS","videoConfig","getConfig","foregroundServiceConfig","foregroundService","notificationTexts","android","channel","smallIconName","push","smallIcon","requestAnimationFrame","startKeepCallAliveService","id","name","title","body","useAndroidKeepCallAliveEffect","foregroundServiceStartedRef","call","current","activeCallCid","cid","useCallCallingState","callingState","isOutgoingCall","RINGING","isCreatedByMe","isCallJoined","JOINED","isRingingCall","ringing","shouldStartForegroundService","OS","undefined","callingx","isSetup","isOngoingCallsEnabled","run","notifee","default","displayedNotifications","getDisplayedNotifications","activeCallNotification","find","notification","stopForegroundService","cancelDisplayedNotification","currentState","sub","addEventListener","nextAppState","remove","IDLE","LEFT","then"],"sourceRoot":"../../../src","sources":["hooks/useAndroidKeepCallAliveEffect.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { hasScreenShare, videoLoggerSystem } from '@stream-io/video-client';
|
|
3
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
4
|
+
import { screenShareAudioMixingManager } from '../modules/ScreenShareAudioManager';
|
|
5
|
+
import { NoiseCancellationWrapper } from '../providers/NoiseCancellation/lib';
|
|
6
|
+
const logger = videoLoggerSystem.getLogger('useScreenShareAudioMixing');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Tries to disable noise cancellation so screen audio passes through
|
|
10
|
+
* unfiltered. Returns true if NC was disabled (and should be re-enabled later).
|
|
11
|
+
*/
|
|
12
|
+
async function disableNoiseCancellation() {
|
|
13
|
+
try {
|
|
14
|
+
const nc = NoiseCancellationWrapper.getInstance();
|
|
15
|
+
const wasEnabled = await nc.isEnabled();
|
|
16
|
+
if (wasEnabled) {
|
|
17
|
+
await nc.disable();
|
|
18
|
+
logger.info('Noise cancellation disabled for screen share audio');
|
|
19
|
+
}
|
|
20
|
+
return wasEnabled;
|
|
21
|
+
} catch {
|
|
22
|
+
// NC module not installed or not configured — nothing to do
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Re-enables noise cancellation if it was previously disabled.
|
|
29
|
+
*/
|
|
30
|
+
async function restoreNoiseCancellation() {
|
|
31
|
+
try {
|
|
32
|
+
const nc = NoiseCancellationWrapper.getInstance();
|
|
33
|
+
await nc.enable();
|
|
34
|
+
logger.info('Noise cancellation re-enabled after screen share audio');
|
|
35
|
+
} catch {
|
|
36
|
+
// NC module not installed — nothing to do
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Hook that manages the lifecycle of screen share audio mixing.
|
|
42
|
+
*
|
|
43
|
+
* When screen share is active and audio mixing is enabled
|
|
44
|
+
* (via `call.screenShare.enableScreenShareAudio()`), this hook
|
|
45
|
+
* calls the native module to mix captured screen/app audio
|
|
46
|
+
* into the microphone audio track.
|
|
47
|
+
*
|
|
48
|
+
* Noise cancellation is temporarily disabled while screen audio mixing
|
|
49
|
+
* is active so that all captured sounds (music, game audio, etc.)
|
|
50
|
+
* pass through without being filtered.
|
|
51
|
+
*/
|
|
52
|
+
export const useScreenShareAudioMixing = () => {
|
|
53
|
+
const call = useCall();
|
|
54
|
+
const {
|
|
55
|
+
useLocalParticipant
|
|
56
|
+
} = useCallStateHooks();
|
|
57
|
+
const localParticipant = useLocalParticipant();
|
|
58
|
+
const isScreenSharing = localParticipant != null && hasScreenShare(localParticipant);
|
|
59
|
+
const [audioEnabled, setAudioEnabled] = useState(() => call?.screenShare.state.audioEnabled ?? false);
|
|
60
|
+
const isMixingActiveRef = useRef(false);
|
|
61
|
+
const ncWasEnabledRef = useRef(false);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!call) return;
|
|
64
|
+
const sub = call.screenShare.state.audioEnabled$.subscribe(setAudioEnabled);
|
|
65
|
+
return () => sub.unsubscribe();
|
|
66
|
+
}, [call]);
|
|
67
|
+
const startMixing = useCallback(async () => {
|
|
68
|
+
if (isMixingActiveRef.current) return;
|
|
69
|
+
try {
|
|
70
|
+
// Disable NC before starting mixing so screen audio is not filtered
|
|
71
|
+
ncWasEnabledRef.current = await disableNoiseCancellation();
|
|
72
|
+
logger.info('Starting screen share audio mixing');
|
|
73
|
+
await screenShareAudioMixingManager.startScreenShareAudioMixing();
|
|
74
|
+
isMixingActiveRef.current = true;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
logger.warn('Failed to start screen share audio mixing', error);
|
|
77
|
+
if (ncWasEnabledRef.current) {
|
|
78
|
+
restoreNoiseCancellation().catch(() => {});
|
|
79
|
+
ncWasEnabledRef.current = false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}, []);
|
|
83
|
+
const stopMixing = useCallback(async () => {
|
|
84
|
+
if (!isMixingActiveRef.current) return;
|
|
85
|
+
try {
|
|
86
|
+
logger.info('Stopping screen share audio mixing');
|
|
87
|
+
await screenShareAudioMixingManager.stopScreenShareAudioMixing();
|
|
88
|
+
isMixingActiveRef.current = false;
|
|
89
|
+
if (ncWasEnabledRef.current) {
|
|
90
|
+
await restoreNoiseCancellation();
|
|
91
|
+
ncWasEnabledRef.current = false;
|
|
92
|
+
}
|
|
93
|
+
} catch (error) {
|
|
94
|
+
logger.warn('Failed to stop screen share audio mixing', error);
|
|
95
|
+
}
|
|
96
|
+
}, []);
|
|
97
|
+
|
|
98
|
+
// Start/stop audio mixing based on screen share status and audio preference
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (isScreenSharing && audioEnabled) {
|
|
101
|
+
startMixing();
|
|
102
|
+
} else {
|
|
103
|
+
stopMixing();
|
|
104
|
+
}
|
|
105
|
+
}, [isScreenSharing, audioEnabled, startMixing, stopMixing]);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
return () => {
|
|
108
|
+
if (isMixingActiveRef.current) {
|
|
109
|
+
screenShareAudioMixingManager.stopScreenShareAudioMixing().catch(() => {});
|
|
110
|
+
isMixingActiveRef.current = false;
|
|
111
|
+
if (ncWasEnabledRef.current) {
|
|
112
|
+
restoreNoiseCancellation().catch(() => {});
|
|
113
|
+
ncWasEnabledRef.current = false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}, []);
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=useScreenShareAudioMixing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useRef","useState","hasScreenShare","videoLoggerSystem","useCall","useCallStateHooks","screenShareAudioMixingManager","NoiseCancellationWrapper","logger","getLogger","disableNoiseCancellation","nc","getInstance","wasEnabled","isEnabled","disable","info","restoreNoiseCancellation","enable","useScreenShareAudioMixing","call","useLocalParticipant","localParticipant","isScreenSharing","audioEnabled","setAudioEnabled","screenShare","state","isMixingActiveRef","ncWasEnabledRef","sub","audioEnabled$","subscribe","unsubscribe","startMixing","current","startScreenShareAudioMixing","error","warn","catch","stopMixing","stopScreenShareAudioMixing"],"sourceRoot":"../../../src","sources":["hooks/useScreenShareAudioMixing.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -4,10 +4,26 @@ import { useEffect, useRef } from 'react';
|
|
|
4
4
|
import { findNodeHandle, NativeModules, Platform } from 'react-native';
|
|
5
5
|
import { usePrevious } from '../utils/hooks';
|
|
6
6
|
import { useIsIosScreenshareBroadcastStarted } from './useIsIosScreenshareBroadcastStarted';
|
|
7
|
+
import { screenShareAudioMixingManager } from '../modules/ScreenShareAudioManager';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The type of screen sharing to use on iOS.
|
|
11
|
+
*
|
|
12
|
+
* - `'broadcast'` — Uses a Broadcast Upload Extension (RPSystemBroadcastPickerView).
|
|
13
|
+
* Captures the entire device screen, works across all apps. Requires an extension target.
|
|
14
|
+
* - `'inApp'` — Uses RPScreenRecorder.startCapture to capture the current app's screen.
|
|
15
|
+
* Only captures the current app. Supports `.audioApp` sample buffers for audio mixing.
|
|
16
|
+
*
|
|
17
|
+
* On Android, this option is ignored — the system screen capture dialog is always used.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Options for screen share behavior.
|
|
22
|
+
*/
|
|
7
23
|
|
|
8
24
|
// ios >= 14.0 or android - platform restrictions
|
|
9
25
|
const CanDeviceScreenShare = Platform.OS === 'ios' && Number.parseInt(Platform.Version?.split('.')[0] ?? '0', 10) >= 14 || Platform.OS === 'android';
|
|
10
|
-
export const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStartedHandler, onScreenShareStoppedHandler, onMissingScreenShareStreamPermission) => {
|
|
26
|
+
export const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShareStartedHandler, onScreenShareStoppedHandler, onMissingScreenShareStreamPermission, screenShareOptions) => {
|
|
11
27
|
const call = useCall();
|
|
12
28
|
const {
|
|
13
29
|
useLocalParticipant,
|
|
@@ -18,6 +34,8 @@ export const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShar
|
|
|
18
34
|
const ownCapabilities = useOwnCapabilities();
|
|
19
35
|
const hasScreenSharingPermissions = ownCapabilities?.includes(OwnCapability.SCREENSHARE);
|
|
20
36
|
const isScreenSharingEnabledInCall = callSettings?.screensharing.enabled;
|
|
37
|
+
const screenShareType = screenShareOptions?.type ?? 'broadcast';
|
|
38
|
+
const includeAudio = screenShareOptions?.includeAudio ?? false;
|
|
21
39
|
const onScreenShareStartedHandlerRef = useRef(onScreenShareStartedHandler);
|
|
22
40
|
onScreenShareStartedHandlerRef.current = onScreenShareStartedHandler;
|
|
23
41
|
const onScreenShareStoppedHandlerRef = useRef(onScreenShareStoppedHandler);
|
|
@@ -28,31 +46,63 @@ export const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShar
|
|
|
28
46
|
const hasPublishedScreenShare = localParticipant && hasScreenShare(localParticipant);
|
|
29
47
|
|
|
30
48
|
// listens to iOS screen share broadcast started event from the system
|
|
49
|
+
// (only relevant for broadcast mode)
|
|
31
50
|
useEffect(() => {
|
|
32
51
|
if (Platform.OS !== 'ios') {
|
|
33
52
|
return;
|
|
34
53
|
}
|
|
54
|
+
if (screenShareType !== 'broadcast') {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
35
57
|
if (iosScreenShareStartedFromSystem && !prevIosScreenShareStartedFromSystem) {
|
|
36
58
|
onScreenShareStartedHandlerRef.current?.();
|
|
59
|
+
if (includeAudio) {
|
|
60
|
+
call?.screenShare.enableScreenShareAudio();
|
|
61
|
+
}
|
|
37
62
|
call?.screenShare.enable();
|
|
38
63
|
} else if (!iosScreenShareStartedFromSystem && prevIosScreenShareStartedFromSystem) {
|
|
39
64
|
onScreenShareStoppedHandlerRef.current?.();
|
|
40
65
|
call?.screenShare.disable(true);
|
|
41
66
|
}
|
|
42
|
-
}, [call, iosScreenShareStartedFromSystem, prevIosScreenShareStartedFromSystem]);
|
|
67
|
+
}, [call, includeAudio, screenShareType, iosScreenShareStartedFromSystem, prevIosScreenShareStartedFromSystem]);
|
|
43
68
|
const onPress = async () => {
|
|
44
69
|
if (!hasScreenSharingPermissions) {
|
|
45
70
|
const logger = videoLoggerSystem.getLogger('useScreenShareButton');
|
|
46
71
|
logger.info('User does not have permissions to stream the screen share media, calling onMissingScreenShareStreamPermission handler if present');
|
|
47
72
|
onMissingScreenShareStreamPermission?.();
|
|
73
|
+
return;
|
|
48
74
|
}
|
|
49
75
|
if (!hasPublishedScreenShare) {
|
|
50
|
-
|
|
76
|
+
// Set audio mixing preference before starting screen share
|
|
77
|
+
if (includeAudio) {
|
|
78
|
+
call?.screenShare.enableScreenShareAudio();
|
|
79
|
+
} else {
|
|
80
|
+
try {
|
|
81
|
+
await call?.screenShare.disableScreenShareAudio();
|
|
82
|
+
} catch (error) {
|
|
83
|
+
const logger = videoLoggerSystem.getLogger('useScreenShareButton');
|
|
84
|
+
logger.warn('Failed to disable screen share audio', error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (Platform.OS === 'ios' && screenShareType === 'inApp') {
|
|
88
|
+
// In-app screen sharing on iOS — uses RPScreenRecorder directly
|
|
89
|
+
try {
|
|
90
|
+
await screenShareAudioMixingManager.startInAppScreenCapture(includeAudio);
|
|
91
|
+
await call?.screenShare.enable();
|
|
92
|
+
onScreenShareStartedHandler?.();
|
|
93
|
+
} catch (error) {
|
|
94
|
+
await screenShareAudioMixingManager.stopInAppScreenCapture();
|
|
95
|
+
const logger = videoLoggerSystem.getLogger('useScreenShareButton');
|
|
96
|
+
logger.warn('Failed to start in-app screen capture', error);
|
|
97
|
+
}
|
|
98
|
+
} else if (Platform.OS === 'ios') {
|
|
99
|
+
// Broadcast screen sharing on iOS — shows the system picker
|
|
51
100
|
const reactTag = findNodeHandle(screenCapturePickerViewiOSRef.current);
|
|
52
101
|
await NativeModules.ScreenCapturePickerViewManager.show(reactTag);
|
|
53
102
|
// After this the iOS screen share broadcast started/stopped event will be triggered
|
|
54
103
|
// and the useEffect listener will handle the rest
|
|
55
104
|
} else {
|
|
105
|
+
// Android screen sharing
|
|
56
106
|
try {
|
|
57
107
|
await call?.screenShare.enable();
|
|
58
108
|
onScreenShareStartedHandler?.();
|
|
@@ -64,6 +114,10 @@ export const useScreenShareButton = (screenCapturePickerViewiOSRef, onScreenShar
|
|
|
64
114
|
}
|
|
65
115
|
} else if (hasPublishedScreenShare) {
|
|
66
116
|
onScreenShareStoppedHandler?.();
|
|
117
|
+
// Stop in-app screen capture if it was active (iOS only)
|
|
118
|
+
if (Platform.OS === 'ios' && screenShareType === 'inApp') {
|
|
119
|
+
await screenShareAudioMixingManager.stopInAppScreenCapture();
|
|
120
|
+
}
|
|
67
121
|
await call?.screenShare.disable(true);
|
|
68
122
|
}
|
|
69
123
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["hasScreenShare","OwnCapability","videoLoggerSystem","useCall","useCallStateHooks","useEffect","useRef","findNodeHandle","NativeModules","Platform","usePrevious","useIsIosScreenshareBroadcastStarted","CanDeviceScreenShare","OS","Number","parseInt","Version","split","useScreenShareButton","screenCapturePickerViewiOSRef","onScreenShareStartedHandler","onScreenShareStoppedHandler","onMissingScreenShareStreamPermission","call","useLocalParticipant","useCallSettings","useOwnCapabilities","callSettings","ownCapabilities","hasScreenSharingPermissions","includes","SCREENSHARE","isScreenSharingEnabledInCall","screensharing","enabled","onScreenShareStartedHandlerRef","current","onScreenShareStoppedHandlerRef","iosScreenShareStartedFromSystem","prevIosScreenShareStartedFromSystem","localParticipant","hasPublishedScreenShare","screenShare","enable","disable","onPress","logger","getLogger","info","reactTag","ScreenCapturePickerViewManager","show","
|
|
1
|
+
{"version":3,"names":["hasScreenShare","OwnCapability","videoLoggerSystem","useCall","useCallStateHooks","useEffect","useRef","findNodeHandle","NativeModules","Platform","usePrevious","useIsIosScreenshareBroadcastStarted","screenShareAudioMixingManager","CanDeviceScreenShare","OS","Number","parseInt","Version","split","useScreenShareButton","screenCapturePickerViewiOSRef","onScreenShareStartedHandler","onScreenShareStoppedHandler","onMissingScreenShareStreamPermission","screenShareOptions","call","useLocalParticipant","useCallSettings","useOwnCapabilities","callSettings","ownCapabilities","hasScreenSharingPermissions","includes","SCREENSHARE","isScreenSharingEnabledInCall","screensharing","enabled","screenShareType","type","includeAudio","onScreenShareStartedHandlerRef","current","onScreenShareStoppedHandlerRef","iosScreenShareStartedFromSystem","prevIosScreenShareStartedFromSystem","localParticipant","hasPublishedScreenShare","screenShare","enableScreenShareAudio","enable","disable","onPress","logger","getLogger","info","disableScreenShareAudio","error","warn","startInAppScreenCapture","stopInAppScreenCapture","reactTag","ScreenCapturePickerViewManager","show","undefined"],"sourceRoot":"../../../src","sources":["hooks/useScreenShareButton.ts"],"mappings":"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","ignoreList":[]}
|
package/dist/module/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { registerGlobals } from '@stream-io/react-native-webrtc';
|
|
|
9
9
|
import Logger from '@stream-io/react-native-webrtc/src/Logger';
|
|
10
10
|
import { Platform } from 'react-native';
|
|
11
11
|
import { registerSDKGlobals } from './utils/internal/registerSDKGlobals';
|
|
12
|
+
import './utils/keepCallAliveHeadlessTask';
|
|
12
13
|
|
|
13
14
|
// We're registering globals, because our video JS client is serving SDKs that use browser based webRTC functions.
|
|
14
15
|
// This will result in creation of 2 global objects: `window` and `navigator`
|
package/dist/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["setClientDetails","registerGlobals","Logger","Platform","registerSDKGlobals","OS","enable","ROOT_PREFIX","StreamVideo","StreamCall"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,0BAA0B;AAC3D;AACA,OAAO,wBAAwB;AAC/B;AACA,OAAO,gCAAgC;AACvC;AACA,OAAO,kBAAkB;AACzB,SAASC,eAAe,QAAQ,gCAAgC;AAChE,OAAOC,MAAM,MAAM,2CAA2C;AAC9D,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,kBAAkB,QAAQ,qCAAqC;;
|
|
1
|
+
{"version":3,"names":["setClientDetails","registerGlobals","Logger","Platform","registerSDKGlobals","OS","enable","ROOT_PREFIX","StreamVideo","StreamCall"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,0BAA0B;AAC3D;AACA,OAAO,wBAAwB;AAC/B;AACA,OAAO,gCAAgC;AACvC;AACA,OAAO,kBAAkB;AACzB,SAASC,eAAe,QAAQ,gCAAgC;AAChE,OAAOC,MAAM,MAAM,2CAA2C;AAC9D,SAASC,QAAQ,QAAQ,cAAc;AACvC,SAASC,kBAAkB,QAAQ,qCAAqC;AACxE,OAAO,mCAAmC;;AAE1C;AACA;AACA;AACA,IAAID,QAAQ,CAACE,EAAE,KAAK,KAAK,EAAE;EACzBJ,eAAe,CAAC,CAAC;EACjBG,kBAAkB,CAAC,CAAC;AACtB;;AAEA;AACAF,MAAM,CAACI,MAAM,CAAC,GAAGJ,MAAM,CAACK,WAAW,eAAe,CAAC;AAEnD,cAAc,yBAAyB;AACvC,cAAc,iCAAiC;AAC/C,cAAc,cAAc;AAC5B,cAAc,YAAY;AAC1B,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,SAAS;AACvB,cAAc,gBAAgB;AAC9B,cAAc,wBAAwB;;AAEtC;AACA;AACA,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,UAAU,QAAQ,wBAAwB;AACnD,cAAc,+BAA+B;AAE7CT,gBAAgB,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { NativeModules, Platform } from 'react-native';
|
|
2
|
+
const StreamVideoReactNative = NativeModules.StreamVideoReactNative;
|
|
3
|
+
export class ScreenShareAudioManager {
|
|
4
|
+
/**
|
|
5
|
+
* Starts mixing screen share audio into the microphone audio track.
|
|
6
|
+
* On iOS, this enables audio buffer processing on the prepared mixer.
|
|
7
|
+
* On Android, this registers an audio processor that captures system media
|
|
8
|
+
* audio via AudioPlaybackCaptureConfiguration and mixes it into the mic buffer.
|
|
9
|
+
*/
|
|
10
|
+
async startScreenShareAudioMixing() {
|
|
11
|
+
return StreamVideoReactNative?.startScreenShareAudioMixing();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Stops mixing screen share audio into the microphone audio track
|
|
16
|
+
* and restores the original audio pipeline.
|
|
17
|
+
*/
|
|
18
|
+
async stopScreenShareAudioMixing() {
|
|
19
|
+
return StreamVideoReactNative?.stopScreenShareAudioMixing();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Starts in-app screen capture using RPScreenRecorder (iOS only).
|
|
24
|
+
* Unlike broadcast screen sharing, in-app capture runs in the main app process
|
|
25
|
+
* and can directly provide `.audioApp` sample buffers for mixing.
|
|
26
|
+
*
|
|
27
|
+
* @param includeAudio Whether to capture and mix app audio.
|
|
28
|
+
*/
|
|
29
|
+
async startInAppScreenCapture(includeAudio) {
|
|
30
|
+
if (Platform.OS !== 'ios') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
return StreamVideoReactNative?.startInAppScreenCapture(includeAudio);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Stops in-app screen capture (iOS only).
|
|
38
|
+
*/
|
|
39
|
+
async stopInAppScreenCapture() {
|
|
40
|
+
if (Platform.OS !== 'ios') {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
return StreamVideoReactNative?.stopInAppScreenCapture();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export const screenShareAudioMixingManager = new ScreenShareAudioManager();
|
|
47
|
+
//# sourceMappingURL=ScreenShareAudioManager.js.map
|