Skip to content

Commit

Permalink
Turn off audio routing for non communication audio modes (#261)
Browse files Browse the repository at this point in the history
* Turn off audio routing for non communication audio modes

* update audioswitch commit

* update audioswitch
  • Loading branch information
davidliu authored Sep 8, 2023
1 parent 265b5d0 commit 75b12b9
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 27 deletions.
2 changes: 1 addition & 1 deletion livekit-android-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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:7b55cec426227a75be25b0d7ad8537d4aede2a2a'
api 'com.github.davidliu:audioswitch:d18e3e31d427c27f1593030e024b370bf24480fd'
implementation "androidx.annotation:annotation:1.4.0"
implementation "androidx.core:core:${versions.androidx_core}"
implementation "com.google.protobuf:protobuf-javalite:${versions.protobuf}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ class AudioOptions(
* This affects the audio routing and how the audio is handled. Default is [AudioType.CallAudioType].
*
* Note: if [audioHandler] is also passed, the values from [audioOutputType] will not be reflected in it,
* and must be set manually.
* and must be set yourself.
*/
val audioOutputType: AudioType? = null,
/**
* Override the default [AudioHandler].
*
* Use [NoAudioHandler] to turn off automatic audio handling.
* Default is [AudioSwitchHandler].
*
* Use [NoAudioHandler] to turn off automatic audio handling or
* [AudioFocusHandler] to get simple audio focus handling.
*/
val audioHandler: AudioHandler? = null,

Expand All @@ -81,20 +84,22 @@ class AudioOptions(
val javaAudioDeviceModuleCustomizer: ((builder: JavaAudioDeviceModule.Builder) -> Unit)? = null,
)

sealed class AudioType(val audioMode: Int, val audioAttributes: AudioAttributes, val audioStreamType: Int) {
sealed class AudioType(
val audioMode: Int,
val audioAttributes: AudioAttributes,
val audioStreamType: Int
) {
/**
* An audio type for general media playback usage (i.e. listener-only use cases).
*
* Audio routing is handled automatically by the system in normal media mode,
* and bluetooth microphones may not work on some devices.
*
* The default [AudioHandler] for this type is [AudioFocusHandler].
*/
class MediaAudioType : AudioType(
AudioManager.MODE_NORMAL,
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.build(),
AudioManager.STREAM_MUSIC
)
Expand All @@ -103,8 +108,6 @@ sealed class AudioType(val audioMode: Int, val audioAttributes: AudioAttributes,
* An audio type for calls (i.e. participating in the call or publishing local microphone).
*
* Audio routing can be manually controlled.
*
* The default [AudioHandler] for this type is [AudioSwitchHandler].
*/
class CallAudioType : AudioType(
AudioManager.MODE_IN_COMMUNICATION,
Expand All @@ -117,8 +120,6 @@ sealed class AudioType(val audioMode: Int, val audioAttributes: AudioAttributes,

/**
* An audio type that takes in a user-defined [AudioAttributes] and audio stream type.
*
* The default [AudioHandler] for this type is [AudioFocusHandler].
*/
class CustomAudioType(audioMode: Int, audioAttributes: AudioAttributes, audioStreamType: Int) :
AudioType(audioMode, audioAttributes, audioStreamType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import javax.inject.Singleton
class AudioSwitchHandler
@Inject
constructor(private val context: Context) : AudioHandler {

/**
* Toggle whether logging is enabled for [AudioSwitch]. By default, this is set to false.
*/
Expand Down Expand Up @@ -124,6 +125,15 @@ constructor(private val context: Context) : AudioHandler {
*/
var audioAttributeContentType: Int = AudioAttributes.CONTENT_TYPE_SPEECH

/**
* On certain Android devices, audio routing does not function properly and bluetooth microphones will not work
* unless audio mode is set to [AudioManager.MODE_IN_COMMUNICATION] or [AudioManager.MODE_IN_CALL].
*
* AudioSwitchHandler by default will not handle audio routing in those cases to avoid audio issues.
*
* If this set to true, AudioSwitchHandler will attempt to do audio routing, though behavior is undefined.
*/
var forceHandleAudioRouting = false

private var audioSwitch: AbstractAudioSwitch? = null

Expand Down Expand Up @@ -156,6 +166,7 @@ constructor(private val context: Context) : AudioHandler {
switch.audioStreamType = audioStreamType
switch.audioAttributeUsageType = audioAttributeUsageType
switch.audioAttributeContentType = audioAttributeContentType
switch.forceHandleAudioRouting = forceHandleAudioRouting

audioSwitch = switch
switch.start(audioDeviceChangeListener ?: defaultAudioDeviceChangeListener)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import android.media.AudioAttributes
import dagger.Module
import dagger.Provides
import io.livekit.android.AudioType
import io.livekit.android.audio.AudioFocusHandler
import io.livekit.android.audio.AudioHandler
import io.livekit.android.audio.AudioSwitchHandler
import javax.inject.Named
Expand Down Expand Up @@ -49,25 +48,15 @@ object AudioHandlerModule {
@Singleton
fun audioHandler(
audioSwitchHandler: Provider<AudioSwitchHandler>,
audioFocusHandler: Provider<AudioFocusHandler>,
@Named(InjectionNames.OVERRIDE_AUDIO_HANDLER)
audioHandlerOverride: AudioHandler?,
audioOutputType: AudioType,
): AudioHandler {
return audioHandlerOverride ?: when (audioOutputType) {
is AudioType.CallAudioType -> {
audioSwitchHandler.get().apply {
audioMode = audioOutputType.audioMode
audioAttributeContentType = audioOutputType.audioAttributes.contentType
audioAttributeUsageType = audioOutputType.audioAttributes.usage
audioStreamType = audioOutputType.audioStreamType
}
}

is AudioType.MediaAudioType,
is AudioType.CustomAudioType -> {
audioFocusHandler.get()
}
return audioHandlerOverride ?: audioSwitchHandler.get().apply {
audioMode = audioOutputType.audioMode
audioAttributeContentType = audioOutputType.audioAttributes.contentType
audioAttributeUsageType = audioOutputType.audioAttributes.usage
audioStreamType = audioOutputType.audioStreamType
}
}
}

0 comments on commit 75b12b9

Please sign in to comment.