Mass-Scale Range Audio and Video
Feature Overview
Starting from version 3.0.0, ZEGO Express SDK has added mass-scale range audio and video functionality, supporting ultra-large-scale range audio/video interaction scenarios. The cloud service dynamically selects routes based on user locations, significantly reducing customer audio/video costs while maintaining an immersive interactive experience in virtual scenes.
This capability relies on the real-time multi-user status synchronization service. Based on cloud user locations, it automatically plays remote audio/video within the listening range and provides spatial audio effects. Users by default play the closest 12 streams (configurable). A single scene supports up to 10,000 users simultaneously enabling microphones and cameras.
In large virtual worlds, users generally do not need to perceive remote users who are far away. ZEGOCLOUD provides AOI (Area Of Interest) capability to eliminate remote audio/video information outside the user's visible range, reducing unnecessary client-side traffic and performance consumption.

Concept Explanation
- Scene: Users need to log in to a scene first. Only users who enter the same scene can conduct range audio/video calls and use the real-time multi-user status synchronization service.
- Listening range: The receiving range of the local user's audio/video. The local user automatically plays audio/video from remote users within the listening range.
- AOI (Area of interest) range: The area of interest to the user (square), generally the user's visible range in a virtual scene. This range follows the user's position in real-time and only receives audio/video information, network status, device status, etc., from remote users within the AOI range.
Application Scenarios
Virtual offices, virtual exhibitions, open virtual worlds, and other virtual scenarios.
Prerequisites
Using this service will incur corresponding fees. Please contact ZEGOCLOUD business personnel to learn about specific fee details.
Before implementing real-time range audio/video, ensure that:
- You have contacted ZEGOCLOUD Technical Support for special packaging and enabled the mass-scale range audio/video service.
- You have integrated the ZEGO Express SDK into your project.
- You have created a project in the ZEGOCLOUD Console and applied for a valid AppID and AppSign. For details, see Console - Project Management.
Implementation Flow
The following figure shows the API interface call sequence diagram:
The following sections describe in detail the implementation steps for each API interface.
1 Create Engine
Call the createEngineWithProfile interface, pass the applied 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.
ZegoEngineProfile *profile = [[ZegoEngineProfile alloc] init];
/** Please obtain through official website registration, format: 123456789 */
profile.appID = appID;
/** 64 characters, please obtain through official website registration, format: "0123456789012345678901234567890123456789012345678901234567890123" */
profile.appSign = appSign;
/** General scenario access */
profile.scenario = ZegoScenarioDefault;
/** Create engine and register self as eventHandler callback. If you don't need to register callback, the eventHandler parameter can be nil. You can call "-setEventHandler:" method later to set callback */
[ZegoExpressEngine createEngineWithProfile:profile eventHandler:self];2 Create Range Scene Module
Call the createRangeScene interface to create a range scene instance. Currently only one instance can be created at a time. Beyond that, it will return null.
/** Define range scene object */
ZegoRangeScene *rangeScene;
/** Create range scene */
rangeScene = [[ZegoExpressEngine sharedEngine] createRangeScene];3 Listen to Range Scene Event Callbacks
You can call the ZegoRangeSceneStream.setEventHandler interface as needed to set range scene and range scene stream management event callbacks respectively, used for listening to range scene and range scene stream management event callbacks.
/** Set range scene event callback */
[rangeScene setEventHandler:self];
/** Range scene stream management event callback */
[[rangeScene getRangeSceneStream] setEventHandler:self];4 Set Range Scene Stream Management Parameters
You can call the setReceiveRange, setReceiveRangeWithParam, and enableRangeSpatializer interfaces as needed to set range scene parameters, controlling the current user's audio/video receiving range, setting the attenuation range interval [min, max] for 3D audio effects distance, and whether to enable 3D audio effects.
The actual stream playing range of the current user is affected by the "audio/video receiving range" and "AOI range". When a remote user is within the current user's "AOI range", assuming the "absolute distance" between the two is r and the "audio/video receiving range" is R, i.e., when r < R, ZEGO Express SDK will actively play the remote user's audio/video stream.
/** Set maximum receiving range for playing streams */
int errorCode = [[rangeScene getRangeSceneStream] setReceiveRange:reciveRange];
/** (Optional) Further set the attenuation range interval [min, max] for 3D audio effects */
/** When the distance is less than min, the volume will not attenuate as the distance increases; when the distance is greater than max, you will not be able to hear the other party's sound */
ZegoReceiveRangeParam *param = [[ZegoReceiveRangeParam alloc] init];
param.min = reciveRangeMin;
param.max = reciveRangeMax;
int errorCode = [[rangeScene getRangeSceneStream] setReceiveRangeWithParam:param];
/** Enable 3D audio effects */
int error = [[rangeScene getRangeSceneStream] enableRangeSpatializer:enable];5 Login to Scene
Call the loginScene interface, pass in scene parameters: sceneID, user, position, broadcastMode, to log in to the scene.
- 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 logging in to the scene will fail.
/** Login scene parameters */
ZegoSceneParam *param = [[ZegoSceneParam alloc] init];
/** Create user */
ZegoUser *user = [[ZegoUser alloc] initWithUserID:userID userName:userName];
/** Set user's scene coordinates, motion orientation, and camera orientation */
ZegoPosition *position = [[ZegoPosition alloc] init];
ZegoPositionOrientation *motionOrientation = [[ZegoPositionOrientation alloc] init];
ZegoPositionOrientation *cameraOrientation = [[ZegoPositionOrientation alloc] init];
motionOrientation.axisForward = [NSArray arrayWithObjects:rotateMatrixForward[0], rotateMatrixForward[1], rotateMatrixForward[2], nil];
motionOrientation.axisRight = [NSArray arrayWithObjects:rotateMatrixRight[0], rotateMatrixRight[1], rotateMatrixRight[2], nil];
motionOrientation.axisUp = [NSArray arrayWithObjects:rotateMatrixUp[0], rotateMatrixUp[1], rotateMatrixUp[2], nil];
cameraOrientation.axisForward = [NSArray arrayWithObjects:rotateMatrixForward[0], rotateMatrixForward[1], rotateMatrixForward[2], nil];
cameraOrientation.axisRight = [NSArray arrayWithObjects:rotateMatrixRight[0], rotateMatrixRight[1], rotateMatrixRight[2], nil];
cameraOrientation.axisUp = [NSArray arrayWithObjects:rotateMatrixUp[0], rotateMatrixUp[1], rotateMatrixUp[2], nil];
position.coordinate = [NSArray arrayWithObjects:coordinate[0], coordinate[1], coordinate[2], nil];
position.motionOrientation = motionOrientation;
position.cameraOrientation = cameraOrientation;
/** Set scene ID */
param.sceneID = sceneID;
/** (Optional) Configure template ID. If you don't need custom templates, i.e., use default scene configuration, you don't need to pass this parameter */
param.templateID = templateID;
param.user = user;
param.position = position;
/** Set user's broadcast mode when logging in to the scene */
param.broadcastMode = ZegoBroadcastModeAll;
[rangeScene loginScene:param callback:^(int errorCode, ZegoSceneConfig * _Nonnull config) {}];If you need to customize templates, please refer to Server API - Scene Template Configuration.
6 Publish Stream to Scene
Call the startPublishingStreamInScene interface to publish stream within the scene. If the current user is within the audio/video receiving range of other users in the scene, other users can receive the current user's audio/video stream.
/** Create publish to scene configuration */
ZegoScenePublisherConfig *scenePublisherConfig = [[ZegoScenePublisherConfig alloc] init];
/** Publish to the scene logged in by rangeScene */
scenePublisherConfig.rangeSceneHandle = [rangeScene getRangeSceneHandle];
[[ZegoExpressEngine sharedEngine] startPublishingStreamInScene:streamID channel:ZegoPublishChannelMain config:scenePublisherConfig];7 Update User Position
Call the updateUserPosition interface to update the current user's position.
/** Set user's scene coordinates, motion orientation, and camera orientation */
ZegoPosition *position = [[ZegoPosition alloc] init];
ZegoPositionOrientation *motionOrientation = [[ZegoPositionOrientation alloc] init];
ZegoPositionOrientation *cameraOrientation = [[ZegoPositionOrientation alloc] init];
motionOrientation.axisForward = [NSArray arrayWithObjects:rotateMatrixForward[0], rotateMatrixForward[1], rotateMatrixForward[2], nil];
motionOrientation.axisRight = [NSArray arrayWithObjects:rotateMatrixRight[0], rotateMatrixRight[1], rotateMatrixRight[2], nil];
motionOrientation.axisUp = [NSArray arrayWithObjects:rotateMatrixUp[0], rotateMatrixUp[1], rotateMatrixUp[2], nil];
cameraOrientation.axisForward = [NSArray arrayWithObjects:rotateMatrixForward[0], rotateMatrixForward[1], rotateMatrixForward[2], nil];
cameraOrientation.axisRight = [NSArray arrayWithObjects:rotateMatrixRight[0], rotateMatrixRight[1], rotateMatrixRight[2], nil];
cameraOrientation.axisUp = [NSArray arrayWithObjects:rotateMatrixUp[0], rotateMatrixUp[1], rotateMatrixUp[2], nil];
position.coordinate = [NSArray arrayWithObjects:coordinate[0], coordinate[1], coordinate[2], nil];
position.motionOrientation = motionOrientation;
position.cameraOrientation = cameraOrientation;
/** Update user position */
int errorCode = [rangeScene updateUserPosition:position];8 Logout from Scene
Call the logoutScene interface to log out from the scene.
/** Logout from scene */
[rangeScene logoutScene:^(int errorCode) {}];9 Destroy Range Scene Module
When the range scene module is no longer needed, you can call the destroyRangeScene interface to destroy the range audio module.
[[ZegoExpressEngine sharedEngine] destroyRangeScene:rangeScene];10 Destroy Engine
When the ZEGO Express SDK is no longer needed, you can call destroyEngine to destroy the engine.
[ZegoExpressEngine destroyEngine:nil];