Summary
@elevenlabs/react-native hard-codes the LiveKit audio session config inside reactNativeSessionSetup (src/index.react-native.ts):
await AudioSession.configureAudio({
android: {
preferredOutputList: ["speaker"],
audioTypeOptions: AndroidAudioTypePresets.communication,
},
ios: {
defaultOutput: "speaker",
},
});
On Android, preferredOutputList is the entire automatic routing order — any output not on the list is never auto-selected. ["speaker"] therefore removes Bluetooth and wired headsets from routing completely: with a BT earpiece (or hearing aid) connected, conversation audio always plays through the phone speaker and the user may hear nothing at all. LiveKit's own default for this option is bluetooth > headset > speaker > earpiece, which the SDK silently overrides.
Because the SDK calls configureAudio inside every startSession(), right before connecting, an app cannot fix this from the outside — any app-level AudioSession.configureAudio(...) is overwritten by the SDK's copy. Still present in 1.2.14 (latest at time of writing).
iOS is less affected: the LiveKit native module keeps .allowBluetooth/.allowBluetoothA2DP in the category options, and defaultOutput: "speaker" only adds .defaultToSpeaker, which yields to a connected headset.
Real-world impact
We build a voice companion app for elderly users. A user with a connected Bluetooth earpiece went through three consecutive sessions unable to hear the agent; app restarts and a phone reboot (obviously) didn't help. Hearing-aid users are the worst-affected group, and they're exactly the users least able to troubleshoot audio routing.
Repro
- Android device, pair any Bluetooth audio device (earbud/headset).
- Start a conversation via
useConversation().startSession(...).
- Agent audio plays from the phone speaker; the BT device receives nothing.
AudioSession.selectAudioOutput is the only escape hatch, and app-level configureAudio before the session has no effect (the SDK re-applies its own config).
Proposed fix
Either (or both):
- Change the hard-coded list to LiveKit's default order,
["bluetooth", "headset", "speaker", "earpiece"] — speaker behavior is unchanged when no headset is connected, and headsets work like they do in a phone call.
- Expose the audio configuration (e.g. an optional
audioSessionConfig on startSession options, or respect a previously applied app-level configureAudio instead of overwriting it).
Current workaround
We ship a pnpm patchedDependencies patch rewriting the hard-coded list, plus a unit test that fails if an SDK bump drops the patch. Works, but every consumer of this SDK with headset users is hitting the same bug.
Happy to open a PR for either variant if you tell me which direction you'd prefer.
Summary
@elevenlabs/react-nativehard-codes the LiveKit audio session config insidereactNativeSessionSetup(src/index.react-native.ts):On Android,
preferredOutputListis the entire automatic routing order — any output not on the list is never auto-selected.["speaker"]therefore removes Bluetooth and wired headsets from routing completely: with a BT earpiece (or hearing aid) connected, conversation audio always plays through the phone speaker and the user may hear nothing at all. LiveKit's own default for this option isbluetooth > headset > speaker > earpiece, which the SDK silently overrides.Because the SDK calls
configureAudioinside everystartSession(), right before connecting, an app cannot fix this from the outside — any app-levelAudioSession.configureAudio(...)is overwritten by the SDK's copy. Still present in 1.2.14 (latest at time of writing).iOS is less affected: the LiveKit native module keeps
.allowBluetooth/.allowBluetoothA2DPin the category options, anddefaultOutput: "speaker"only adds.defaultToSpeaker, which yields to a connected headset.Real-world impact
We build a voice companion app for elderly users. A user with a connected Bluetooth earpiece went through three consecutive sessions unable to hear the agent; app restarts and a phone reboot (obviously) didn't help. Hearing-aid users are the worst-affected group, and they're exactly the users least able to troubleshoot audio routing.
Repro
useConversation().startSession(...).AudioSession.selectAudioOutputis the only escape hatch, and app-levelconfigureAudiobefore the session has no effect (the SDK re-applies its own config).Proposed fix
Either (or both):
["bluetooth", "headset", "speaker", "earpiece"]— speaker behavior is unchanged when no headset is connected, and headsets work like they do in a phone call.audioSessionConfigonstartSessionoptions, or respect a previously applied app-levelconfigureAudioinstead of overwriting it).Current workaround
We ship a pnpm
patchedDependenciespatch rewriting the hard-coded list, plus a unit test that fails if an SDK bump drops the patch. Works, but every consumer of this SDK with headset users is hitting the same bug.Happy to open a PR for either variant if you tell me which direction you'd prefer.