@voltkit-rtc/react-native 0.1.5 → 0.1.6

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.6
4
+
5
+ 2026-11-06. WebRTC's own echo canceller by default on Android. Same peer dependencies as 0.1.5. Build the app again after
6
+ upgrading: the setting is read from the manifest when the app starts, and the version check reads this package's version.
7
+
8
+ - **WebRTC's echo canceller (AEC3) and noise suppressor by default** (`android.hardwareEchoCancellation` now defaults to
9
+ `false`; meta-data `in.voltkit.rtc.HW_AEC`). On Android, while WebRTC uses the phone's own canceller it switches its own
10
+ off, so the result depended on the phone: on an Oppo on the loudspeaker the person on the other phone heard themselves
11
+ with distortion, in this SDK and the Flutter one (a developer's finding, 2026-11-06). Agora and ZEGO tell developers to
12
+ use the SDK's canceller for such phones; theirs keep one, WebRTC does not. AEC3 is the canceller browsers use, and the
13
+ one this SDK's `react-native-webrtc` build carries. To keep the phone's, as before 0.1.6, set
14
+ `android: { hardwareEchoCancellation: true }` in the plugin options (or `in.voltkit.rtc.HW_AEC` to `true`). iOS is
15
+ unchanged: it uses the system's voice processing.
16
+
3
17
  ## 0.1.5
4
18
 
5
19
  2026-11-05. A developer's findings on 0.1.4, and the round of 2026-11-05 (decisions D2 and D10). Peer dependencies
package/README.md CHANGED
@@ -134,7 +134,7 @@ you edit no native file:
134
134
  | `android.callServiceCamera` | `false` | Adds the `camera` type and `FOREGROUND_SERVICE_CAMERA`, for an app that keeps the camera on in the background (`background={{ pauseCamera: false }}`) |
135
135
  | `android.screenShare` | `false` | Turns on react-native-webrtc's screen-capture service for [screen sharing](#screen-sharing), with `FOREGROUND_SERVICE_MEDIA_PROJECTION` and the `mediaProjection` type on the call service |
136
136
  | `android.audioMode` | `"communication"` | `"media"` for an app whose users only listen: see [Audio routing](#audio-routing) |
137
- | `android.hardwareEchoCancellation` | `true` | The phone's own echo canceller and noise suppressor, where it has them |
137
+ | `android.hardwareEchoCancellation` | `false` | `false` (the default from 0.1.6): WebRTC's own echo canceller and noise suppressor (AEC3). `true`: the phone's own, where it has them, as before 0.1.6. See [Echo on Android](#echo-on-android) |
138
138
  | `ios.backgroundAudio` | `true` | Adds `audio` to `UIBackgroundModes`, so a call keeps its sound in the background |
139
139
  | `ios.voip` | `false` | Adds `voip` to `UIBackgroundModes`, for an app that integrates CallKit itself |
140
140
 
@@ -741,11 +741,12 @@ export function OutputPicker() {
741
741
  tried again until the user picks it, a device is added, or the call ends.
742
742
  - **No Bluetooth permission** is needed: the routing goes through Android's
743
743
  `AudioManager`.
744
- - **Echo on one phone model.** The phone's own echo canceller and noise
745
- suppressor are used where it has them. If one model echoes, turn them off with
746
- the Expo plugin's `android.hardwareEchoCancellation: false` (or the
747
- `in.voltkit.rtc.HW_AEC` meta-data, below), and WebRTC's own echo canceller
748
- does the work.
744
+ - **Echo cancellation.** From 0.1.6, WebRTC's own echo canceller and noise
745
+ suppressor (AEC3, the one browsers use), not the phone's built-in ones, which
746
+ some phones cannot run well on the loudspeaker.
747
+ `android: { hardwareEchoCancellation: true }` in the Expo plugin's options (or
748
+ the `in.voltkit.rtc.HW_AEC` meta-data, below) brings the phone's back. See
749
+ [Echo on Android](#echo-on-android).
749
750
  - **Apps whose users only listen** can set the audio mode to `media` (the
750
751
  plugin's `android.audioMode`, or the `in.voltkit.rtc.AUDIO_MODE` meta-data):
751
752
  sound plays at the media volume and on Bluetooth's high-quality profile, with
@@ -765,8 +766,8 @@ In a React Native app without Expo, the audio settings are meta-data in
765
766
  <application>
766
767
  <!-- communication (calls and audio rooms) or media (listen-only apps) -->
767
768
  <meta-data android:name="in.voltkit.rtc.AUDIO_MODE" android:value="communication" />
768
- <!-- the phone's own echo canceller and noise suppressor, where it has them -->
769
- <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="true" />
769
+ <!-- false: WebRTC's own echo canceller and noise suppressor (from 0.1.6); true: the phone's own, where it has them -->
770
+ <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="false" />
770
771
  <!-- react-native-webrtc's screen-capture service: see Screen sharing -->
771
772
  <meta-data android:name="in.voltkit.rtc.SCREEN_SHARE" android:value="false" />
772
773
  </application>
@@ -1433,12 +1434,42 @@ The emulator has only the loudspeaker, so `useAudioOutput().outputs` lists one
1433
1434
  output and `setSpeakerphoneOn(false)` has nowhere else to go. Test the earpiece
1434
1435
  and headsets on a phone.
1435
1436
 
1436
- ### Echo on one phone model
1437
+ ### Echo on Android
1437
1438
 
1438
- Turn off the phone's own echo canceller with the Expo plugin's
1439
- `android.hardwareEchoCancellation: false` (or `in.voltkit.rtc.HW_AEC` set to
1440
- `false`) and build again; WebRTC's own canceller takes over. A headset or the
1441
- earpiece removes echo entirely.
1439
+ From 0.1.6 the SDK uses WebRTC's own echo canceller and noise suppressor (AEC3,
1440
+ the one browsers use) on Android, not the phone's built-in ones. While WebRTC
1441
+ uses a phone's canceller it switches its own off, and some phones' cancellers
1442
+ do not cope with the loudspeaker: the person on the other phone hears their own
1443
+ voice back, even in another room. An app on 0.1.5 or earlier that sees this
1444
+ should upgrade and build again.
1445
+
1446
+ To use the phone's own canceller instead, as before 0.1.6, set it in the Expo
1447
+ plugin's options, in `app.json` or `app.config.js`:
1448
+
1449
+ ```json
1450
+ {
1451
+ "expo": {
1452
+ "plugins": [
1453
+ ["@voltkit-rtc/react-native", { "android": { "hardwareEchoCancellation": true } }]
1454
+ ]
1455
+ }
1456
+ }
1457
+ ```
1458
+
1459
+ Then make a new build of the app (`npx expo run:android`, or a new EAS build):
1460
+ the setting is read when the app starts, so reloading the JavaScript does not
1461
+ apply it. In a React Native app without Expo, set the meta-data in
1462
+ `AndroidManifest.xml` instead, and build again:
1463
+
1464
+ ```xml
1465
+ <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="true" />
1466
+ ```
1467
+
1468
+ An Expo app uses the plugin option, not a hand edit: `expo prebuild` writes the
1469
+ manifest again, and the edit is lost. Test either choice on the phone that
1470
+ echoed and on another before you ship it. A headset or the earpiece on the
1471
+ phone that causes the echo also stops it. Where echo comes from, including two
1472
+ phones in one room: https://voltkit.in/docs/troubleshooting#echo.
1442
1473
 
1443
1474
  ### Google Play rejects the app for 16 KB page sizes
1444
1475
 
@@ -25,8 +25,10 @@ internal enum class AudioMode {
25
25
  * (plan §5.3), as the Expo config plugin writes them or a hand-written manifest gives them:
26
26
  *
27
27
  * <meta-data android:name="in.voltkit.rtc.AUDIO_MODE" android:value="communication" /> communication | media
28
- * <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="true" /> the handset's own echo
29
- * canceller and noise suppressor
28
+ * <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="false" /> the handset's own echo
29
+ * canceller and noise suppressor;
30
+ * false (the default from 0.1.6):
31
+ * WebRTC's own (AEC3)
30
32
  * <meta-data android:name="in.voltkit.rtc.SCREEN_SHARE" android:value="false" /> react-native-webrtc's
31
33
  * screen-share service
32
34
  *
@@ -34,7 +36,7 @@ internal enum class AudioMode {
34
36
  */
35
37
  internal data class RtcConfig(
36
38
  val audioMode: AudioMode = AudioMode.communication,
37
- val hardwareEchoCancellation: Boolean = true,
39
+ val hardwareEchoCancellation: Boolean = false,
38
40
  val screenShare: Boolean = false,
39
41
  /** What could not be read, with the default used instead; the init provider logs it. */
40
42
  val problems: List<String> = emptyList(),
@@ -55,7 +57,7 @@ internal data class RtcConfig(
55
57
  }
56
58
  return RtcConfig(
57
59
  audioMode = mode,
58
- hardwareEchoCancellation = flag(meta(HW_AEC), HW_AEC, default = true, problems),
60
+ hardwareEchoCancellation = flag(meta(HW_AEC), HW_AEC, default = false, problems),
59
61
  screenShare = flag(meta(SCREEN_SHARE), SCREEN_SHARE, default = false, problems),
60
62
  problems = problems,
61
63
  )
@@ -21,7 +21,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
21
21
  */
22
22
 
23
23
  /** The version of this package: what getDiagnostics() reports, and what the native side was built from. */
24
- const SDK_VERSION = exports.SDK_VERSION = '0.1.5';
24
+ const SDK_VERSION = exports.SDK_VERSION = '0.1.6';
25
25
 
26
26
  /** The native module, or null where there is none (iOS, Expo Go, an app not rebuilt). */
27
27
  function nativeModule() {
@@ -9,7 +9,7 @@ import { Platform } from 'react-native';
9
9
  import NativeVoltkitRtc from "./specs/NativeVoltkitRtc.js";
10
10
  import { iosUnsupported, logError, nativeMissing } from "./errors.js";
11
11
  /** The version of this package: what getDiagnostics() reports, and what the native side was built from. */
12
- export const SDK_VERSION = '0.1.5';
12
+ export const SDK_VERSION = '0.1.6';
13
13
 
14
14
  /** The native module, or null where there is none (iOS, Expo Go, an app not rebuilt). */
15
15
  export function nativeModule() {
@@ -2,7 +2,7 @@ import type { EventSubscription } from 'react-native';
2
2
  import { type AudioDevice, type Constants, type Spec } from './specs/NativeVoltkitRtc';
3
3
  import type { MediaDevice } from '@voltkit-rtc/client';
4
4
  /** The version of this package: what getDiagnostics() reports, and what the native side was built from. */
5
- export declare const SDK_VERSION = "0.1.5";
5
+ export declare const SDK_VERSION = "0.1.6";
6
6
  /** The native module, or null where there is none (iOS, Expo Go, an app not rebuilt). */
7
7
  export declare function nativeModule(): Spec | null;
8
8
  /** The module's constants, read once: the audio mode, screen sharing, the call service as the manifest declares them. */
@@ -2,7 +2,7 @@ import type { EventSubscription } from 'react-native';
2
2
  import { type AudioDevice, type Constants, type Spec } from './specs/NativeVoltkitRtc.js';
3
3
  import type { MediaDevice } from '@voltkit-rtc/client';
4
4
  /** The version of this package: what getDiagnostics() reports, and what the native side was built from. */
5
- export declare const SDK_VERSION = "0.1.5";
5
+ export declare const SDK_VERSION = "0.1.6";
6
6
  /** The native module, or null where there is none (iOS, Expo Go, an app not rebuilt). */
7
7
  export declare function nativeModule(): Spec | null;
8
8
  /** The module's constants, read once: the audio mode, screen sharing, the call service as the manifest declares them. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltkit-rtc/react-native",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "React Native SDK for VoltKit RTC: calls, audio rooms and live video on Android (iOS in preview), with the hooks of @voltkit-rtc/react, background calls, audio routing and an Expo config plugin.",
5
5
  "keywords": [
6
6
  "voltkit",
@@ -25,7 +25,7 @@ exports.setVoltkitManifest = setVoltkitManifest;
25
25
  * <uses-feature android:name="android.hardware.microphone" android:required="false" /> with RECORD_AUDIO
26
26
  * <application>
27
27
  * <meta-data android:name="in.voltkit.rtc.AUDIO_MODE" android:value="communication" /> RtcConfig.kt
28
- * <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="true" />
28
+ * <meta-data android:name="in.voltkit.rtc.HW_AEC" android:value="false" />
29
29
  * <meta-data android:name="in.voltkit.rtc.SCREEN_SHARE" android:value="false" />
30
30
  * <service android:name="com.voltkit.rtc.reactnative.VoltkitCallService" android:exported="false"
31
31
  * android:foregroundServiceType="microphone|mediaPlayback" /> VoltkitCallService.kt
@@ -51,7 +51,11 @@ export interface VoltkitRtcAndroidProps {
51
51
  * android.blockedPermissions blocks what it needs.
52
52
  */
53
53
  screenShare?: boolean;
54
- /** The phone's own echo canceller and noise suppressor, where it has them (meta-data in.voltkit.rtc.HW_AEC; default true). */
54
+ /**
55
+ * The phone's own echo canceller and noise suppressor, where it has them (meta-data in.voltkit.rtc.HW_AEC). Default false
56
+ * from 0.1.6: WebRTC's own (AEC3, the one browsers use), because WebRTC switches its own off while it uses the phone's and
57
+ * some phones' cancellers do not cope with the loudspeaker. True for the phone's, as before 0.1.6.
58
+ */
55
59
  hardwareEchoCancellation?: boolean;
56
60
  }
57
61
  export interface VoltkitRtcIosProps {
@@ -28,7 +28,7 @@ const ANDROID_DEFAULTS = {
28
28
  callService: true,
29
29
  callServiceCamera: false,
30
30
  screenShare: false,
31
- hardwareEchoCancellation: true,
31
+ hardwareEchoCancellation: false,
32
32
  };
33
33
  const IOS_DEFAULTS = { backgroundAudio: true, voip: false };
34
34
  const TOP_KEYS = ['cameraPermission', 'microphonePermission', 'android', 'ios'];
package/src/native.ts CHANGED
@@ -10,7 +10,7 @@ import { iosUnsupported, logError, nativeMissing } from './errors';
10
10
  import type { AudioDeviceType, DeviceKind, MediaDevice } from '@voltkit-rtc/client';
11
11
 
12
12
  /** The version of this package: what getDiagnostics() reports, and what the native side was built from. */
13
- export const SDK_VERSION = '0.1.5';
13
+ export const SDK_VERSION = '0.1.6';
14
14
 
15
15
  /** The native module, or null where there is none (iOS, Expo Go, an app not rebuilt). */
16
16
  export function nativeModule(): Spec | null {