This message was deleted.
# ask-ai
s
This message was deleted.
t
Thanks for reaching out, Gabs. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’ll explain how to manage the audio routine with the LiveKit Android SDK and what you can control. Quick summary of what you can do • Capture & publish microphone audio with
LocalAudioTrack
(create, publish,
setEnabled()
to mute/unmute,
setVolume()
to adjust). • Handle audio routing (speaker, earpiece, Bluetooth) via the SDK’s audio switching helper (
AudioSwitchHandler
) which manages device changes and transitions. • Manage audio focus and interruptions by integrating with Android’s
AudioManager
(the SDK integrates with audio focus handling; ensure your app responds on focus loss/gain). • Request and declare
RECORD_AUDIO
permission at runtime. • Control background behavior by using a foreground service if you need audio while the app is backgrounded and by handling lifecycle events (`onPause`/`onResume`) appropriately. • Opus DTX (silence suppression) is enabled by default to reduce bitrate; it can be changed at track publish time if needed. Basic example (conceptual Kotlin) 1. Create & publish microphone track:
Copy code
val localAudioTrack = LocalAudioTrack.createMicrophoneTrack(context, "mic")
localParticipant.publishAudioTrack(localAudioTrack)
1. Mute/unmute:
Copy code
localAudioTrack.setEnabled(false) // mute
localAudioTrack.setEnabled(true)  // unmute
1. Adjust volume:
Copy code
localAudioTrack.setVolume(0.5f)
Routing & focus notes • Use the SDK’s audio switch handler to let users select Bluetooth/speaker/earpiece and to handle automatic device changes. • Make sure your app requests audio focus via
AudioManager
and responds to focus changes (pause or duck as appropriate). • For background audio, run a foreground service with a notification if you need to keep the microphone or playback active when the app is not visible. If you’d like, I can: • Share a full code sample for integrating
AudioSwitchHandler
and audio focus handling. • Walk through implementing a simple audio device selection UI. Which of those would you prefer? Sources: Bringing Zoom's end-to-end optimizations to WebRTC | LiveKit | Bringing Zoom's end-to-end optimizations to WebRTC | LiveKit, with interactive elements
b
And remote side?
t
Thanks — I’ll explain how to manage the remote side (receiving and controlling other participants’ audio) with the LiveKit Android SDK. What you can do for remote audio • Subscribe to remote audio tracks via the room events (
TrackSubscribed
) and get a
RemoteAudioTrack
. • Control local playback volume for each remote track with
remoteAudioTrack.setVolume(float)
. • Detect remote mute/unmute via track events (
trackMuted
,
trackUnmuted
) and update UI or play indicators. • Unsubscribe from a remote publication to stop receiving audio and save bandwidth with
remoteTrackPublication.setSubscribed(false)
. • Let the SDK manage audio routing (speaker, earpiece, Bluetooth) via the
AudioSwitchHandler
so remote playback follows the device’s current audio route. • Rely on participant lifecycle events (
ParticipantConnected
,
ParticipantDisconnected
,
TrackUnsubscribed
) to keep state in sync. Quick conceptual Kotlin snippets 1. Handle track subscription:
Copy code
// inside room event handler
if (event is RoomEvent.TrackSubscribed && event.track is RemoteAudioTrack) {
    val remoteAudio = event.track as RemoteAudioTrack
    // store and control this track
    remoteAudio.setVolume(1.0f)
}
1. Detect mute/unmute:
Copy code
if (event is RoomEvent.TrackMuted) { /* update UI */ }
if (event is RoomEvent.TrackUnmuted) { /* update UI */ }
1. Unsubscribe:
Copy code
remoteTrackPublication.setSubscribed(false)
Would you like a full sample that wires Room event handling, a per-participant volume UI, and audio device selection with AudioSwitchHandler? , with interactive elements
b
Yes
t
Great — I’ll provide a focused, end-to-end Android example that wires Room event handling, per-participant volume UI, and audio device selection using the SDK’s audio switching. This example is conceptual Kotlin you can adapt into your app. 1) Setup and connect (simplified)
Copy code
val room = Room(options) // create Room per your app setup
room.connect(url, token)
2) Start local microphone and publish
Copy code
// create mic track and publish
val localAudioTrack = LocalAudioTrack.createMicrophoneTrack(context, "mic")
room.localParticipant?.publishTrack(localAudioTrack)
3) Mute/unmute local mic
Copy code
// toggle mic
localAudioTrack.setEnabled(false) // mute
localAudioTrack.setEnabled(true)  // unmute
4) Initialize AudioSwitchHandler (device selection + routing)
Copy code
val audioSwitchHandler = AudioSwitchHandler(context)

// start monitoring available devices (call during call start)
audioSwitchHandler.start { selectedDevice ->
    // SDK will route audio to selectedDevice (SPEAKER, EARPIECE, BLUETOOTH, etc.)
    // update UI to reflect selected device
}

// stop when call ends
audioSwitchHandler.stop()
5) Room event handling: subscribe to remote tracks and maintain map of remote audio tracks
Copy code
val remoteAudioTracks = mutableMapOf<String, RemoteAudioTrack>() // key by track sid or participant id

room.addListener { event ->
    when (event) {
        is RoomEvent.TrackSubscribed -> {
            val track = event.track
            if (track is RemoteAudioTrack) {
                remoteAudioTracks[event.trackSid] = track
                // start playback (SDK handles rendering) and set default volume
                track.setVolume(1.0f)
            }
        }

        is RoomEvent.TrackUnsubscribed -> {
            remoteAudioTracks.remove(event.trackSid)
        }

        is RoomEvent.TrackMuted -> {
            // update UI to show muted state for event.trackSid
        }

        is RoomEvent.TrackUnmuted -> {
            // update UI to show unmuted state
        }

        is RoomEvent.ParticipantConnected -> { /* update participant list */ }
        is RoomEvent.ParticipantDisconnected -> {
            // remove all tracks for that participant
        }
    }
}
6) Per-participant volume UI control
Copy code
// Example: user moves a slider for participant with trackSid
fun onVolumeSliderChanged(trackSid: String, value: Float) {
    remoteAudioTracks[trackSid]?.setVolume(value) // value 0.0 - 1.0
}
7) Unsubscribe from a remote track to save bandwidth
Copy code
// get the publication object (example assumes you have it)
remoteTrackPublication.setSubscribed(false)
8) Handle audio focus and lifecycle • Request audio focus via Android AudioManager when starting the call and abandon on end. • Pause or duck audio on focus loss as appropriate. • Use a foreground service with notification if you must keep audio active while backgrounded. 9) Permissions • Request
RECORD_AUDIO
at runtime before creating microphone track. Notes and tips • The SDK handles native rendering and routing when you use AudioSwitchHandler — you only need to start it and react to device selection. • Use room events (`TrackMuted`/`TrackUnmuted`) to reflect remote participants’ mute state in your UI. • Adjust
RemoteAudioTrack.setVolume
per participant for local playback levels without affecting sender. Would you like a full runnable sample project (Activity + layout + AudioSwitchHandler wiring) or a focused snippet for the device-selection UI? , with interactive elements