Range Audio
Feature Overview
This document does not apply to the Web platform.
Concept Explanation
- Range: The range within which a listener receives audio.
- Orientation: Refers to the position and direction of the listener in the game world coordinates. For details, please refer to
Set 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 Audio, 3D Spatial Audio, and Team Voice.
| Feature | Description |
|---|---|
Range Audio | Listeners in the room have a range limit on the distance for receiving audio. If the distance between the speaker and themselves exceeds this range, they cannot hear the sound. To ensure voice clarity, when more than 20 people nearby are speaking, only the sounds of the 20 speakers closest to them can be heard. Suppose the maximum range for audio reception is set to R, and the distance between the speaker and the listener is r, then:
![]() The above image takes the range audio mode as "World" as an example. For more information about sound reachability under different mode combinations, please refer to Set General Voice Mode. |
| 3D Spatial Audio | Sound has 3D spatial sense and attenuates with distance. |
General Voice Mode | Players can choose to join a team and support freely switching between "World", "Team Only", and "Secret Team" voice modes in the room.
Note
|
Use Cases
The game voice feature is suitable for battle royale games and metaverse scenarios.
In battle royale games, team voice provides team formation functionality. Teams can be changed before and after the game starts. Developers do not need to pay attention to stream grouping and the implementation of publishing and playing, directly implementing team voice functionality.
In battle royale games and metaverse scenarios, 3D spatial audio capability is provided. When listening to speaker sound effects, there is a sense of direction and distance, making the scene feel more realistic.
Download Sample Source Code
Please refer to Download Sample Source Code to get the source code.
For related source code, please check files in the "lib/topics/AudioAdvanced/range_audio" directory.
Prerequisites
Before implementing range audio, ensure:
- You have integrated ZEGO Express SDK in your project and implemented basic real-time audio and video features. For details, please refer to Quick Start - Integrating SDK and Quick Start - Implementing Video Call.
- 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.
Notes
Please pay attention to the following when using the range audio feature to avoid integration issues.
If you are already using the real-time audio and video features of ZEGO Express SDK, please note the following:
- Since the range audio feature module is implemented based on the ZegoExpressEngine's publishing and playing interfaces, you do not need to pay attention to the concept of publishing and playing when using it. In the range audio scenario, the concept of publishing audio stream changes to "enable microphone", and the concept of playing audio stream changes to "enable speaker". It is recommended that you do not use the startPublishingStream and startPlayingStream interfaces for publishing and playing operations while integrating the range audio feature, to avoid effect conflicts.
- The related callbacks for publishing and playing in the range audio feature 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 the game voice feature. Developers can refer to the detailed introduction in the following documentation to implement other related interfaces as needed.
1 Create Engine
Call the createEngineWithProfile interface, pass the applied AppID to the appID parameter, and create an engine singleton object.
/** Obtain through official website registration, format is 123456789 */
int appID = appID;
/** Obtain through official website registration, format is '0123456789012345678901234567890123456789012345678901234567890123' (64 characters in total) */
String appSign = appSign;
/** General scenario access */
ZegoScenario scenario = ZegoScenario.General;
var profile = ZegoEngineProfile(appID, scenario, appSign: appSign);
/** Create engine */
ZegoExpressEngine.createEngineWithProfile(profile);
// When using real-time audio and video SDK for audio-only scenarios, you can disable the camera, which will not require camera permissions and publish video streams
// ZegoExpressEngine.instance.enableCamera(false);2 Create Range Audio Module
Call the createRangeAudio method to create a range audio instance.
var rangAudio = await ZegoExpressEngine.instance.createRangeAudio();
if (rangAudio == null) {
print("Failed to create range audio instance module");
}3 Listen for Range Audio Event Callbacks
You can implement the ZegoExpressEngine.onRangeAudioMicrophoneStateUpdate microphone event callback as needed to listen for notifications of microphone enable status.
// set range audio event handler
ZegoExpressEngine.onRangeAudioMicrophoneStateUpdate = (ZegoRangeAudio rangeAudio, ZegoRangeAudioMicrophoneState state, int errorCode) {
};4 Login Room
After creating a ZegoUser user object by passing in the userID and userName parameters, call the loginRoom interface, pass in the room ID parameter roomID and the user parameter user, and 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 business account system.
- userID cannot be empty, otherwise it will cause room login to fail.
/** Create user */
var user = ZegoUser.id("user1");
/** Start logging in to the room */
ZegoExpressEngine.instance.loginRoom("room1", user);When a user has successfully logged in to the room, if the application exits abnormally, after restarting the application, the developer needs to first call the logoutRoom interface to leave the room, then call the loginRoom interface to log in to the room again.
5 Set Listener's Current Position
Developers can call the updateSelfPosition interface to set their own position and orientation, or update their position and direction in the world coordinate system when their orientation changes.
- If this interface is not called to set position information before calling enableSpeaker to turn on the speaker, they will not be able to receive sounds from anyone other than teammates.
- The coordinate values of the three axes of their own coordinate system can be obtained through the rotation angle conversion matrix of a third-party 3D engine.
| Parameter Name | Description |
| position | The coordinates of oneself in the world coordinate system. The parameter is a float array of length 3, with the three values representing the coordinate values of forward, right, and up. |
| axisForward | The unit vector of the forward axis of one's own coordinate system. The parameter is a float array of length 3, with the three values representing the coordinate values of forward, right, and up. |
| axisRight | The unit vector of the right axis of one's own coordinate system. The parameter is a float array of length 3, with the three values representing the coordinate values of forward, right, and up. |
| axisUp | The unit vector of the up axis of one's own coordinate system. The parameter is a float array of length 3, with the three values representing the coordinate values of forward, right, and up. |

// One's own coordinates in the world coordinate system, in the order of forward, right, and up.
var position = Float32List.fromList(<double>[100.0, 100.0, 100.0]);
// Unit vector of one's own coordinate system's forward direction.
var axisForward = Float32List.fromList(<double>[1.0,0.0,0.0]);
// Unit vector of one's own coordinate system's right direction.
var axisRight = Float32List.fromList(<double>[0.0,1.0,0.0]);
// Unit vector of one's own coordinate system's up direction.
var axisUp = Float32List.fromList(<double>[0.0,0.0,1.0]);
rangAudio?.updateSelfPosition(position, axisForward, axisRight, axisUp);6 Add or Update Speaker Position Information
After successfully logging in to the room, you can 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 reception range and are in World mode. If speaker positions are not set or speakers exceed the listener's range, there will be a situation where sounds cannot be heard.
- Here, speakers refer to other people in the room, and listeners refer to oneself.
- userID: The ID of other speaking users in the room.
- position: The coordinates of the speaker in the world coordinate system. The parameter is a float array of length 3, with the three values representing the coordinate values of forward, right, and up.
// User's coordinates in the world coordinate system, in the order of forward, right, and up.
var position = Float32List.fromList(<double>[100.0, 100.0, 100.0]);
// Add/update user position
rangAudio?.updateAudioSource("abc",position);7 (Optional) Set Audio Reception Range
Call the setAudioReceiveRange interface to set the attenuation range of the listener's audio reception distance. When the distance is less than min, the volume will not attenuate with increasing distance; when the distance is greater than max, the other party's sound cannot be heard.
// Set the attenuation range interval [min, max] for 3D spatial audio
var param = ZegoReceiveRangeParam(0.5, 1.0);
rangeAudio.setAudioReceiveRange(param);Developers can set min to 0 and max to the maximum range of the listener's audio reception distance, that is, taking oneself as the starting point, with the set distance as a three-dimensional space in 3D space. After setting this range, when 3D spatial audio is enabled, the sound will attenuate with increasing distance until it exceeds the set range, at which point there will be no more sound.
// Set the maximum range of audio reception distance. Sounds from audio sources beyond this range will not be heard
var param = ZegoReceiveRangeParam(0, 1000);
rangeAudio.setAudioReceiveRange(param);If the audio reception range is not set, it means only team members' voices can be received, and all sounds outside the team cannot be received. After setting, voice within the team will not be limited by the audio reception range and will not have 3D spatial audio.
8 (Optional) Implement 3D Spatial Audio
Enable 3D Spatial Audio
Call the enableSpatializer interface to set 3D spatial audio. When enable is true, it means 3D spatial audio is enabled. At this time, the audio of non-team members in the room will produce spatial sense changes with changes in the distance and direction of the speaker from themselves. When false, it means 3D spatial audio is disabled. (Can be enabled or disabled at any time)
This feature only takes effect for people outside the team.
rangAudio?.enableSpatializer(true);Set Local Player's 3D Spatial Audio
Developers can use the media player or audio effect player as a sound source and set its position in the world coordinate system. This feature can be applied to playing background music at a designated location in a virtual world scene, giving it a 3D spatial audio effect.
To implement this feature, complete the following steps:
- Call the enableSpatializer interface to enable 3D spatial audio.
- Set the local player's 3D spatial audio
- Media Player:
Please 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:
Please 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 status as
ZegoAudioEffectPlayState.Playing, call the ZegoAudioEffectPlayer.updatePosition interface to set the position of the currently playing audio effect resource in the world coordinate system.
// Enable 3D spatial audio, 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
var mediaPlayerPosition = Float32List.fromList(<double>[100.0, 100.0, 100.0]);
mediaPlayer.updatePosition(mediaPlayerPosition);
// 3. Use media player to load media resources
ZegoMediaPlayerResource resource = ZegoMediaPlayerResource.defaultResource();
resource.loadType = ZegoMultimediaLoadType.FilePath;
resource.filePath = "path";
await mediaPlayer.loadResourceWithConfig(resource);
// 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);
// 3. After receiving [onAudioEffectPlayStateUpdate] callback status as ZegoAudioEffectPlayState.Playing
// Set the audio effect player's position in the world coordinate system
var audioEffectPlayerPosition = Float32List.fromList(<double>[100.0, 100.0, 100.0]);
await 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 the audio stream. When 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 status.
-
Call the enableSpeaker interface to set whether to enable the speaker. When enable is true, it means enabled, and audio streams in the room will be automatically played. When false, it means disabled. (Can be enabled or disabled at any time)
After calling the enableSpeaker interface, when the maximum playing stream limit is exceeded (currently 20 streams), team member audio streams (team mode needs to be set) will be prioritized, then the audio streams closest to oneself in the world range will be played.
// Enable microphone
rangAudio?.enableMicrophone(true);
// Enable speaker
rangAudio?.enableSpeaker(true);10 (Optional) Join Team, 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 audio and 3D spatial audio.
rangAudio?.setTeamID("123");Set General Voice Mode
Call the setRangeAudioMode interface to set the range audio mode (modes can be switched 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 the value 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 other people in World mode within range. |
| Team Only | Team | After setting this mode, this user can only communicate with team members. |
| Secret Team | SecretTeam | After setting this mode, this user can communicate with team members and can only receive voices from people in World mode within range (one-way). |
rangAudio?.setRangeAudioMode(ZegoRangeAudioMode.World);The reachability of speaker voices varies under different range audio modes.
- Assuming user A's mode is "World", the voice reachability of user B under different range audio modes is as follows:
| Same Team | Within Maximum Range | Range Audio Mode | Can A Hear B's Voice | Can B Hear A's Voice |
|---|---|---|---|---|
| Yes | Yes | World (World) | Yes | Yes |
| Team Only (Team) | Yes | Yes | ||
| Secret Team (SecretTeam) | Yes | Yes | ||
| No | World (World) | Yes | Yes | |
| Team Only (Team) | Yes | Yes | ||
| Secret Team (SecretTeam) | Yes | Yes | ||
| No | Yes | World (World) | Yes | Yes |
| Team Only (Team) | No | No | ||
| Secret Team (SecretTeam) | No | Yes | ||
| No | World (World) | No | No | |
| Team Only (Team) | No | No | ||
| Secret Team (SecretTeam) | No | No |
- Assuming user A's mode is "Team Only", the voice reachability of user B under different range audio modes is as follows:
| Same Team | Within Maximum Range | Range Audio Mode | Can A Hear B's Voice | Can B Hear A's Voice |
|---|---|---|---|---|
| Yes | Yes | World (World) | Yes | Yes |
| Team Only (Team) | Yes | Yes | ||
| Secret Team (SecretTeam) | Yes | Yes | ||
| No | World (World) | Yes | Yes | |
| Team Only (Team) | Yes | Yes | ||
| Secret Team (SecretTeam) | Yes | Yes | ||
| No | Yes | World (World) | No | No |
| Team Only (Team) | No | No | ||
| Secret Team (SecretTeam) | No | No | ||
| No | World (World) | No | No | |
| Team Only (Team) | No | No | ||
| Secret Team (SecretTeam) | No | No |
- Assuming user A's mode is "Secret Team", the voice reachability of user B under different range audio modes is as follows:
| Same Team | Within Maximum Range | Range Audio Mode | Can A Hear B's Voice | Can B Hear A's Voice |
|---|---|---|---|---|
| Yes | Yes | World (World) | Yes | Yes |
| Team Only (Team) | Yes | Yes | ||
| Secret Team (SecretTeam) | Yes | Yes | ||
| No | World (World) | Yes | Yes | |
| Team Only (Team) | Yes | Yes | ||
| Secret Team (SecretTeam) | Yes | Yes | ||
| No | Yes | World (World) | Yes | No |
| Team Only (Team) | No | No | ||
| Secret Team (SecretTeam) | No | No | ||
| No | World (World) | No | No | |
| Team Only (Team) | No | No | ||
| Secret Team (SecretTeam) | No | No |
Set Custom Voice Mode
- Custom voice mode and general voice mode cannot be used at the same time.
- If you need to use custom voice mode, please ensure that all online users in the game voice are using Express SDK version 3.3.0 or above.
Through custom voice mode, you can freely control the audio send/receive logic to complete various audio interactions. An example is as follows: Assume A, B, and C are members of the same team, and C is within A's reception 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 B and C at the same time |
| 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 |
rangAudio?.setRangeAudioCustomMode(ZegoRangeAudioSpeakMode.All, ZegoRangeAudioListenMode.All);11 Destroy Range Audio Module
When the range audio module is no longer in use, call the destroyRangeAudio interface to destroy it and release the resources occupied by the range audio module.
ZegoExpressEngine.instance.destroyRangeAudio(rangAudio!);12 Leave Room
Call the logoutRoom interface to leave the room. After leaving, the microphone and speaker will be automatically disabled (i.e., cannot send your own audio or receive other people's audio), and the speaker information list will be cleared.
// Leave room
ZegoExpressEngine.instance.logoutRoom("roomID");FAQ
- How many streams in the reception range can be played simultaneously at most?
To ensure voice clarity, when more than 20 people nearby are speaking, only the sounds of the 20 speakers closest to them can be heard. If there are more than 20 people and the distance is the same, it depends on the order in which each userID is first passed when calling the updateAudioSource interface.
- Does the "range" in range audio refer to the reception range or the speaking range?
The "range" in range audio refers to the reception range.
- Do team members in team voice have 3D spatial audio when co-hosting?
Voice within the team has the effect of normal co-hosting, and currently does not have 3D spatial audio.
- If I am already calling the publishing interface, will there be a conflict when using range audio?
Range audio currently uses the main channel to send audio. If the customer is already using the main channel, there will be a conflict.

