@stream-io/video-react-native-sdk 1.42.0 → 1.43.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.
Files changed (47) hide show
  1. package/CHANGELOG.md +20 -6
  2. package/dist/commonjs/components/Call/RingingCallContent/OutgoingCall.js.map +1 -1
  3. package/dist/commonjs/components/Participant/FloatingParticipantView/index.js.map +1 -1
  4. package/dist/commonjs/contexts/ThemeContext.js +10 -0
  5. package/dist/commonjs/contexts/ThemeContext.js.map +1 -1
  6. package/dist/commonjs/hooks/useScreenShareButton.js.map +1 -1
  7. package/dist/commonjs/modules/call-manager/CallManager.js.map +1 -1
  8. package/dist/commonjs/providers/NoiseCancellation/lib.js.map +1 -1
  9. package/dist/commonjs/providers/StreamCall/AudioInterruptionTracer.js.map +1 -1
  10. package/dist/commonjs/version.js +1 -1
  11. package/dist/module/components/Call/RingingCallContent/OutgoingCall.js.map +1 -1
  12. package/dist/module/components/Participant/FloatingParticipantView/index.js.map +1 -1
  13. package/dist/module/contexts/ThemeContext.js +10 -0
  14. package/dist/module/contexts/ThemeContext.js.map +1 -1
  15. package/dist/module/hooks/useScreenShareButton.js.map +1 -1
  16. package/dist/module/modules/call-manager/CallManager.js.map +1 -1
  17. package/dist/module/providers/NoiseCancellation/lib.js.map +1 -1
  18. package/dist/module/providers/StreamCall/AudioInterruptionTracer.js.map +1 -1
  19. package/dist/module/version.js +1 -1
  20. package/dist/typescript/components/Participant/FloatingParticipantView/index.d.ts.map +1 -1
  21. package/dist/typescript/contexts/ThemeContext.d.ts +10 -1
  22. package/dist/typescript/contexts/ThemeContext.d.ts.map +1 -1
  23. package/dist/typescript/hooks/useScreenShareButton.d.ts +2 -1
  24. package/dist/typescript/hooks/useScreenShareButton.d.ts.map +1 -1
  25. package/dist/typescript/modules/call-manager/CallManager.d.ts.map +1 -1
  26. package/dist/typescript/providers/NoiseCancellation/lib.d.ts.map +1 -1
  27. package/dist/typescript/providers/StreamCall/AudioInterruptionTracer.d.ts.map +1 -1
  28. package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
  29. package/dist/typescript/version.d.ts +1 -1
  30. package/expo-config-plugin/dist/withAndroidMessagingService.js +29 -3
  31. package/expo-config-plugin/dist/withIosScreenCapture/addBroadcastExtensionXcodeTarget.js +84 -2
  32. package/expo-config-plugin/dist/withIosScreenCapture/withPlistUpdates.js +3 -6
  33. package/expo-config-plugin/dist/withIosScreenCapture/withTarget.js +6 -4
  34. package/expo-config-plugin/static/AudioUploader.swift +230 -0
  35. package/expo-config-plugin/static/SampleHandler.swift +67 -14
  36. package/ios/StreamInCallManager.swift +2 -2
  37. package/ios/StreamVideoReactNative.m +15 -5
  38. package/package.json +27 -25
  39. package/src/components/Call/RingingCallContent/OutgoingCall.tsx +1 -2
  40. package/src/components/Participant/FloatingParticipantView/index.tsx +1 -4
  41. package/src/contexts/ThemeContext.tsx +10 -1
  42. package/src/hooks/useScreenShareButton.ts +2 -1
  43. package/src/modules/call-manager/CallManager.ts +1 -2
  44. package/src/providers/NoiseCancellation/lib.ts +1 -2
  45. package/src/providers/StreamCall/AudioInterruptionTracer.tsx +1 -2
  46. package/src/utils/StreamVideoRN/types.ts +1 -3
  47. package/src/version.ts +1 -1
@@ -51,6 +51,7 @@ void broadcastNotificationCallback(CFNotificationCenterRef center,
51
51
  bool hasListeners;
52
52
  CFNotificationCenterRef _notificationCenter;
53
53
  AVAudioPlayer *_busyTonePlayer; // Instance variable
54
+ ScreenAudioCapture *_screenAudioCapture; // Broadcast screen-share audio receiver
54
55
  }
55
56
 
56
57
  RCT_EXPORT_MODULE();
@@ -647,19 +648,25 @@ RCT_EXPORT_METHOD(startScreenShareAudioMixing:(RCTPromiseResolveBlock)resolve
647
648
  if (apmId && [apmId isKindOfClass:[RTCDefaultAudioProcessingModule class]]) {
648
649
  RTCDefaultAudioProcessingModule *apm = (RTCDefaultAudioProcessingModule *)apmId;
649
650
  apm.capturePostProcessingDelegate = mixer;
650
- NSLog(@"[SSAMixer] Set capturePostProcessingDelegate on APM");
651
651
  } else {
652
- NSLog(@"[SSAMixer] WARNING: No RTCDefaultAudioProcessingModule available, mixing will not work");
652
+ NSLog(@"[SSAudio][Native] WARNING: No RTCDefaultAudioProcessingModule available, screen-share audio mixing will not work");
653
653
  }
654
654
 
655
655
  [mixer startMixing];
656
656
 
657
- // Wire audio buffer handler on the active capturer → mixer.enqueue
658
657
  InAppScreenCapturer *capturer = options.activeInAppScreenCapturer;
659
658
  if (capturer) {
660
659
  capturer.audioBufferHandler = ^(CMSampleBufferRef sampleBuffer) {
661
660
  [mixer enqueue:sampleBuffer];
662
661
  };
662
+ } else {
663
+ if (!_screenAudioCapture) {
664
+ _screenAudioCapture = [ScreenAudioCapture new];
665
+ }
666
+ _screenAudioCapture.onAudioBuffer = ^(AVAudioPCMBuffer *pcmBuffer) {
667
+ [mixer enqueuePCM:pcmBuffer];
668
+ };
669
+ [_screenAudioCapture start];
663
670
  }
664
671
 
665
672
  resolve(nil);
@@ -671,12 +678,16 @@ RCT_EXPORT_METHOD(stopScreenShareAudioMixing:(RCTPromiseResolveBlock)resolve
671
678
  WebRTCModule *webrtcModule = [self.moduleRegistry moduleForName:"WebRTCModule"];
672
679
  WebRTCModuleOptions *options = [WebRTCModuleOptions sharedInstance];
673
680
 
674
- // Stop feeding audio to the mixer
675
681
  InAppScreenCapturer *capturer = options.activeInAppScreenCapturer;
676
682
  if (capturer) {
677
683
  capturer.audioBufferHandler = nil;
678
684
  }
679
685
 
686
+ if (_screenAudioCapture) {
687
+ _screenAudioCapture.onAudioBuffer = nil;
688
+ [_screenAudioCapture stop];
689
+ }
690
+
680
691
  // Stop mixing
681
692
  ScreenShareAudioMixer *mixer = webrtcModule.audioDeviceModule.screenShareAudioMixer;
682
693
  [mixer stopMixing];
@@ -686,7 +697,6 @@ RCT_EXPORT_METHOD(stopScreenShareAudioMixing:(RCTPromiseResolveBlock)resolve
686
697
  if (apmId && [apmId isKindOfClass:[RTCDefaultAudioProcessingModule class]]) {
687
698
  RTCDefaultAudioProcessingModule *apm = (RTCDefaultAudioProcessingModule *)apmId;
688
699
  apm.capturePostProcessingDelegate = nil;
689
- NSLog(@"[SSAMixer] Cleared capturePostProcessingDelegate on APM");
690
700
  }
691
701
 
692
702
  resolve(nil);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-native-sdk",
3
- "version": "1.42.0",
3
+ "version": "1.43.0",
4
4
  "description": "Stream Video SDK for React Native",
5
5
  "author": "https://getstream.io",
6
6
  "homepage": "https://getstream.io/video/docs/react-native/",
@@ -16,7 +16,7 @@
16
16
  "build:expo-plugin": "rimraf expo-config-plugin/dist && tsc --project expo-config-plugin/tsconfig.json",
17
17
  "build": "yarn copy-version && bob build && yarn build:expo-plugin",
18
18
  "test:expo-plugin": "jest --config=expo-config-plugin/jest.config.js --coverage",
19
- "test": "yarn copy-version && jest --coverage && yarn test:expo-plugin",
19
+ "test": "yarn copy-version && jest --coverage && yarn test:types && yarn test:expo-plugin",
20
20
  "test:types": "yarn copy-version && tsc -p tsconfig.spec.json",
21
21
  "copy-version": "echo \"export const version = '$npm_package_version';\" > ./src/version.ts"
22
22
  },
@@ -52,8 +52,8 @@
52
52
  "!**/.*"
53
53
  ],
54
54
  "dependencies": {
55
- "@stream-io/video-client": "1.56.0",
56
- "@stream-io/video-react-bindings": "1.19.1",
55
+ "@stream-io/video-client": "1.57.0",
56
+ "@stream-io/video-react-bindings": "1.19.2",
57
57
  "intl-pluralrules": "2.0.1",
58
58
  "react-native-url-polyfill": "^3.0.0",
59
59
  "rxjs": "~7.8.2",
@@ -65,7 +65,7 @@
65
65
  "@react-native-firebase/messaging": ">=17.5.0",
66
66
  "@stream-io/noise-cancellation-react-native": ">=0.1.0",
67
67
  "@stream-io/react-native-callingx": ">=0.1.0",
68
- "@stream-io/react-native-webrtc": "^145.1.1",
68
+ "@stream-io/react-native-webrtc": "^145.2.0",
69
69
  "@stream-io/video-filters-react-native": ">=0.1.0",
70
70
  "expo": ">=47.0.0",
71
71
  "expo-notifications": "*",
@@ -106,37 +106,39 @@
106
106
  },
107
107
  "devDependencies": {
108
108
  "@babel/core": "^7.29.7",
109
- "@expo/config-plugins": "56.0.8",
110
- "@expo/config-types": "^56.0.5",
109
+ "@babel/preset-env": "^7.29.7",
110
+ "@babel/preset-typescript": "^7.29.7",
111
+ "@expo/config-plugins": "^57.0.6",
112
+ "@expo/config-types": "^57.0.2",
111
113
  "@expo/plist": "^0.7.0",
112
114
  "@react-native-community/netinfo": "12.0.1",
113
- "@react-native-firebase/app": "^24.0.0",
114
- "@react-native-firebase/messaging": "^24.0.0",
115
- "@react-native/babel-preset": "0.85.3",
116
- "@react-native/metro-config": "0.85.3",
117
- "@stream-io/noise-cancellation-react-native": "^0.9.5",
118
- "@stream-io/react-native-callingx": "^0.8.1",
119
- "@stream-io/react-native-webrtc": "145.1.1",
115
+ "@react-native-firebase/app": "^24.1.1",
116
+ "@react-native-firebase/messaging": "^24.1.1",
117
+ "@react-native/babel-preset": "0.86.2",
118
+ "@react-native/jest-preset": "0.86.2",
119
+ "@react-native/metro-config": "0.86.2",
120
+ "@stream-io/noise-cancellation-react-native": "^0.10.0",
121
+ "@stream-io/react-native-callingx": "^0.9.0",
122
+ "@stream-io/react-native-webrtc": "145.2.0",
120
123
  "@stream-io/typescript-config": "^0.0.0",
121
- "@stream-io/video-filters-react-native": "^0.14.5",
124
+ "@stream-io/video-filters-react-native": "^0.15.0",
122
125
  "@testing-library/jest-native": "^5.4.3",
123
126
  "@testing-library/react-native": "13.3.3",
124
127
  "@tsconfig/node18": "^18.2.6",
125
128
  "@types/jest": "^29.5.14",
126
- "@types/node": "^25.9.3",
127
- "@types/react": "~19.2.15",
129
+ "@types/node": "^25.9.5",
130
+ "@types/react": "~19.2.18",
128
131
  "@types/react-test-renderer": "^19.1.0",
129
- "expo": "~56.0.9",
130
- "expo-module-scripts": "^56.0.3",
131
- "expo-notifications": "~56.0.16",
132
+ "expo": "~57.0.9",
133
+ "expo-notifications": "~57.0.8",
132
134
  "jest": "^29.7.0",
133
135
  "react": "19.2.3",
134
- "react-native": "0.85.3",
135
- "react-native-builder-bob": "^0.41.0",
136
- "react-native-gesture-handler": "~2.31.2",
137
- "react-native-reanimated": "4.3.1",
136
+ "react-native": "0.86.2",
137
+ "react-native-builder-bob": "^0.43.0",
138
+ "react-native-gesture-handler": "~2.32.0",
139
+ "react-native-reanimated": "4.5.3",
138
140
  "react-native-svg": "15.15.5",
139
- "react-native-worklets": "0.8.3",
141
+ "react-native-worklets": "0.10.1",
140
142
  "react-test-renderer": "19.2.3",
141
143
  "rimraf": "^6.1.3",
142
144
  "typescript": "^6.0.3"
@@ -109,8 +109,7 @@ const Background = () => {
109
109
  const { useCameraState } = useCallStateHooks();
110
110
  const { isMute, camera } = useCameraState();
111
111
  const localVideoStream = camera.state.mediaStream as unknown as
112
- | MediaStream
113
- | undefined;
112
+ MediaStream | undefined;
114
113
 
115
114
  if (isMute || !localVideoStream) {
116
115
  return (
@@ -25,10 +25,7 @@ import { useFloatingVideoDimensions } from './useFloatingVideoDimensions';
25
25
  import { type StreamVideoParticipant } from '@stream-io/video-client';
26
26
 
27
27
  export type FloatingParticipantViewAlignment =
28
- | 'top-left'
29
- | 'top-right'
30
- | 'bottom-left'
31
- | 'bottom-right';
28
+ 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
32
29
 
33
30
  /**
34
31
  * Props to be passed for the LocalVideoView component.
@@ -7,8 +7,17 @@ import React, {
7
7
 
8
8
  import { defaultTheme, type Theme } from '../theme/theme';
9
9
 
10
+ /**
11
+ * Recursively marks every property of `T` as optional.
12
+ *
13
+ * The `extends object` guard is required, not cosmetic: `Theme` carries a
14
+ * `[component: string]: any` index signature, which the mapped type inherits.
15
+ * Without the guard that index signature becomes `DeepPartial<any>`, an
16
+ * all-object type that no primitive leaf can satisfy, and every theme override
17
+ * fails to typecheck. Guarding short-circuits `any` back to `any`.
18
+ */
10
19
  export type DeepPartial<T> = {
11
- [P in keyof T]?: DeepPartial<T[P]>;
20
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
12
21
  };
13
22
 
14
23
  export type StreamThemeInputValue = {
@@ -37,7 +37,8 @@ export type ScreenShareOptions = {
37
37
  * (e.g., YouTube video audio) mixed with the user's microphone.
38
38
  *
39
39
  * - iOS in-app: Audio captured from RPScreenRecorder `.audioApp` buffers.
40
- * - iOS broadcast: Audio mixing is **not** currently supported.
40
+ * - iOS broadcast: Audio captured in the Broadcast Upload Extension and
41
+ * streamed to the app over a dedicated socket, then mixed into the audio track.
41
42
  * - Android: Audio captured via AudioPlaybackCaptureConfiguration (API 29+).
42
43
  *
43
44
  * Default: `false`.
@@ -55,8 +55,7 @@ const isAndroidTelecomManaged = (): boolean => {
55
55
  * the extra narrowing here is what makes that provable to the type-checker.
56
56
  */
57
57
  const getTelecomContext = ():
58
- | { cx: NonNullable<typeof CallingxModule>; callId: string }
59
- | undefined => {
58
+ { cx: NonNullable<typeof CallingxModule>; callId: string } | undefined => {
60
59
  if (!isAndroidTelecomManaged() || !CallingxModule) {
61
60
  return undefined;
62
61
  }
@@ -17,8 +17,7 @@ export function getNoiseCancellationLibThrowIfNotInstalled() {
17
17
 
18
18
  export class NoiseCancellationWrapper {
19
19
  private static noiseCancellationInstance:
20
- | InstanceType<Type['NoiseCancellation']>
21
- | undefined;
20
+ InstanceType<Type['NoiseCancellation']> | undefined;
22
21
 
23
22
  private constructor() {}
24
23
 
@@ -34,8 +34,7 @@ export const AudioInterruptionTracer = () => {
34
34
  const removeInCallManagerListener =
35
35
  callManager.ios.addAudioInterruptionListener(traceAudioInterruption);
36
36
  const callingx = getCallingxLibIfAvailable() as
37
- | CallingxAudioInterruptionEvents
38
- | undefined;
37
+ CallingxAudioInterruptionEvents | undefined;
39
38
  const callingxSubscription = callingx?.addEventListener(
40
39
  'didAudioInterruption',
41
40
  traceAudioInterruption,
@@ -17,9 +17,7 @@ export type KeepAliveAndroidNotificationTexts = {
17
17
  };
18
18
 
19
19
  export type NonRingingPushEvent =
20
- | 'call.live_started'
21
- | 'call.notification'
22
- | 'call.missed';
20
+ 'call.live_started' | 'call.notification' | 'call.missed';
23
21
 
24
22
  export type StreamVideoConfig = {
25
23
  /**
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.42.0';
1
+ export const version = '1.43.0';