Skip to main content
Version: 3.x.x

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 as encoderConfig.

  • 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 deviceId from VideoSDK.getMics() as microphoneId. That microphone is selected when the mic opens, and again when you publish the track with unmuteMic() or changeMic().

  • It is a suspend function, 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 VideoSDKException when the track can't be created, for example with 3018 (ERROR_MICROPHONE_ACCESS_DENIED_OR_DISMISSED) when the RECORD_AUDIO permission is not granted, or 3024 (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 onEnded on 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}")
}
}
encoderConfigAudioUse it for
SPEECH_LOW_QUALITYMono, 16 kHz, 24 kbpsSpeech, at a lower sample rate
SPEECH_STANDARD (default)Mono, 32 kHz, 24 kbpsNormal voice
MUSIC_STANDARDMono, 48 kHz, 40 kbpsMusic, such as songs or instruments
STANDARD_STEREOStereo, 48 kHz, 32 kbpsStereo sources
HIGH_QUALITYMono, 48 kHz, 32 kbpsUnprocessed audio, where you choose the processing with noiseConfig
HIGH_QUALITY_STEREOStereo, 48 kHz, 32 kbpsUnprocessed stereo audio

Audio processing with NoiseConfig​

  • Pass a NoiseConfig as the noiseConfig parameter 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: true for noiseSuppression, echoCancellation and autoGainControl, and false for highPassFilter. Set a flag to null to keep the value of the encoderConfig.

  • If you don't pass one, the encoderConfig decides. SPEECH_LOW_QUALITY and SPEECH_STANDARD turn 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.

  1. Setting up a Custom Track during the initialization of a room
  2. 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.

caution

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.

tip

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