davidliu
Committed by GitHub

Add audio/focus options to AudioSwitchHandler (#246)

Also changed the default audio mode to MODE_NORMAL and focus mode to AUDIOFOCUS_GAIN, and the default input audio source to DEFAULT
... ... @@ -140,7 +140,7 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0'
api 'io.github.webrtc-sdk:android:104.5112.10'
api "com.squareup.okhttp3:okhttp:4.10.0"
api 'com.github.davidliu:audioswitch:8edf84ee46cdbc84c2b7725aa8f8d66363e19876'
api 'com.github.davidliu:audioswitch:fb33b237aa50b3d1d2dea0e0695ecb7b38a98971'
implementation "androidx.annotation:annotation:1.4.0"
implementation "androidx.core:core:${versions.androidx_core}"
implementation "com.google.protobuf:protobuf-javalite:${versions.protobuf}"
... ...
package io.livekit.android.audio
import android.content.Context
import android.media.AudioDeviceInfo
import android.media.AudioManager
import android.os.Build
import android.os.Handler
... ... @@ -49,6 +48,20 @@ constructor(private val context: Context) : AudioHandler {
*/
var preferredDeviceList: List<Class<out AudioDevice>>? = null
/**
* The audio mode to use while started.
*
* Defaults to [AudioManager.MODE_NORMAL].
*/
var audioMode: Int = AudioManager.MODE_NORMAL
/**
* The audio focus mode to use while started.
*
* Defaults to [AudioManager.AUDIOFOCUS_GAIN].
*/
var focusMode: Int = AudioManager.AUDIOFOCUS_GAIN
private var audioSwitch: AbstractAudioSwitch? = null
// AudioSwitch is not threadsafe, so all calls should be done on the main thread.
... ... @@ -74,55 +87,10 @@ constructor(private val context: Context) : AudioHandler {
preferredDeviceList = preferredDeviceList ?: defaultPreferredDeviceList
)
}
switch.audioMode = audioMode
switch.focusMode = focusMode
audioSwitch = switch
switch.start { audioDevices: List<AudioDevice>, selectedAudioDevice: AudioDevice? ->
// On >S, some devices don't properly use bluetooth mic if no audio tracks.
// Using the new communication devices api fixes this.
// TODO: Move into AudioSwitch itself
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val commDevices = audioManager.availableCommunicationDevices
val audioDeviceInfo = when (selectedAudioDevice) {
is AudioDevice.BluetoothHeadset -> {
commDevices.firstOrNull { info ->
info.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO || info.type == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP
}
}
is AudioDevice.Earpiece -> {
commDevices.firstOrNull { info ->
info.type == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE
}
}
is AudioDevice.Speakerphone -> {
commDevices.firstOrNull { info ->
info.type == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER
}
}
is AudioDevice.WiredHeadset -> {
commDevices.firstOrNull { info ->
info.type == AudioDeviceInfo.TYPE_WIRED_HEADSET || info.type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES
}
}
else -> {
null
}
}
if (audioDeviceInfo != null) {
audioManager.setCommunicationDevice(audioDeviceInfo)
} else {
audioManager.clearCommunicationDevice()
}
}
audioDeviceChangeListener?.invoke(audioDevices, selectedAudioDevice)
}
switch.start(audioDeviceChangeListener ?: defaultAudioDeviceChangeListener)
switch.activate()
}
}
... ...
package io.livekit.android.dagger
import android.content.Context
import android.media.MediaRecorder
import android.os.Build
import androidx.annotation.Nullable
import dagger.Module
... ... @@ -103,6 +104,7 @@ object RTCModule {
.setAudioTrackErrorCallback(audioTrackErrorCallback)
.setAudioRecordStateCallback(audioRecordStateCallback)
.setAudioTrackStateCallback(audioTrackStateCallback)
.setAudioSource(MediaRecorder.AudioSource.DEFAULT)
moduleCustomizer?.invoke(builder)
return builder.createAudioDeviceModule()
... ...