diff --git a/.changeset/bright-houses-relax.md b/.changeset/bright-houses-relax.md new file mode 100644 index 000000000..5b434e288 --- /dev/null +++ b/.changeset/bright-houses-relax.md @@ -0,0 +1,5 @@ +--- +"client-sdk-android": minor +--- + +Default prioritizing speaker over earpiece diff --git a/.changeset/new-bulldogs-bow.md b/.changeset/new-bulldogs-bow.md new file mode 100644 index 000000000..ab91d36e2 --- /dev/null +++ b/.changeset/new-bulldogs-bow.md @@ -0,0 +1,5 @@ +--- +"client-sdk-android": minor +--- + +Explicitly expose AudioSwitchHandler from Room for easier audio handling diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/audio/AudioSwitchHandler.kt b/livekit-android-sdk/src/main/java/io/livekit/android/audio/AudioSwitchHandler.kt index 5fda6f8d4..d3b72f867 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/audio/AudioSwitchHandler.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/audio/AudioSwitchHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 LiveKit, Inc. + * Copyright 2023-2025 LiveKit, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,8 @@ import javax.inject.Inject import javax.inject.Singleton /** - * An [AudioHandler] built on top of [AudioSwitch]. + * An [AudioHandler] built on top of [AudioSwitch]. This handles things such as + * getting the audio focus as needed, as well as automatic audio output device management. * * The various settings should be set before connecting to a [Room] and [start] is called. */ @@ -222,8 +223,8 @@ constructor(private val context: Context) : AudioHandler { listOf( AudioDevice.BluetoothHeadset::class.java, AudioDevice.WiredHeadset::class.java, - AudioDevice.Earpiece::class.java, AudioDevice.Speakerphone::class.java, + AudioDevice.Earpiece::class.java, ) } } diff --git a/livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt b/livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt index d7bd703f8..7d355d3df 100644 --- a/livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt +++ b/livekit-android-sdk/src/main/java/io/livekit/android/room/Room.kt @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 LiveKit, Inc. + * Copyright 2023-2025 LiveKit, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,10 +26,13 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import io.livekit.android.ConnectOptions +import io.livekit.android.LiveKit +import io.livekit.android.LiveKitOverrides import io.livekit.android.RoomOptions import io.livekit.android.Version import io.livekit.android.audio.AudioHandler import io.livekit.android.audio.AudioProcessingController +import io.livekit.android.audio.AudioSwitchHandler import io.livekit.android.audio.AuthedAudioProcessingController import io.livekit.android.audio.CommunicationWorkaround import io.livekit.android.dagger.InjectionNames @@ -77,6 +80,17 @@ constructor( private val defaultDispatcher: CoroutineDispatcher, @Named(InjectionNames.DISPATCHER_IO) private val ioDispatcher: CoroutineDispatcher, + /** + * The [AudioHandler] for setting up the audio as need. + * + * By default, this is an instance of [AudioSwitchHandler]. + * + * This can be substituted for your own custom implementation through + * [LiveKitOverrides.audioOptions] when creating the room with [LiveKit.create]. + * + * @see [audioSwitchHandler] + * @see [AudioSwitchHandler] + */ val audioHandler: AudioHandler, private val closeableManager: CloseableManager, private val e2EEManagerFactory: E2EEManager.Factory, @@ -272,6 +286,14 @@ constructor( val remoteParticipants: Map get() = mutableRemoteParticipants + /** + * A convenience getter for the audio handler as a [AudioSwitchHandler]. + * + * Will return null if [audioHandler] is not a [AudioSwitchHandler]. + */ + val audioSwitchHandler: AudioSwitchHandler? + get() = audioHandler as? AudioSwitchHandler + private var sidToIdentity = mutableMapOf() private var mutableActiveSpeakers by flowDelegate(emptyList())