[bug] Cannot change audio output to earpiece if a bluetooth device is connected.
Describe the bug
When a Bluetooth audio device (e.g., AirPods, earbuds) is connected, it becomes impossible to route audio to the phone's earpiece using Room.setAudioOutputDevice() or Room.setSpeakerOn(false). The audio continues to route to the Bluetooth device instead of the earpiece, even after explicit device selection.
This appears to be due to the mobile OS (iOS/Android) prioritizing Bluetooth audio routing over earpiece routing. While switching from Bluetooth to speaker works correctly via setSpeakerOn(true), switching from Bluetooth to earpiece does not work as expected.
To Reproduce
- Connect Bluetooth earbuds/headphones to the device
- Join a LiveKit room with audio enabled
- Get available audio output devices using
Hardware.instance.audioOutputs() - Attempt to switch to earpiece using either:
-
room.setAudioOutputDevice(earpiece_device) -
room.setSpeakerOn(false)after Bluetooth was active
-
- Observe that audio continues playing through Bluetooth device instead of earpiece
Expected behavior
When selecting the earpiece device from the available audio outputs, the audio should route to the phone's earpiece/receiver, not continue playing through the Bluetooth device. The behavior should be:
- Bluetooth → Speaker: ✅ Works (via
setSpeakerOn(true)) - Bluetooth → Earpiece: ❌ Fails (audio stays on Bluetooth)
- Speaker → Earpiece: ✅ Works
- Earpiece → Bluetooth: ✅ Works
Platform information
- Flutter version: 3.35.1
- Plugin version: livekit_client: ^2.4.9
- Flutter target OS: Android (Model: Pixel 6a, Real Device)
- Flutter target OS version: Android 16 Baklava
Additional context
We've tested various workarounds including:
- Multiple calls to
setAudioOutputDevice() - Toggling
setSpeakerOn(true)thensetSpeakerOn(false)with delays - Attempting audio session resets via microphone disable/enable cycles
None of these approaches reliably route audio from Bluetooth to earpiece. This seems to be a limitation of how mobile operating systems handle audio routing priorities (Bluetooth > Speaker > Earpiece), but it would be valuable if LiveKit could provide a way to override this behavior or document the limitation.
Workaround
Currently hiding the earpiece option in the UI when Bluetooth devices are detected to prevent user confusion.