ZEGO Express SDK 从 3.0.0 版本起,新增万人范围音视频功能,支持超大规模的范围音视频互动场景。云端服务基于用户位置动态选路,保持虚拟场景沉浸式互动体验的同时大量减少客户音视频成本。 此能力依赖多人状态实时同步服务,根据云端用户位置自动拉取收听范围内的远端音视频并提供空间音效,用户默认拉取距离最近的 12 路(可配置)音视频。单场景内支持 1 万个用户同时开启麦克风及摄像头。
大型虚拟世界中,用户一般不需要感知距离较远的远端用户,ZEGO 提供 AOI(Area Of Interest)能力,减免用户可见范围外的远端音视频信息,减少不必要的用户端流量及性能消耗。
虚拟办公、虚拟会展、开放虚拟世界等虚拟场景。
使用该服务会产生相应的费用,请联系 ZEGO 商务人员了解具体的费用情况。
在实现实时范围音视频前,请确保:
下图为 API 接口调用时序图:
下文详细介绍各 API 接口的对应实现步骤。
调用 createEngine 接口,将申请到到 AppID 和 AppSign 传入参数 “appID” 和 “appSign”,创建引擎单例对象。引擎当前只支持同时创建一个实例,超出后将返回 null。
/** 定义 SDK 引擎对象 */
ZegoExpressEngine engine;
ZegoEngineProfile profile = new ZegoEngineProfile();
/** 请通过官网注册获取,格式为 123456789L */
profile.appID = appID;
/** 64个字符,请通过官网注册获取,格式为"0123456789012345678901234567890123456789012345678901234567890123" */
profile.appSign = appSign;
/** 通用场景接入 */
profile.scenario = ZegoScenario.DEFAULT;
/** 设置app的application 对象 */
profile.application = getApplication();
/** 创建引擎 */
engine = ZegoExpressEngine.createEngine(profile, null);
调用 createRangeScene 接口创建范围场景实例,当前只支持同时创建一个实例,超出后将返回 null。
/** 定义范围场景对象 */
ZegoRangeScene rangeScene;
/** 创建范围场景 */
rangeScene = engine.createRangeScene();
您可以根据需要调用 ZegoRangeSceneStream.setEventHandler 接口分别设置范围场景、范围场景流管理事件回调,用于监听范围场景、范围场景流管理事件回调。
/** 设置范围场景事件回调 */
rangeScene.setEventHandler(new IZegoRangeSceneEventHandler() {
@Override
public void onSceneStateUpdate(ZegoRangeScene rangeScene, ZegoSceneState state, int errorCode) {
super.onSceneStateUpdate(rangeScene, state, errorCode);
}
@Override
public void onEnterView(ZegoRangeScene rangeScene, ZegoUser user, ZegoPosition position) {
super.onEnterView(rangeScene, user, position);
}
@Override
public void onLeaveView(ZegoRangeScene rangeScene, String userID) {
super.onLeaveView(rangeScene, userID);
}
// 无需关注
@Override
public void onUserStatusUpdate(ZegoRangeScene rangeScene, String userID, ZegoPosition position, int channel, byte[] status) {
super.onUserStatusUpdate(rangeScene, userID, position, channel, status);
}
// 无需关注
@Override
public void onUserCommandUpdate(ZegoRangeScene rangeScene, String userID, ZegoPosition position, int channel, byte[] command) {
super.onUserCommandUpdate(rangeScene, userID, position, channel, command);
}
// 无需关注
@Override
public void onCustomCommandUpdate(ZegoRangeScene rangeScene, byte[] command) {
super.onCustomCommandUpdate(rangeScene, command);
}
});
/** 范围场景流管理事件回调 */
rangeScene.getRangeSceneStream().setEventHandler(new IZegoRangeSceneStreamEventHandler() {
@Override
public void onUserStreamStateUpdate(ZegoRangeScene rangeScene, String userID, String streamID, ZegoStreamState state) {
super.onUserStreamStateUpdate(rangeScene, userID, streamID, state);
}
@Override
public void onUserMicUpdate(ZegoRangeScene rangeScene, String userID, ZegoDeviceState state) {
super.onUserMicUpdate(rangeScene, userID, state);
}
@Override
public void onUserCameraUpdate(ZegoRangeScene rangeScene, String userID, ZegoDeviceState state) {
super.onUserCameraUpdate(rangeScene, userID, state);
}
@Override
public void onUserSpeakerUpdate(ZegoRangeScene rangeScene, String userID, ZegoDeviceState state) {
super.onUserSpeakerUpdate(rangeScene, userID, state);
}
});
您可以根据需要调用 setReceiveRange 以及 enableRangeSpatializer 接口设置范围场景参数,控制当前用户音视频的接收范围、设置 3D 音效距离的衰减范围区间 [min, max]、是否开启 3D 音效。
当前用户实际拉流范围受“音视频的接收范围”和“AOI 范围”影响,当远端用户在当前用户的“AOI 范围”内时,假设二者“绝对距离”为 r,“音视频的接受范围”为 R,即当 r < R 时,ZEGO Express SDK 将会主动拉取远端用户的音视频流。
/** 设置拉流最大接收范围 */
int errorCode = rangeScene.getRangeSceneStream().setReceiveRange(reciveRange);
/** (可选)进一步设置 3D 音效的衰减范围区间 [min, max] */
/** 距离小于 min 时,音量不会随着距离的增加而衰减;距离大于 max 时,将无法听到对方的声音 */
ZegoReceiveRangeParam param = new ZegoReceiveRangeParam();
param.min = reciveRangeMin;
param.max = reciveRangeMax;
int errorCode = rangeScene.getRangeSceneStream().setReceiveRange(param);
/** 开启 3D 音效 */
int error = rangeScene.getRangeSceneStream().enableRangeSpatializer(enable);
调用 loginScene 接口,传入场景参数:sceneID
、user
、position
、broadcastMode
,即可登录场景。
/** 登录场景参数 */
ZegoSceneParam param = new ZegoSceneParam();
/** 创建用户 */
ZegoUser user = new ZegoUser(userID, userName);
/** 设置用户的场景坐标、运动朝向、摄像机朝向 */
ZegoPosition position = new ZegoPosition()
for (int i = 0; i < 3; ++i) {
position.coordinate[i] = coordinate[i];
position.motionOrientation.axisForward[i] = rotateMatrixFront[i];
position.motionOrientation.axisRight[i] = rotateMatrixRight[i];
position.motionOrientation.axisUp[i] = rotateMatrixUp[i];
position.cameraOrientation.axisForward[i] = rotateMatrixFront[i];
position.cameraOrientation.axisRight[i] = rotateMatrixRight[i];
position.cameraOrientation.axisUp[i] = rotateMatrixUp[i];
}
/** 设置场景 ID */
param.sceneID = sceneID;
/** (可选)配置模版 ID,若不需要自定义模版,即使用默认的场景配置,无需传此参数*/
param.templateID = templateID;
param.user = user;
param.position = position;
/** 设置用户登录场景的广播模式 */
param.broadcastMode = ZegoBroadcastMode.ALL;
rangeScene.loginScene(param, new IZegoRangeSceneLoginSceneCallback() {
@Override
public void onLoginSceneCallback(int errorCode, ZegoSceneConfig config) {
}
});
如果您需要自定义模板,详情请参考 服务端 API - 场景模版配置。
调用 startPublishingStreamInScene 接口,在场景内推流,如果当前用户在场景内其他用户的音视频的接受范围内,其他用户可以接收当前用户的音视频流。
/** 创建推流到场景配置 */
ZegoScenePublisherConfig scenePublisherConfig = new ZegoScenePublisherConfig();
/** 推流到 rangeScene 登录的场景 */
scenePublisherConfig.rangeSceneHandle = rangeScene.getRangeSceneHandle();
engine.startPublishingStreamInScene(streamID, ZegoPublishChannel.MAIN, scenePublisherConfig);
调用 updateUserPosition 接口,更新当前用户的位置。
/** 设置用户的场景坐标、运动朝向、摄像机朝向 */
ZegoPosition position = new ZegoPosition()
for (int i = 0; i < 3; ++i) {
position.coordinate[i] = coordinate[i];
position.motionOrientation.axisForward[i] = rotateMatrixFront[i];
position.motionOrientation.axisRight[i] = rotateMatrixRight[i];
position.motionOrientation.axisUp[i] = rotateMatrixUp[i];
position.cameraOrientation.axisForward[i] = rotateMatrixFront[i];
position.cameraOrientation.axisRight[i] = rotateMatrixRight[i];
position.cameraOrientation.axisUp[i] = rotateMatrixUp[i];
}
/** 更新用户位置 */
int errorCode = rangeScene.updateUserPosition(position);
调用 logoutScene 接口退出场景。
/** 退出场景 */
rangeScene.logoutScene(new IZegoRangeSceneLogoutSceneCallback() {
@Override
public void onLogoutSceneCallback(int errorCode) {
}
});
当不再使用范围场景模块时,可以调用 destroyRangeScene 接口销毁范围语音模块。
engine.destroyRangeScene(rangeScene);
当不再使用 ZEGO Express SDK 时,可以调用 destroyEngine 销毁引擎。
ZegoExpressEngine.destroyEngine(null);
联系我们
文档反馈