logo
当前页

快速开始

本文档用于说明如何快速集成客户端 SDK (ZEGO Express SDK)并实现与智能体进行语音互动。

前提条件

  • 已联系 ZEGO 技术支持获取支持 AI 回声消除的 ZEGO Express SDK,并集成到您的项目中。

示例代码

以下是客户端示例代码,,您可以参考示例代码来实现自己的业务逻辑。

以下视频演示了如何跑通服务端和客户端(Web)示例代码并跟智能体进行语音互动。

整体业务流程

  1. 服务端,参考业务后台快速开始文档跑通业务后台示例代码,部署好业务后台
    • 接入实时互动 AI Agent API 管理智能体。
  2. 客户端,跑通示例代码
    • 通过业务后台创建和管理智能体。
    • 集成 ZEGO Express SDK 完成实时通信。

完成以上两个步骤后即可实现将智能体加入房间并与真实用户进行实时互动。

sequenceDiagram participant 客户端 participant 业务后台 participant AI Agent 后台 业务后台->>业务后台: 注册智能体 业务后台->>AI Agent 后台: 注册智能体 AI Agent 后台-->>业务后台: 客户端->>业务后台: 通知业务后台开始通话 业务后台->>AI Agent 后台: 创建智能体实例 AI Agent 后台->>AI Agent 后台: 智能体登录房间并推流、拉用户流 AI Agent 后台-->>业务后台: 业务后台-->>客户端: 客户端->业务后台: 请求 Token 业务后台-->>客户端: Token 客户端->>客户端: 初始化 ZEGO Express SDK 后登录房间并推流 客户端->>客户端: 用户拉智能体流 客户端->>业务后台: 通知业务后台停止通话 业务后台->>AI Agent 后台: 删除智能体实例 AI Agent 后台-->>业务后台: 业务后台-->>客户端: 客户端->>客户端: 用户停止推流并退出房间

核心能力实现

集成 ZEGO Express SDK

请参考 集成 SDK > 2.2 > 方式2 手动集成 SDK。集成 SDK 后按以下步骤初始化 ZegoExpressEngine。

1
添加权限声明

进入 “app/src/main” 目录,打开 “AndroidManifest.xml” 文件,添加权限。

AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 
1
Copied!
2
运行时申请录音权限
Untitled
private final ActivityResultLauncher<String> requestPermissionLauncher = registerForActivityResult(
    new ActivityResultContracts.RequestPermission(), new ActivityResultCallback<Boolean>() {
        @Override
        public void onActivityResult(Boolean isGranted) {
            if (isGranted) {
                // 同意权限
            }
        }
    });
//发起请求
requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO);
1
Copied!
3
创建并初始化 ZegoExpressEngine
Untitled
ZegoEngineProfile zegoEngineProfile = new ZegoEngineProfile();
zegoEngineProfile.appID = KeyCenter.appID;
zegoEngineProfile.scenario = ZegoScenario.HIGH_QUALITY_CHATROOM;
zegoEngineProfile.application = getApplication();
ZegoExpressEngine.createEngine(zegoEngineProfile, null);
1
Copied!

通知业务后台开始通话

可在客户端真实用户进入房间后立即通知业务后台开始通话,异步调用可加降低通话接通时间。业务后台收到开始通话通知后,使用与客户端相同的 roomID 及关联的 userID 和 streamID 创建智能体实例,这样智能体就能与真实用户在同一个房间内进行相互推拉流实现语音互动。

用户进入房间并推流

真实用户登录房间后推流。

说明

在此场景下需要开启 AI 回声消除以获得更好的效果。

登录用的 token 需要从您的业务后台获取,请参考完整示例代码。

说明

请确保 roomID、userID、streamID 在一个 ZEGO APPID 下是唯一的。

  • roomID: 由用户自己定义生成规则,会用来登录 Express SDK 的房间。仅支持数字,英文字符 和 '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '`', ';', '’', ',', '.', '<', '>', ''。如果需要与 Web SDK 互通,请不要使用 '%'。
  • userID: 长度不超过32字节。仅支持数字,英文字符 和 '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '`', ';', '’', ',', '.', '<', '>', ''。如果需要与 Web SDK 互通,请不要使用 '%'。
  • streamID: 长度不超过256字节。仅支持数字,英文字符 和 '-', '_'。
客户端登录房间并推流
private void loginRoom(String agentId, String userId, String userName, String token,
    IZegoRoomLoginCallback callback) {
    ZegoEngineConfig config = new ZegoEngineConfig();
    HashMap<String, String> advanceConfig = new HashMap<String, String>();
    advanceConfig.put("set_audio_volume_ducking_mode", "1");
    advanceConfig.put("enable_rnd_volume_adaptive", "true");
    config.advancedConfig = advanceConfig;
    ZegoExpressEngine.setEngineConfig(config);
    ZegoExpressEngine.getEngine().setRoomScenario(ZegoScenario.HIGH_QUALITY_CHATROOM);
    ZegoExpressEngine.getEngine().setAudioDeviceMode(ZegoAudioDeviceMode.GENERAL);

    // 开启 AI 回声消除
    ZegoExpressEngine.getEngine().enableAEC(true);
    ZegoExpressEngine.getEngine().setAECMode(ZegoAECMode.AI_AGGRESSIVE2);
    ZegoExpressEngine.getEngine().enableAGC(true);
    ZegoExpressEngine.getEngine().enableANS(true);
    ZegoExpressEngine.getEngine().setANSMode(ZegoANSMode.MEDIUM);

    ZegoRoomConfig roomConfig = new ZegoRoomConfig();
    roomConfig.isUserStatusNotify = true;
    roomConfig.token = token;

    String roomId = generateRoomID(agentId);
    ZegoExpressEngine.getEngine()
        .loginRoom(roomId, new ZegoUser(userId, userName), roomConfig, (errorCode, extendedData) -> {
            Timber.d(
                "loginRoom() called with: errorCode = [" + errorCode + "], extendedData = [" + extendedData + "]");
            if (errorCode == 0) {
                String userSteamID = generateUserStreamID(agentId, userId);
                ZegoExpressEngine.getEngine().startPublishingStream(userSteamID);
                ZegoExpressEngine.getEngine().muteMicrophone(false);
            }
            if (callback != null) {
                callback.onRoomLoginResult(errorCode, extendedData);
            }

        });
}
1
Copied!

拉智能体流

默认只有一个真实用户及智能体在同一个房间内,所以拉流时默认新增的就是智能体流。

客户端拉智能体的流
// 监听回调
void setEventHandler() {
        engine.setEventHandler(new IZegoEventHandler() {
            @Override
            // 房间内其他用户推流/停止推流时,我们会在这里收到相应用户的音视频流增减的通知
            public void onRoomStreamUpdate(String roomID, ZegoUpdateType updateType, ArrayList<ZegoStream> streamList, JSONObject extendedData) {
                super.onRoomStreamUpdate(roomID, updateType, streamList, extendedData);
                //当 updateType 为 ZegoUpdateType.ADD 时,代表有音视频流新增,此时我们可以调用 startPlayingStream 接口拉取播放该音视频流
                if (updateType == ZegoUpdateType.ADD) {
                    // 开始拉流,设置远端拉流渲染视图,视图模式采用 SDK 默认的模式,等比缩放填充整个 View
                    ZegoStream stream = streamList.get(0);
                    // 默认新增是智能体流,直接拉流
                    // 如下 remoteUserView 为 UI 界面上的 TextureView.
                    ZegoCanvas playCanvas = new ZegoCanvas(findViewById(R.id.remoteUserView));
                    ZegoExpressEngine.getEngine().startPlayingStream(stream.streamID, playCanvas);
                }
            }
        });
}
1
Copied!

恭喜你🎉!完成这一步骤后,您已经可以用语音问智能体任何问题,智能体都会用语音回答您的问题!

退出房间结束通话

客户端调用退出登录接口退出房间,并停止推拉流。同时通知业务后台本次通话结束。业务后台收到结束通话通知后会删除智能体实例,智能体实例会自动退出房间并停止推拉流。这样一次完整的互动就结束了。

Untitled
// 通知业务后台结束通话
private void stop() {
    RequestBody body = RequestBody.create("", MediaType.parse("application/json; charset=utf-8"));
    Request request = new Request.Builder().url(YOUR_SERVER_URL + "/api/stop").post(body).build();

    new OkHttpClient.Builder().build().newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {

        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            if (response.isSuccessful()) {
                // 退出房间
                ZegoExpressEngine.getEngine().logoutRoom();
            }
        }
    });
}

1
Copied!

以上就是您实现与智能体进行实时语音互动的完整核心流程。

Previous

发布日志

Next

展示字幕