You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On a physical iPhone, the second (and subsequent) sequential WebRTC conversation captures only silence. The microphone track is live, enabled, and unmuted at the WebRTC level ; bytesSent increments and LiveKit reports the engine running but total audio energy is zero and the agent receives only ....
Root cause: The React Native setup strategy calls AudioSession.stopAudioSession() at the end of each session and AudioSession.startAudioSession() at the start of the next. On iOS, this deactivates and reactivates the AVAudioSession, but the RTCAudioSession's input capture unit is not automatically re-armed when the new LiveKit peer connection publishes its mic track. The hardware tap is stalled.
The reporter confirmed this by manually muting then unmuting: audio resumed immediately within the same track, without any route change. This is the critical signal — a LiveKit-level mute/unmute causes the native RTCAudioSession to call setRecordingEnabled:YES again, which restarts the capture unit.
Fix
After createConnection() resolves (room connected, mic track published), apply an automatic mute → unmute microcycle on localParticipant when running on iOS in a voice session:
This runs before attachNativeVolume and before the conversation is considered ready, so it is invisible to the user (~1–2 async ticks at session start, before the agent begins listening).
Guards:
Platform.OS === "ios" — Android is unaffected and unchanged
!options.textOnly — no mic track is published in text-only sessions; no-op there
try/catch — failure is non-fatal and logged via console.warn; the session continues
Changes
File
Change
packages/react-native/src/index.react-native.ts
Add iosRearmMicrophone() helper; call it in reactNativeSessionSetup after createConnection() on iOS voice sessions
This issue only reproduces on a physical iPhone (not Simulator — Simulator has no AVAudioSession hardware stall). The recommended validation steps from the issue reporter:
Build a native Expo development client for iPhone using the official examples/react-native-expo app with this patch applied
Start a conversation, speak, confirm the agent responds, call endSession()
Wait for provider status disconnected
Immediately start a second conversation and speak
Confirm bytesSent and audioLevel are non-zero for session 2
Repeat for 10 consecutive sessions
Expected (with fix): all sessions capture and transmit microphone audio normally Expected (without fix): sessions 2+ show audioLevel: 0, bytesSent << session 1
Low Risk
Scoped to iOS voice WebRTC session startup with guarded, best-effort mic toggle; no API or auth changes, though a failed re-arm could still leave the known silent-mic bug on that call.
Overview
Fixes silent microphone on the 2nd+ back-to-back WebRTC voice call on physical iPhones (#991). After stopAudioSession() / startAudioSession() between calls, iOS can leave the RTCAudioSession input tap stalled even though the LiveKit mic track looks live.
The React Native voice setup strategy now runs an automatic mute → unmute on localParticipant right after createConnection() for iOS non–text-only WebRTC sessions (iosRearmMicrophone), before native volume attach—mirroring the manual toggle that restores capture. Failures are non-fatal (console.warn); Android and text-only sessions are unchanged. CHANGELOG documents the patch under Unreleased.
Reviewed by Cursor Bugbot for commit 5c8f5e2. Bugbot is set up for automated code reviews on this repo. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #991
Problem
On a physical iPhone, the second (and subsequent) sequential WebRTC conversation captures only silence. The microphone track is live, enabled, and unmuted at the WebRTC level ;
bytesSentincrements and LiveKit reports the engine running but total audio energy is zero and the agent receives only....Root cause: The React Native setup strategy calls
AudioSession.stopAudioSession()at the end of each session andAudioSession.startAudioSession()at the start of the next. On iOS, this deactivates and reactivates the AVAudioSession, but the RTCAudioSession's input capture unit is not automatically re-armed when the new LiveKit peer connection publishes its mic track. The hardware tap is stalled.The reporter confirmed this by manually muting then unmuting: audio resumed immediately within the same track, without any route change. This is the critical signal — a LiveKit-level mute/unmute causes the native RTCAudioSession to call
setRecordingEnabled:YESagain, which restarts the capture unit.Fix
After
createConnection()resolves (room connected, mic track published), apply an automatic mute → unmute microcycle onlocalParticipantwhen running on iOS in a voice session:This runs before
attachNativeVolumeand before the conversation is considered ready, so it is invisible to the user (~1–2 async ticks at session start, before the agent begins listening).Guards:
Platform.OS === "ios"— Android is unaffected and unchanged!options.textOnly— no mic track is published in text-only sessions; no-op theretry/catch— failure is non-fatal and logged viaconsole.warn; the session continuesChanges
packages/react-native/src/index.react-native.tsiosRearmMicrophone()helper; call it inreactNativeSessionSetupaftercreateConnection()on iOS voice sessionspackages/react-native/CHANGELOG.mdTesting
This issue only reproduces on a physical iPhone (not Simulator — Simulator has no AVAudioSession hardware stall). The recommended validation steps from the issue reporter:
examples/react-native-expoapp with this patch appliedendSession()disconnectedbytesSentandaudioLevelare non-zero for session 2Expected (with fix): all sessions capture and transmit microphone audio normally
Expected (without fix): sessions 2+ show
audioLevel: 0,bytesSent<< session 1Related