logo
当前页

快速发起语音通话

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

前提条件

示例代码

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

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

整体业务流程

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

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

核心能力实现

集成 ZEGO Express SDK

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

如果包含web平台, 请参考 集成 SDK > 3.4 手动引入 JS文件。

1
进入 android/app/src/main 目录,打开 AndroidManifest.xml 文件,添加权限
AndroidManifest.xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1
Copied!
2
进入 ios/Runner 目录,打开 Info.plist 文件,添加权限
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    ...
    <key>UIBackgroundModes</key>
    <array>
        <string>audio</string>
    </array>
    <key>NSMicrophoneUsageDescription</key>
    <string>需要访问麦克风以进行语音聊天</string>
</dict>
</plist>
1
Copied!
3
进入 ios 目录,打开 Podfile 文件,添加权限
Podfile
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)

    # Start of the permission_handler configuration
    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
        'PERMISSION_MICROPHONE=1',
      ]
    end
    # End of the permission_handler configuration
  end
end
1
Copied!
4
运行时申请麦克风权限
Untitled
import 'package:permission_handler/permission_handler.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  Permission.microphone.request().then((status) {
    runApp(const MyApp());
  });
}
1
Copied!
5
创建并初始化 ZegoExpressEngine
Untitled
await ZegoExpressEngine.createEngineWithProfile(
  /// 设置该场景可以避免申请相机权限,接入方应按自己的业务场景设置具体值
  ZegoEngineProfile(ZegoKey.appId, ZegoScenario.HighQualityChatroom),
);
1
Copied!

通知业务后台开始通话

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

用户进入房间并推流

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

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

说明

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

  • roomID: 由用户自己定义生成规则,会用来登录 Express SDK 的房间。仅支持数字,英文字符 和 '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '`', ';', '’', ',', '.', '<', '>', ''。如果需要与 Web SDK 互通,请不要使用 '%'。
  • userID: 长度不超过32字节。仅支持数字,英文字符 和 '~', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '-', '`', ';', '’', ',', '.', '<', '>', ''。如果需要与 Web SDK 互通,请不要使用 '%'。
  • streamID: 长度不超过256字节。仅支持数字,英文字符 和 '-', '_'。
客户端登录房间并推流
final String _userId = 'user_id_1';
final String _roomId = 'room_id_1';
final String _userStreamId = 'user_stream_id_1';

/// 生成 RTC Token [参考文档](https://doc-zh.zego.im/article/14350)
final token = await getToken();
if (token.isEmpty) {
  return false;
}

/// 下面用来做应答延迟优化的,需要集成对应版本的ZegoExpressEngine sdk,请联系即构同学
ZegoExpressEngine.setEngineConfig(
  ZegoEngineConfig(
    advancedConfig: {
      /**该配置是用来做音量闪避的**/
      'set_audio_volume_ducking_mode': '1',
      /**该配置是用来做播放音量自适用**/
      'enable_rnd_volume_adaptive': 'true'
    },
  ),
);


/// 启用3A
ZegoExpressEngine.instance.enableAGC(true);
ZegoExpressEngine.instance.enableAEC(true);
if (!kIsWeb) {
  ZegoExpressEngine.instance.setAECMode(ZegoANSMode.AIAGGRESSIVE2);

  /// 这个设置只影响AEC(回声消除),我们这里设置为ModeGeneral,是会走我们自研的回声消除,这比较可控,
  /// 如果其他选项,可能会走系统的回声消除,这在iphone手机上效果可能会更好,但如果在一些android机上效果可能不好
  ZegoExpressEngine.instance.setAudioDeviceMode(
    ZegoAudioDeviceMode.General,
  );
}
ZegoExpressEngine.instance.enableANS(true);
ZegoExpressEngine.instance.setANSMode(ZegoANSMode.Medium);

/// 登录房间
final user = ZegoUser(_userId, _userId);
final roomConfig = ZegoRoomConfig.defaultConfig()
  ..isUserStatusNotify = true
  ..token = token;
final loginResult = await ZegoExpressEngine.instance.loginRoom(
  _roomId,
  user,
  config: roomConfig,
);
if (0 != loginResult.errorCode && 1002001 != loginResult.errorCode) {
  return false;
}

/// 开始推流(打开麦克风)
await ZegoExpressEngine.instance.muteMicrophone(false);
await ZegoExpressEngine.instance.startPublishingStream(_userStreamId);
1
Copied!

拉智能体流

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

客户端拉智能体的流
  ZegoExpressEngine.onRoomStreamUpdate = _onRoomStreamUpdate;

  void _onRoomStreamUpdate(
    String roomID,
    ZegoUpdateType updateType,
    List<ZegoStream> streamList,
    Map<String, dynamic> extendedData,
  ) {
    if (updateType == ZegoUpdateType.Add) {
      for (var stream in streamList) {
        ZegoExpressEngine.instance.startPlayingStream(stream.streamID);
      }
    } else if (updateType == ZegoUpdateType.Delete) {
      for (var stream in streamList) {
        ZegoExpressEngine.instance.stopPlayingStream(stream.streamID);
      }
    }
  }
1
Copied!

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

退出房间结束通话

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

Untitled
// 通知业务后台结束通话
Future<Map<String, dynamic>> stopCall() async {
  try {
    final response = await http.post(
      Uri.parse('$_currentBaseUrl/api/stop'),
      headers: {'Content-Type': 'application/json'},
    );

    if (response.statusCode == 200) {
      final json = jsonDecode(response.body);
      return json;
    }
    return {'code': -1, 'message': '请求失败'};
  } catch (e) {
    return {'code': -1, 'message': e.toString()};
  }
}

/// 停止与AI智能体的会话
Future<bool> stop() async {
  stopCall();

  final String _roomId = 'room_id_1';

  final engine = ZegoExpressEngine.instance;

  /// 停止推流
  await engine.stopPublishingStream();

  /// 登出房间
  await engine.logoutRoom(_roomId);

  return true;
}
1
Copied!

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

ZEGO Express SDK 最佳配置实践

为了获得最佳的音频通话体验,建议按照以下最佳实践配置 ZEGO Express SDK。这些配置可以显著提升智能体语音交互的质量。

监听异常回调

注意
由于 LLM 和 TTS 等参数比较多且复杂,在接入测试过程中容易因为参数配置错误导致的智能体不回答或者不说话等各种异常问题。我们强烈建议您在接入测试过程中监听异常回调,并根据回调信息快速排查问题。

Previous

发布日志

Next

展示字幕