livekit / client-sdk-android

LiveKit SDK for Android
https://docs.livekit.io
Apache License 2.0
174 stars 69 forks source link

Input is taken from speaker not bluetooth device if the Room has no other members that are publishing audio tracks. #242

Closed wissa-b closed 1 year ago

wissa-b commented 1 year ago

Describe the bug If localParticipant.setMicrophoneEnabled is set to false by default ( after room.connect ) is called. And the user has a bluetooth device connected, after the user unmute him/her self, as long as no other users unmuted once in the room, the audio input is taken from the speaker although bluetooth is the top item in preferred device list. But when any other user in the room unmutes, then suddenly the audio input is routed from the bluetooth device!.

I was able to reproduce it on the sample app too, just set the enabled parameter to false in line 142: CallViewModel>connectToRoom> localParticipant.setMicrophoneEnabled(false)

To Reproduce Steps to reproduce the behavior:

in the sample app:

  1. Set LocalParticipant.setMicrophoneEnabled(false) / and
  2. Connect to a bluetooth headset
  3. Start the app
  4. Connect to a Room with a valid token
  5. wait for other users to join
  6. No other users should unmute themselves yet.
  7. Unmute yourself.
  8. Start speaking
  9. Your audio is transmitted through the phone's speaker / earpiece (depending on your preferences)
  10. Ask another user to unmute themselves.
  11. Your audio starts to be transmitted from the bluetooth headset.

Expected behavior If no one else in the room is unmuted, and the user is muted by default when joining the room, on unmute the audio input should come from the bluetooth headset.

Screenshots If applicable, add screenshots to help explain your problem.

Device Info:

Additional context The Audio switch activates the devices in the correct order, Bluetooth headset is activated last.

davidliu commented 1 year ago

User reporting issue as not fixed, reopening.

davidliu commented 1 year ago

It looks like on Android 12, the audio mode MODE_IN_COMMUNICATION can't be kept if no audio output is being played, and the WebRTC default audio source defaulted to VOICE_COMMUNICATION (which required the aforementioned audio mode to work correctly).

The audio mode defaults are now being changed to MODE_NORMAL and AudioSource.DEFAULT. This may affect noise suppression capabilities, though I didn't hear a different on my phone.

To change the modes back to the previous values, you'll have to pass in the appropriate overrides when creating the room:

val room = LiveKit.create(
        appContext = application,
        overrides = LiveKitOverrides(
            audioHandler = AudioSwitchHandler(application).apply {
                audioMode = AudioManager.MODE_IN_COMMUNICATION
            },
            javaAudioDeviceModuleCustomizer = {
                it.setAudioSource(AudioSource.VOICE_COMMUNICATION)
            }
        )
    )

There may be a workaround to use the communication modes by playing a silent audio track, but didn't seem to work with the webrtc sdk, so that's something I'll need to investigate another time.

wissa-b commented 1 year ago

@davidliu I can confirm the issue is solved. thank you 🚀