Issue In Audio Call

Currently I have Two React-native Application A and B and i am Using LiveKit for Audio Call functionality
My A and B both application is working Great in android Devices
And
A in Android and B in Ios is working
B in IOS and A in Android case Android audio is going to IOS but IOS Audio is not receiving in Android App

Both implementation is same
Then why the issue came

It’s difficult to say, this sounds like it is only an issue with a single app, and only present on iOS. To me, that points towards something specific in the broken app (either an issue with the app, or some issue in the framework resulting from how it is being called)

If it were me, I would start with the known-working React Native sample, GitHub - livekit-examples/agent-starter-react-native · GitHub, and slowly add features to make it resemble your non-functioning app, to isolate the root cause.

Similar issue: iOS calling Web works, but Web calling iOS fails to transmit audio to the iOS device.

Worth untangling something before either of you goes further: these are two different failures pointing in opposite directions.

  • @mohit: iOS is not sending audio. Android to iOS works, iOS to Android does not.
  • @luis_gerardo_camara_salinas: iOS is not playing received audio. iOS to Web works, Web to iOS does not.

Those have different root causes and different fixes, so I would not treat the second as confirmation of the first.

Also worth noting on the original report: since A-on-Android with B-on-iOS worked, and the failing case is app A running on iOS, this narrows to app A’s iOS audio setup specifically. Darryn’s instinct was right, and you can confirm it faster than by rebuilding from the sample.

First: find out which half is broken

This one test decides everything, and both of you should run it before changing any code.

On the receiving side, when the remote audio track arrives, check three things:

  1. Is the track actually subscribed?
  2. Is track.isMuted false?
  3. Is participant.audioLevel moving, or is isSpeaking ever firing, while the other person talks?

Then check bytes on the wire. If you are on LiveKit Cloud, open the session in the dashboard and look at the iOS participant’s published audio track. Self-hosted, pull the same from the server API. For the Web case, chrome://webrtc-internals gives you this directly: look at inbound-rtp for the audio track and watch packetsReceived and audioLevel.

Interpretation:

  • Track subscribed, unmuted, but bytesSent near zero from iOS → iOS is publishing silence. This is a capture / AVAudioSession problem, not a network or subscription problem. That is mohit’s case.
  • Packets arriving, audioLevel non-zero, but nothing audible → iOS is receiving fine and not rendering. This is a playback route / category problem. That is Luis’s case.
  • No packets at all → subscription or connectivity, and a completely different investigation.

Skipping this step is how people spend a week on the wrong half.

If iOS is publishing silence (mohit)

In rough order of likelihood:

1. Something else stole the audio session. This is the most common cause by a wide margin and it is invisible in your LiveKit code. If any other library sets the AVAudioSession category to playback, ambient, or soloAmbient, the LiveKit microphone goes silent while everything else keeps reporting healthy. Common culprits: expo-audio / expo-av, react-native-sound, react-native-track-player, react-native-video, or any notification-sound helper. There is a confirmed issue for exactly this behaviour with expo-audio: livekit/client-sdk-react-native#286.

The tell: log the category and mode right after connect, and again after any sound plays.

// iOS, right after room.connect and again after any other audio plays
// category must be playAndRecord, mode should be voiceChat or videoChat

If it is anything other than playAndRecord, that is your bug, full stop.

2. registerGlobals() missing or called too late. It has to run in index.js, before anything else touches WebRTC. Partial setups produce exactly this kind of “half works” symptom rather than a clean failure.

3. CallKit without audio session handoff. If app A uses CallKit or react-native-callkeep and app B does not, that alone explains why one app breaks on iOS and the other does not. With CallKit, the call provider owns the audio session, and you must forward didActivate and didDeactivate to RTCAudioSession. Without that forwarding, the mic is dead while everything else looks normal. The SDK README calls this out specifically.

4. NSMicrophoneUsageDescription missing from Info.plist, or the permission was granted after connect rather than before. Request and confirm the permission before joining, not during.

5. Simulator. Microphone capture in the iOS Simulator is unreliable. Confirm on a physical device before debugging anything else.

If iOS receives but plays nothing (luis)

Different list:

1. Audio is routing to the earpiece, not the speaker. playAndRecord defaults to the receiver. Users hold the phone in front of them, hear nothing, and report “no audio.” Set defaultToSpeaker:

await AudioSession.configureAudio({ ios: { defaultOutput: 'speaker' } });
await AudioSession.startAudioSession();

Order matters. Configure before starting the session, and start the session before room.connect.

2. Hardware mute switch. Under ambient or soloAmbient, the physical silent switch kills playback. Under playAndRecord it does not. Another reason the category is the first thing to check.

3. Static configuration when the correct config changes mid-session. The right audio configuration shifts as local and remote tracks publish and unpublish. Configuring once at startup is fragile. Use useIOSAudioManagement, or on newer versions let registerGlobals() handle it automatically, which is the default and is usually sufficient for voice apps:

useIOSAudioManagement(room, true, () => ({
  audioCategory: 'playAndRecord',
  audioCategoryOptions: [
    'allowBluetooth', 'allowBluetoothA2DP', 'allowAirPlay', 'defaultToSpeaker',
  ],
  audioMode: 'videoChat',
}));

Be aware there is a known report that selectAudioOutput and setAppleAudioConfiguration can have no effect when called after connect (issue #322 on the same repo), so set your configuration before connecting rather than trying to correct it afterwards.

Since both of your apps share an implementation

If the code really is identical, the difference is in the environment, and these are where it usually hides:

  • Diff the lockfiles, not package.json. Compare @livekit/react-native, @livekit/react-native-webrtc, and livekit-client across both apps. Duplicated or hoisted react-native-webrtc copies under yarn are a documented cause of odd runtime behaviour.
  • Diff Info.plist, specifically NSMicrophoneUsageDescription and UIBackgroundModes.
  • Diff the full native dependency list. Any extra audio-touching pod in one app and not the other is your prime suspect, per cause 1 above.
  • On Android, check LiveKitReactNative.setup() in MainApplication. MediaAudioType is for consume-only apps and will not behave correctly if that side also publishes. CommunicationAudioType is the default and the right one for a call.

If you post the result of the packets-versus-silence test above, plus your AVAudioSession category and mode logged immediately after connect, that should be enough to pin it down without rebuilding from the sample app.