All Products
Search
Document Center

ApsaraVideo Live:Integrate the voice chat room SDK on Android

Last Updated:Feb 28, 2026

Build a voice chat room on Android using the ApsaraVideo Live ARTC SDK. This guide covers channel creation, role-based access, audio controls, and background music.

Prerequisites

Before you begin, make sure you have:

How it works

A voice chat room uses the ARTC SDK in audio-only mode with role-based access:

  • Streamer (interactive role): Creates the channel, publishes audio, and receives audio from all participants.

  • Viewer (live role): Joins an existing channel and receives audio. Can be promoted to co-streamer through role switching.

Implementation flow:

  1. Configure the channel profile and client role.

  2. Set the audio profile for high-quality music.

  3. Build and encode the authentication token.

  4. Join the channel.

Implementation diagram

Create a channel as a streamer

Initialize the SDK in interactive live mode, set the interactive role, and join the channel. The SDK subscribes to all remote audio streams automatically.

// Set channel profile to interactive live streaming
mAliRtcEngine.setChannelProfile(AliRTCSdkInteractiveLive);
// Set the role to interactive (streamer can publish and receive audio)
mAliRtcEngine.setClientRole(AliRTCSdkInteractive);
// Use high-quality music mode for voice chat scenarios
mAliRtcEngine.setAudioProfile(AliRtcEngineHighQualityMode, AliRtcSceneMusicMode);

// Set the listener for callbacks
mAliRtcEngine.setRtcEngineEventListener(this);
// Auto-publish local audio
mAliRtcEngine.publishLocalAudioStream(true);
// Auto-subscribe to all remote audio streams
mAliRtcEngine.setDefaultSubscribeAllRemoteAudioStreams(true);
mAliRtcEngine.subscribeAllRemoteAudioStreams(true);
// Enable audio-only mode (no video)
mAliRtcEngine.setAudioOnlyMode(true);

// Build the authentication token
JSONObject tokenv2 = new JSONObject();
tokenv2.put("appid", userInfo.appId);
tokenv2.put("channelid", userInfo.channelId);
tokenv2.put("userid", userInfo.userId);
tokenv2.put("nonce", userInfo.nonce);
tokenv2.put("timestamp", userInfo.timestamp);
tokenv2.put("gslb",userInfo.gslb);
tokenv2.put("token", userInfo.token);
String base64TokenV2 = Base64.encodeToString(JSON.toJSONBytes(tokenv2),Base64.NO_WRAP);
// Join the channel with the Base64-encoded token
mAliRtcEngine.joinChannel(base64TokenV2, null, null, mUsername);

Join a channel as a viewer

The viewer uses the same initialization flow as the streamer, except the client role is set to AliRTCSdkLive instead of AliRTCSdkInteractive. This designates the user as an ordinary viewer.

To join as a co-streamer, set the role to AliRTCSdkInteractive.

mAliRtcEngine.setChannelProfile(AliRTCSdkInteractiveLive);
// Set the role to live (ordinary viewer)
mAliRtcEngine.setClientRole(AliRTCSdkLive);
// Use high-quality music mode for voice chat scenarios
mAliRtcEngine.setAudioProfile(AliRtcEngineHighQualityMode, AliRtcSceneMusicMode);

// Set the listener for callbacks
mAliRtcEngine.setRtcEngineEventListener(this);
// Auto-publish local audio
mAliRtcEngine.publishLocalAudioStream(true);
// Auto-subscribe to all remote audio streams
mAliRtcEngine.setDefaultSubscribeAllRemoteAudioStreams(true);
mAliRtcEngine.subscribeAllRemoteAudioStreams(true);
// Enable audio-only mode (no video)
mAliRtcEngine.setAudioOnlyMode(true);

// Build the authentication token
JSONObject tokenv2 = new JSONObject();
tokenv2.put("appid", userInfo.appId);
tokenv2.put("channelid", userInfo.channelId);
tokenv2.put("userid", userInfo.userId);
tokenv2.put("nonce", userInfo.nonce);
tokenv2.put("timestamp", userInfo.timestamp);
tokenv2.put("gslb",userInfo.gslb);
tokenv2.put("token", userInfo.token);
String base64TokenV2 = Base64.encodeToString(JSON.toJSONBytes(tokenv2),Base64.NO_WRAP);
// Join the channel with the Base64-encoded token
mAliRtcEngine.joinChannel(base64TokenV2, null, null, mUsername);

Switch the viewer role

After a viewer joins the channel, switch the role dynamically:

// Switch the role to streamer for a user who has joined the channel
mAliRtcEngine.setClientRole(AliRTCSdkInteractive);

Control volume, voice effects, and reverberation

Adjust volume

// Adjust the local recording volume
mAliRtcEngine.setRecordingVolume(volumeLevel);
// Adjust the volume of a specific remote user
mAliRtcEngine.setRemoteAudioVolume(uid, volume);
// Adjust the playback volume of all sounds
mAliRtcEngine.setPlayoutVolume(volume);

Apply a voice changer

// Apply the "old man" voice changer effect
mAliRtcEngine.setAudioEffectVoiceChangerMode(AliRtcSdk_AudioEffect_Voice_Changer_Oldman);

Apply reverberation

// Configure reverberation by setting room size
mAliRtcEngine.setAudioEffectReverbParamType(AliRtcEngine.AliRtcAudioEffectReverbParamType.AliRtcSdk_AudioEffect_Reverb_Room_Size, value);

Play background music

Two methods are available: raw PCM data input and file-based input.

PCM data input

Create a music input stream, then push raw PCM frames.

Create the external audio stream:

AliRtcEngine.AliRtcExternalAudioStreamConfig config = new AliRtcEngine.AliRtcExternalAudioStreamConfig();
config.sampleRate = sampleRate;
config.channels = channels;
// Local playback volume of the accompaniment (used when the ARTC SDK handles playback)
config.playoutVolume = 60;
// Volume published to remote participants
config.publishVolume = 100;
int externalAudioStreamId = aliRtcEngine.addExternalAudioStream(config);

AliRtcExternalAudioStreamConfig parameters:

ParameterDescription
sampleRateAudio sample rate
channelsNumber of audio channels
playoutVolumeLocal playback volume of the accompaniment
publishVolumeVolume published to remote participants

Push PCM data:

// Build an audio frame with raw PCM data
AliRtcEngine.AliRtcAudioFrame sample = new AliRtcEngine.AliRtcAudioFrame();
sample.data = buffer;
sample.numSamples = numSamples;
sample.numChannels = channels;
sample.sampleRate = sampleRate;
sample.bytesPerSample = bytesPerSample;
// Push the PCM data to the external audio stream
int ret = aliRtcEngine.pushExternalAudioStreamRawData(externalAudioStreamId, sample);

AliRtcAudioFrame fields:

FieldDescription
dataRaw PCM audio buffer
numSamplesNumber of audio samples
numChannelsNumber of audio channels
sampleRateAudio sample rate
bytesPerSampleBytes per audio sample

File-based input

Start accompaniment from a local audio file:

AliRtcEngine.AliRtcAudioAccompanyConfig config = new AliRtcEngine.AliRtcAudioAccompanyConfig();
config.onlyLocalPlay = localPlay;       // Play locally only, without publishing
config.replaceMic = replaceMic;         // Replace microphone input with the file
config.loopCycles = loopCycles;         // Number of playback loops
config.startPosMs = startPosMs;         // Start position in milliseconds
config.publishVolume = pubVolume;       // Volume published to remote participants
config.playoutVolume = playVolume;      // Local playback volume
return mAliRtcEngine.startAudioAccompany(audioFileName, config);

AliRtcAudioAccompanyConfig parameters:

ParameterDescription
onlyLocalPlayPlay locally only, without publishing to remote participants
replaceMicReplace microphone input with the audio file
loopCyclesNumber of playback loops
startPosMsStart position in milliseconds
publishVolumeVolume published to remote participants
playoutVolumeLocal playback volume