Custom Audio Sources - Android
For a high-quality streaming experience, fine-tuning audio tracks becomes essential—especially when delivering content to a broader live audience.
You can provide a custom audio track for a host's stream both before and during a live session.
Custom Audio Track
A custom audio track lets you pick the audio profile, the microphone, and whether noise suppression, echo cancellation, auto gain control and the high-pass filter are on.
How to Create Custom Audio Track ?
-
Create the track with
VideoSDK.createMicrophoneAudioTrack(). Pass the audio profile asencoderConfig. -
The mic opens when the track is created. Call
stop()on the track to release the mic if you don't publish it. -
To capture from a specific microphone, such as a Bluetooth headset, pass its
deviceIdfromVideoSDK.getMics()asmicrophoneId. That microphone is selected when the mic opens, and again when you publish the track withunmuteMic()orchangeMic(). -
It is a
suspendfunction, so call it from a coroutine. It suspends until the mic is open and runs the work on a background thread, so it is safe to call from the main thread. -
It throws
VideoSDKExceptionwhen the track can't be created, for example with3018(ERROR_MICROPHONE_ACCESS_DENIED_OR_DISMISSED) when theRECORD_AUDIOpermission is not granted, or3024(ERROR_MICROPHONE_IN_USE) when the mic won't open or record. The method doesn't ask for the permission, so request it first. -
A mic that fails after the track is created ends the track. Set
onEndedon the track to find out.
Example
lifecycleScope.launch {
try {
val audioCustomTrack = VideoSDK.createMicrophoneAudioTrack(
encoderConfig = CustomMicrophoneTrackConfig.SPEECH_STANDARD, // HIGH_QUALITY | MUSIC_STANDARD, Default : SPEECH_STANDARD
)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Microphone track failed: ${e.code} ${e.name}")
}
}
encoderConfig | Audio | Use it for |
|---|---|---|
SPEECH_LOW_QUALITY | Mono, 16 kHz, 24 kbps | Speech, at a lower sample rate |
SPEECH_STANDARD (default) | Mono, 32 kHz, 24 kbps | Normal voice |
MUSIC_STANDARD | Mono, 48 kHz, 40 kbps | Music, such as songs or instruments |
STANDARD_STEREO | Stereo, 48 kHz, 32 kbps | Stereo sources |
HIGH_QUALITY | Mono, 48 kHz, 32 kbps | Unprocessed audio, where you choose the processing with noiseConfig |
HIGH_QUALITY_STEREO | Stereo, 48 kHz, 32 kbps | Unprocessed stereo audio |
Audio processing with NoiseConfig
-
Pass a
NoiseConfigas thenoiseConfigparameter to turn noise suppression, echo cancellation, auto gain control and the high-pass filter on or off for the track. -
If you pass a
NoiseConfig, it decides every flag. A flag you leave out takes its default:truefornoiseSuppression,echoCancellationandautoGainControl, andfalseforhighPassFilter. Set a flag tonullto keep the value of theencoderConfig. -
If you don't pass one, the
encoderConfigdecides.SPEECH_LOW_QUALITYandSPEECH_STANDARDturn noise suppression, echo cancellation and auto gain control on. The music, stereo and high-quality profiles turn them off.
lifecycleScope.launch {
try {
val audioCustomTrack = VideoSDK.createMicrophoneAudioTrack(
encoderConfig = CustomMicrophoneTrackConfig.HIGH_QUALITY,
// Turns noise suppression on. null keeps the HIGH_QUALITY value of the other flags.
noiseConfig = NoiseConfig(
noiseSuppression = true,
echoCancellation = null,
autoGainControl = null,
highPassFilter = null
),
)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Microphone track failed: ${e.code} ${e.name}")
}
}
How to Setup Custom Audio Track ?
The custom track can be set up both before and after the room is created.
- Setting up a Custom Track during the initialization of a room
- Setting up a Custom Track with methods
1. Setup during live stream initialization
If you're starting the stream with the mic enabled (micEnabled = true) and wish to use a custom track from the beginning, pass it to createRoom() as customMicrophoneTrack.
The track is published when you join only if micEnabled is true. With micEnabled set to false, publish it later by passing it to unmuteMic(), or call stop() on it to release the mic.
Example
override fun onCreate(savedInstanceState: Bundle?) {
//..
lifecycleScope.launch {
val audioCustomTrack = try {
VideoSDK.createMicrophoneAudioTrack(encoderConfig = CustomMicrophoneTrackConfig.HIGH_QUALITY)
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Microphone track failed: ${e.code} ${e.name}")
null
}
// create a new room instance
val liveStream = VideoSDK.createRoom(
roomId = roomId,
token = token,
participantName = participantName,
// If true, it will use the passed custom track to turn mic on
micEnabled = true,
camEnabled = true,
multiStream = false,
// Pass the custom track here
customMicrophoneTrack = audioCustomTrack,
)
}
}
2. Setup dynamically using methods
During the live stream, you can update the audio source by passing the CustomStreamTrack in the unmuteMic() method of Room, while the mic is muted.
You can also pass custom track in changeMic() method of Room, while the mic is on. It turns the mic off and on again with the new track, so onStreamDisabled and then onStreamEnabled fire.
Both are suspend functions, so call them from a coroutine.
unmuteMic() throws VideoSDKException with 3054 (ERROR_ALREADY_IN_REQUESTED_STATE) when the mic is already on. Use changeMic() to switch the track of a mic that is on.
Example
lifecycleScope.launch {
try {
val audioCustomTrack = VideoSDK.createMicrophoneAudioTrack(
encoderConfig = CustomMicrophoneTrackConfig.HIGH_QUALITY,
)
if (liveStream!!.isMicEnabled) {
liveStream!!.changeMic(audioCustomTrack)
} else {
liveStream!!.unmuteMic(audioCustomTrack)
}
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Switching the mic track failed: ${e.code} ${e.name}")
}
}
API Reference
The API references for all the methods and events utilised in this guide are provided below.
Got a Question? Ask us on discord

