Game Voice
Feature Overview
Concept Explanation
- Range: The range within which a listener receives audio.
- Orientation: Refers to the listener's position and facing direction in the game world coordinates. For details, please refer to
Set the listener's current position. - Listener: A user in the room who receives audio.
- Speaker: A user in the room who sends audio.
Feature Description
Starting from version 2.11.0, ZEGO Express SDK has added a game voice module, mainly including: range voice, 3D audio effects, and team voice.
| Feature | Description |
|---|---|
Range Voice | Listeners in the room have range limitations on the distance at which they can receive audio. If a speaker is beyond that range, they cannot be heard. To ensure voice clarity, when more than 20 people nearby are speaking, only the 20 closest speakers can be heard. Assuming the maximum audio receiving range is set to R, and the distance between the speaker and the listener is r, then:
![]() The above image only takes the range voice mode as "World" as an example. For more sound reachability under different mode combinations, please refer to Set Common Voice Mode. |
| 3D Audio Effects | Sound has 3D spatial sense and attenuates with distance. |
Common Voice Mode | Players can choose to join a team and support freely switching between "World", "Team Only", and "Secret Team" voice modes within the room.
Note
|
Application Scenarios
Game voice features are suitable for battle royale games and metaverse scenarios.
In battle royale games, team voice provides team functionality. Teams can be changed before and after the game starts. Developers do not need to focus on stream grouping and publish/play stream implementation, directly implementing team voice functionality.
In battle royale games and metaverse scenarios, 3D audio effects are provided. When listening to speaker audio effects, there is a sense of direction and distance, making the scene feel more realistic.
Example Source Code Download
Please refer to Download Example Source Code to get the source code.
For related source code, please check the files in the "/ZegoExpressExample/Examples/AdvancedAudioProcessing/RangeAudio" directory.
Prerequisites
Before implementing range voice, please ensure:
- You have created a project in the ZEGOCLOUD Console and applied for a valid AppID and AppSign. For details, please refer to Console - Project Information.
- You have integrated ZEGO Express SDK in your project and implemented basic audio and video publish/play stream functionality. For details, please refer to Quick Start - Integration and Quick Start - Implementation.
Precautions
Please pay close attention to the following precautions when using the range voice feature to avoid integration issues.
If you are already using ZEGO Express SDK's real-time audio and video functionality, please note the following:
- Since the range voice module is implemented based on ZegoExpressEngine's publish/play stream interfaces, you don't need to focus on the concept of publish/play streams when using it. In range voice scenarios, the concept of publishing audio stream becomes "enable microphone", and the concept of playing audio stream becomes "enable speaker". It is recommended not to use startPublishingStream and startPlayingStream interfaces for publish/play stream operations while integrating the range voice feature to avoid effect conflicts.
- Publish/play stream related callbacks in the range voice module (onPublisherStateUpdate, onPlayerStateUpdate, onPublisherQualityUpdate, and onPlayerQualityUpdate) will no longer take effect.
Usage Steps
The above image only shows the core steps and interfaces for implementing game voice functionality. Developers can refer to the detailed introduction in the following documentation according to business needs and implement other related interfaces.
1 Create Engine
Call the createEngine interface, pass the obtained AppID and AppSign into the parameters "appID" and "appSign", and create an engine singleton object. The engine currently only supports creating one instance at a time. Beyond that, it will return null.
/** Define SDK engine object */
ZegoExpressEngine engine;
ZegoEngineProfile profile = new ZegoEngineProfile();
/** Please obtain through official website registration, format is 123456789L */
profile.appID = appID;
/** 64 characters, please obtain through official website registration, format is "0123456789012345678901234567890123456789012345678901234567890123" */
profile.appSign = appSign;
/** General scenario access, please choose the appropriate scenario according to actual situation */
profile.scenario = ZegoScenario.DEFAULT;
/** Set app's application object */
profile.application = getApplication();
/** Create engine */
engine = ZegoExpressEngine.createEngine(profile, null);2 Create Range Voice Module
Call the createRangeAudio method to create a range voice instance.
ZegoRangeAudio rangeAudio = engine.createRangeAudio();
if (rangeAudio == null) {
printf("Failed to create range voice instance module");
}3 Listen to Range Voice Event Callbacks
You can call the setEventHandler interface as needed to set event callbacks for the microphone, used to listen to microphone enable state onRangeAudioMicrophoneStateUpdate notifications.
// set range audio event handler
rangeAudio.setEventHandler(new IZegoRangeAudioEventHandler() {
@Override
public void onRangeAudioMicrophoneStateUpdate(ZegoRangeAudio rangeAudio, ZegoRangeAudioMicrophoneState state, int errorCode) {
super.onRangeAudioMicrophoneStateUpdate(rangeAudio, state, errorCode);
AppLogger.getInstance().callApi("microphone state update. state: %s, errorCode: %d", state, errorCode);
}
});4 Login to Room
After creating a ZegoUser user object by passing in the user ID parameter userID and userName, call the loginRoom interface, passing in the room ID parameter roomID and user parameter user, to log in to the room.
- Within the same AppID, ensure that roomID is globally unique.
- Within the same AppID, ensure that userID is globally unique. It is recommended that developers set it to a meaningful value and associate userID with their own business account system.
- userID cannot be empty, otherwise it will cause room login failure.
/** Create user */
ZegoUser user = new ZegoUser("user1");
/** Start logging in to room */
engine.loginRoom("room1", user);When a user has successfully logged in to a room, if the application exits abnormally, after restarting the application, developers need to first call the logoutRoom interface to exit the room, then call the loginRoom interface to log in to the room again.
5 Set the Listener's Current Position
Developers can call the updateSelfPosition interface to set the listener's own position and orientation, or update their position and facing direction in the world coordinate system when their own orientation changes.
- If this interface is not called to set position information before calling enableSpeaker to enable the speaker, you will not be able to receive sound from anyone other than teammates.
- The coordinate values of the three axes of your own coordinate system can be obtained through the rotation angle conversion matrix of a third-party 3D engine.
| Parameter Name | Description |
| position | Your coordinates in the world coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order. |
| axisForward | The unit vector of the forward axis of your coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order. |
| axisRight | The unit vector of the right axis of your coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order. |
| axisUp | The unit vector of the up axis of your coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order. |

// Your coordinates in the world coordinate system, in the order of front, right, up.
float[] position = new float[]{100.0, 100.0, 100.0};
// Unit vector of your forward facing direction in your coordinate system.
float[] axisForward = new float[]{1.0,0.0,0.0};
// Unit vector of your right facing direction in your coordinate system.
float[] axisRight = new float[]{0.0,1.0,0.0};
// Unit vector of your up facing direction in your coordinate system.
float[] axisUp = new float[]{0.0,0.0,1.0};
rangeAudio.updateSelfPosition(position, axisForward, axisRight, axisUp);6 Add or Update Speaker Position Information
After successfully logging in to the room, you need to call the updateAudioSource interface to add or update speaker position information.
- In World mode: Need to update the positions of the listener and all speakers in the room. In Secret Team mode: Need to update the positions of all speakers in the room who are within the audio receiving range and in World mode. If speaker positions are not set, or if speakers are beyond the listener's range, there will be situations where sound cannot be heard.
- Here, speakers refer to other people in the room, and listeners refer to yourself.
- userID: The ID of other speaking users in the room.
- position: The speaker's coordinates in the world coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order.
// User coordinates in the world coordinate system, in the order of front, right, up.
float[] position = new float[]{100.0, 100.0, 100.0};
// Add/update user position
rangeAudio.updateAudioSource("abc",position);7 (Optional) Set Audio Receiving Range
Call the setAudioReceiveRange interface to set the maximum range at which the listener receives audio distance, that is, taking yourself as the starting point, the set distance as a three-dimensional space in 3D space. After setting this range, when 3D audio effects are enabled, the sound will attenuate as distance increases until it exceeds the set range, at which point there will be no more sound.
// Set the maximum range for audio receiving distance. Sounds beyond this range will not be heard
rangeAudio.setAudioReceiveRange(1000);You can also further control the attenuation range through the setAudioReceiveRange interface. When the distance is less than min, the volume will not attenuate as distance increases; when the distance is greater than max, you will not be able to hear the other party's sound.
// Set the attenuation range interval for 3D audio effects [min, max]
ZegoReceiveRangeParam param = new ZegoReceiveRangeParam();
param.min = reciveRangeMin;
param.max = reciveRangeMax;
rangeAudio.setAudioReceiveRange(param);If the audio receiving distance is not set, it means you can only receive voices from within your own team and cannot receive all sounds outside the team. After setting, voice within the team will not be limited by the audio receiving distance and will not have 3D audio effects.
8 (Optional) Implement 3D Audio Effects
Enable 3D Audio Effects
Call the enableSpatializer interface to set 3D audio effects. When enable is true, it means 3D audio effects are enabled. At this time, the audio of non-team members in the room will produce spatial changes as the speaker's distance and direction from you changes. When it is false, it means 3D audio effects are disabled. (Can be enabled or disabled at any time)
This function only takes effect for people outside the team.
rangeAudio.enableSpatializer(true);Set 3D Audio Effects for Local Players
Developers can use media player or audio effect player as sound sources and set their positions in the world coordinate system. This function can be applied to playing background music at a specified position in a virtual world scene, giving it 3D audio effects.
- Call the enableSpatializer interface to enable 3D audio effects.
- Set 3D audio effects for local players
-
Media Player:
NotePlease refer to Media Player to learn how to create a media player and load media resources.
- Call the createMediaPlayer interface to create a media player.
- Call the ZegoMediaPlayer.updatePosition interface to set the media player's position in the world coordinate system.
- Call the loadResourceWithConfig interface to load media resources.
-
Audio Effect Player:
NotePlease refer to Audio Effect Player to learn how to create an audio effect player and load audio effect resources.
- Call the createAudioEffectPlayer interface to create an audio effect player.
- Call the ZegoAudioEffectPlayer.start interface to play audio effect resources.
- After receiving the onAudioEffectPlayStateUpdate callback with state
ZegoAudioEffectPlayState.Playing, call the ZegoAudioEffectPlayer.updatePosition interface to set the position of the playing audio effect resource in the world coordinate system.
-
// Enable 3D audio effects, this step is a prerequisite
rangeAudio.enableSpatializer(true);
// Set the position of local players
// Media Player
// 1. Create media player
ZegoMediaPlayer mediaPlayer = engine.createMediaPlayer();
// 2. Set the media player's position in the world coordinate system
float [] mediaPlayerPosition = new float[3];
mediaPlayer.updatePosition(mediaPlayerPosition);
// 3. Use media player to load media resources
ZegoMediaPlayerResource resource = new ZegoMediaPlayerResource();
resource.loadType = ZegoMultimediaLoadType.FILE_PATH;
resource.filePath = "path";
mediaPlayer.loadResourceWithConfig(resource, new IZegoMediaPlayerLoadResourceCallback() {
@Override
public void onLoadResourceCallback(int errorCode) {
if (errorCode == 0)
mediaPlayer.start();
}
});
// Audio Effect Player
// 1. Create audio effect player
ZegoAudioEffectPlayer audioEffectPlayer = engine.createAudioEffectPlayer();
// 2. Start playing audio effect resources
int effectSoundID = 1;
String path = "path";
audioEffectPlayer.start(effectSoundID, path, null);
// 3. After receiving [onAudioEffectPlayStateUpdate] callback with state ZegoAudioEffectPlayState.Playing
// Set the audio effect player's position in the world coordinate system
float [] audioEffectPlayerPosition = new float[3];
audioEffectPlayer.updatePosition(effectSoundID, audioEffectPlayerPosition);9 Enable Microphone and Speaker
After successfully logging in to the room:
-
Call the enableMicrophone interface to set whether to enable the microphone. When enable is true, it means enabled, and the SDK will automatically use the main channel to publish audio stream. When it is false, it means disabled. (Can be enabled or disabled at any time)
Developers can listen to the onRangeAudioMicrophoneStateUpdate event callback to get the updated microphone state.
-
Call the enableSpeaker interface to set whether to enable the speaker. When enable is true, it means enabled, and the SDK will automatically pull audio streams within the room. When it is false, it means disabled. (Can be enabled or disabled at any time)
After calling the enableSpeaker interface, when the maximum number of play streams is exceeded (currently 20), it will prioritize pulling team member audio streams (team mode needs to be set), then pull world audio streams closest to your own range.
// Enable microphone
rangeAudio.enableMicrophone(true);
// Enable speaker
rangeAudio.enableSpeaker(true);10 (Optional) Join Team and Set Voice Mode
Join Team
Call the setTeamID interface to set the team ID you want to join as needed (ID can be changed at any time). After setting the ID, you can directly join. After joining a team, communication with teammates in the same team is not limited by range voice and 3D audio effects.
rangeAudio.setTeamID("123");Set Common Voice Mode
Call the setRangeAudioMode interface to set the range voice mode (can switch modes at any time). When the mode parameter is ZegoRangeAudioModeWorld or ZegoRangeAudioSecretTeam, it means you can hear the voices of all people in World mode. When it is ZegoRangeAudioModeTeam, it means you can only hear the voices of other members in the same team.
| Voice Mode | Parameter Value | Feature Description |
|---|---|---|
| World | WORLD | After setting this mode, this user can communicate with team members and can also communicate with people in World mode within range. |
| Team Only | TEAM | After setting this mode, this user can only communicate with team members. |
| Secret Team | SECRET_TEAM | After setting this mode, this user can communicate with team members and can only receive voice from people in World mode within range. |
rangeAudio.setRangeAudioMode(ZegoRangeAudioMode.WORLD);Under different range voice modes, the receivability of speaker voices varies.
- Assuming user A's mode is "World", the sound receivability of user B under different range voice modes is as follows:
| Same Team | Within Maximum Range | Range Voice Mode | Can A Hear B's Voice? | Can B Hear A's Voice? |
|---|---|---|---|---|
| Yes | Yes | World | Yes | Yes |
| Team Only | Yes | Yes | ||
| Secret Team | Yes | Yes | ||
| No | World | Yes | Yes | |
| Team Only | Yes | Yes | ||
| Secret Team | Yes | Yes | ||
| No | Yes | World | Yes | Yes |
| Team Only | No | No | ||
| Secret Team | No | Yes | ||
| No | World | No | No | |
| Team Only | No | No | ||
| Secret Team | No | No |
- Assuming user A's mode is "Team Only", the sound receivability of user B under different range voice modes is as follows:
| Same Team | Within Maximum Range | Range Voice Mode | Can A Hear B's Voice? | Can B Hear A's Voice? |
|---|---|---|---|---|
| Yes | Yes | World | Yes | Yes |
| Team Only | Yes | Yes | ||
| Secret Team | Yes | Yes | ||
| No | World | Yes | Yes | |
| Team Only | Yes | Yes | ||
| Secret Team | Yes | Yes | ||
| No | Yes | World | No | No |
| Team Only | No | No | ||
| Secret Team | No | No | ||
| No | World | No | No | |
| Team Only | No | No | ||
| Secret Team | No | No |
- Assuming user A's mode is "Secret Team", the sound receivability of user B under different range voice modes is as follows:
| Same Team | Within Maximum Range | Range Voice Mode | Can A Hear B's Voice? | Can B Hear A's Voice? |
|---|---|---|---|---|
| Yes | Yes | World | Yes | Yes |
| Team Only | Yes | Yes | ||
| Secret Team | Yes | Yes | ||
| No | World | Yes | Yes | |
| Team Only | Yes | Yes | ||
| Secret Team | Yes | Yes | ||
| No | Yes | World | Yes | No |
| Team Only | No | No | ||
| Secret Team | No | No | ||
| No | World | No | No | |
| Team Only | No | No | ||
| Secret Team | No | No |
Set Custom Voice Mode
- Custom voice mode and common voice mode cannot be used simultaneously.
- If you need to use custom voice mode, please ensure that all online users in game voice use Express SDK version 3.3.0 or higher.
Through custom voice mode, you can freely control audio send/receive logic to complete various audio interactions. An example is as follows: Assuming A, B, and C are members of the same team, and C is within A's receiving range, you can achieve the expected audio experience through the configuration in the table
| User | Speaking Expectation | Listening Expectation | Speaking Mode Configuration | Listening Mode Configuration | Remarks |
|---|---|---|---|---|---|
| A | Send audio to team members and other users within range | Receive audio from team members and other users within range | All | All | A can communicate with both B and C |
| B | Send audio only to team members | Receive audio only from team members | Team | Team | B can only communicate with A |
| C | Send audio only to users within range | Receive audio only from users within range | World | World | C can only communicate with A |
rangeAudio.setRangeAudioCustomMode(ZegoRangeAudioSpeakMode.ALL, ZegoRangeAudioListenMode.ALL);11 Destroy Range Voice Module
When the range voice module is no longer needed, you can call the destroyRangeAudio interface to destroy it and release the resources occupied by the range voice module.
engine.destroyRangeAudio(rangeAudio);12 Exit Room
Call the logoutRoom interface to exit the room. After exiting, the microphone and speaker will be automatically turned off (i.e., you cannot send your own audio or hear other people's audio), and the speaker information list will be cleared.
// Exit room
engine.logoutRoom("roomID");FAQ
- How many streams can be played simultaneously within the listening range at most?
To ensure voice clarity, when more than 20 people nearby are speaking, you can only hear the voices of the 20 closest speakers. If there are more than 20 people and the distance is the same, the order is determined by the order in which each userID was first passed when calling the updateAudioSource interface.
- Does the "range" in range voice refer to the listening range or the speaking range?
The "range" in range voice refers to the listening range.
- Do team members in team voice have 3D audio effects when communicating?
Voice within the team has the effect of normal communication; there are currently no 3D audio effects.
- If I am already calling the publish stream interface, will there be conflicts when using range voice?
Range voice currently uses the main channel to send audio. If the client has already used the main channel, there will be conflicts.

