Environment
@livekit/react-native-webrtc 144.1.1, @livekit/react-native 2.11.1
- Consumed via
@elevenlabs/react-native 1.2.15 (WebRTC conversation transport)
- iOS 26.3 (23D127), iPhone 17 Pro (iPhone17,3), React Native 0.83.6 (Fabric/Hermes)
Summary
Within a single app process, the first WebRTC voice session captures microphone
audio normally. Every subsequent session connects, publishes its local audio
track, plays remote audio — but the captured local audio is pure silence. Only
killing the process restores capture. AudioDeviceModule.setVoiceProcessingEnabled(false)
fully resolves it (raw audio unit capture works on every instantiation), which
isolates the fault to the voice-processing IO unit path.
Evidence (Sentry breadcrumb trails from a release build)
Working call 1 and deaf call 2 are indistinguishable at every inspectable layer:
- Identical JS sequences:
AudioSession.startAudioSession() → local track publish
(muted: false) → room connect.
- Identical engine snapshots at connect, read via
AudioDeviceModule:
{ micMuted: false, recording: true, playing: true, engineRunning: true, vpEnabled: true, vpBypassed: false }.
- The engine naturally stops between calls (
engineRunning: false before call 2)
and restarts for call 2 — the restart "succeeds" and captures silence.
Ruled out by on-device falsification across separate builds:
- Audio session refcounting / stale
setActive(false): reference-counting
start/stop so only the first start / last stop reach native → still deaf.
- Deactivation timing: deferring
setActive(false) until 2.6 s after the mic
track stopped (fully clean teardown) → still deaf.
- Re-activation after deactivation: keeping the session active continuously
(never calling setActive(false) between calls) → still deaf. Backgrounding
and returning does not recover; only process death does.
- Latched VPIO mute:
setMicrophoneMuted(false) before every session, and
isMicrophoneMuted() confirmed false during the deaf call → still deaf.
Workaround
// Before each session (engine stopped at this point):
await AudioDeviceModule.setVoiceProcessingEnabled(false)
Capture then works on every session. Software AEC handles echo acceptably on
speakerphone, but losing the hardware voice-processing path (AEC/AGC/NS quality,
power) is a real cost — hence this report.
Repro sketch
- Start a WebRTC session that publishes a mic track (any LiveKit room works;
observed via the ElevenLabs conversation transport). Confirm remote side hears
audio.
- Disconnect the room, stop tracks.
- Start a second session in the same process.
- Remote side receives silence;
AudioDeviceModule.isRecording() returns true.
Environment
@livekit/react-native-webrtc144.1.1,@livekit/react-native2.11.1@elevenlabs/react-native1.2.15 (WebRTC conversation transport)Summary
Within a single app process, the first WebRTC voice session captures microphone
audio normally. Every subsequent session connects, publishes its local audio
track, plays remote audio — but the captured local audio is pure silence. Only
killing the process restores capture.
AudioDeviceModule.setVoiceProcessingEnabled(false)fully resolves it (raw audio unit capture works on every instantiation), which
isolates the fault to the voice-processing IO unit path.
Evidence (Sentry breadcrumb trails from a release build)
Working call 1 and deaf call 2 are indistinguishable at every inspectable layer:
AudioSession.startAudioSession()→ local track publish(
muted: false) → room connect.AudioDeviceModule:{ micMuted: false, recording: true, playing: true, engineRunning: true, vpEnabled: true, vpBypassed: false }.engineRunning: falsebefore call 2)and restarts for call 2 — the restart "succeeds" and captures silence.
Ruled out by on-device falsification across separate builds:
setActive(false): reference-countingstart/stop so only the first start / last stop reach native → still deaf.
setActive(false)until 2.6 s after the mictrack stopped (fully clean teardown) → still deaf.
(never calling
setActive(false)between calls) → still deaf. Backgroundingand returning does not recover; only process death does.
setMicrophoneMuted(false)before every session, andisMicrophoneMuted()confirmedfalseduring the deaf call → still deaf.Workaround
Capture then works on every session. Software AEC handles echo acceptably on
speakerphone, but losing the hardware voice-processing path (AEC/AGC/NS quality,
power) is a real cost — hence this report.
Repro sketch
observed via the ElevenLabs conversation transport). Confirm remote side hears
audio.
AudioDeviceModule.isRecording()returnstrue.