通过 AOQ 接入 fun-asr-realtime,发送麦克风音频并实时接收语音识别结果。客户端代码以 Android Java 为例,AOQ 支持的其他平台使用相同的接口。
方案概述
fun-asr-realtime 将音频流实时转写为带标点的文本。AOQ SDK 将媒体和事件分轨传输:客户端通过 Audio 轨上行音频,通过 Data 轨发送控制事件并接收识别事件。该模型使用 Inference 事件协议,而不是 Realtime 事件协议。
该方案适用于实时字幕、会议转写、语音输入和智能助手。Audio 轨避免客户端把音频编码成事件消息,Data 轨则保留 run-task、result-generated 和 finish-task 等完整任务语义。
- 客户端向业务 AppServer 请求临时 AOQ 连接凭证。
- AppServer 使用 API Key 向千问AI平台申请 Token,并把连接字段返回客户端。
- 客户端建立 AOQ 连接并发送 run-task;收到 task-started 后开始上行麦克风音频。
- 服务端持续返回 result-generated;客户端发送 finish-task 后等待最终结果和 task-finished。
准备工作
- 开通千问AI平台,并按获取与配置 API Key获取 API Key。API Key 只保存在业务 AppServer,不要写入客户端代码或提交到代码仓库。
- 根据业务部署地域确认 AOQ Endpoint。地域和接入地址的选择方法请参见选择地域、服务部署范围和接入域名。
- 从SDK 下载获取最新版 AOQ Client SDK。本文传输 PCM 音频,不需要额外集成 Opus 插件。
- 搭建业务 AppServer,并按Token 鉴权实现 AOQ Inference 协议的服务端代理鉴权。每次建立新连接前,客户端都应从 AppServer 获取新的连接凭证。
导入 SDK
根据开发平台选择相应的 SDK 导入方式。后续客户端实现以 Android Java 为例;其他平台使用相同的接口设计和事件流程。
- Android
- iOS
- HarmonyOS
- Linux (Python)
- 将 AoqClientSdk-release.aar 放入 app/libs 目录,并在 app/build.gradle 中配置依赖和 ABI:
- 在 AndroidManifest.xml 中声明网络和录音权限:
- 在开始录音前动态申请 RECORD_AUDIO 权限。纯语音识别不需要 CAMERA 权限。
体验 Demo
千问AI平台提供适用于 Android 平台的 Demo,可用于快速验证 AOQ 接入效果。下载 APK 并配置 API Key 和 workspaceId 后,即可体验部分模型。
扫描以下二维码下载 Demo:

实现流程
- AppServer 使用 Inference Token 地址获取 fun-asr-realtime 的 AOQ 连接参数。
- 客户端把 Token 响应转换为 AoqConnectConfig,发布 Audio 和 Data 轨,并订阅 Data 轨。
- 客户端按业务需求和模型要求配置音频编码参数,启动麦克风采集但暂不发送音频,然后建立 AOQ 连接。
- 连接成功后发送 run-task;收到 task-started 后开启 Audio 轨发送。
- 客户端在 onDataMsg 中处理 result-generated;结束录音时先关闭 Audio 轨发送,再发送 finish-task。
- 收到 task-finished 后,可在同一连接上使用新的 task_id 发起下一轮识别,或断开连接并销毁引擎。

AppServer 获取 Token
在 AppServer 设置 DASHSCOPE_API_KEY,并使用所选地域的 Endpoint 发送请求。clientIp 为终端的真实公网 IP;该字段可选,但建议传入,以便服务分配合适的 Relay 接入点。
如果 AppServer 无法获取终端真实公网 IP,请从请求体中删除 clientIp 字段,不要传空字符串。
| 响应字段 | SDK 字段 |
|---|---|
| aoqTokenForClient | AoqConnectConfig.token |
| sid | AoqConnectConfig.sid |
| clientRelayCertFingerprint | AoqConnectConfig.certFingerprint |
| clientRelayEndpoints | AoqConnectConfig.relayEndpoints |
| extraInfo.workspaceIdHash | AoqConnectConfig.workspaceIdHash |
实现 Android 客户端
以下步骤按连接和任务的实际执行顺序拆分 Android Java 客户端代码。各片段来自后文的完整示例。
1. 创建引擎并设置回调
创建 AOQ 客户端引擎,并注册连接状态和 Data 轨事件回调。请根据业务逻辑实现回调处理;连接成功后再启动识别任务。
2. 配置音频编码
配置发送给模型的音频编码。请根据业务需求和模型要求设置格式、采样率和声道数。以下代码以 16 kHz 单声道 PCM 为例;支持范围请参见客户端事件中的 run-task 参数。
3. 配置连接和传输轨道
使用 AppServer 返回的凭证配置 AOQ 连接,并根据业务需要选择发布和订阅的轨道。以下代码为实时语音识别发布 Audio 和 Data 轨,并订阅 Data 轨。
4. 启动音频采集并建立连接
配置音频采集方式并建立 AOQ 连接。请根据业务选择内置或外部采集、是否启用 VoIP 模式以及声道数。收到 task-started 前保持 Audio 轨发送关闭。
5. 启动识别任务
连接成功后生成任务 ID,并发送 run-task 启动识别。请根据实际使用的模型和音频输入配置 model、format、sample_rate 及其他任务参数,完整说明请参见客户端事件。
6. 处理服务端事件
处理任务状态、识别结果和错误事件,并将结果传递给业务层。请根据应用的展示和状态管理需求实现回调逻辑;收到 task-started 后再发送音频,展示结果时过滤心跳事件。完整响应结构请参见服务端事件。
7. 结束识别任务
用户结束本轮录音时,停止音频上行并发送 finish-task。保持连接直至收到最终识别结果和 task-finished;后续可按业务需要启动新任务或释放连接。事件格式请参见客户端事件。
8. 断开连接并销毁引擎
页面销毁或不再需要识别时,释放音频采集、AOQ 连接和引擎资源。请根据应用生命周期决定释放时机,不要在刚发送 finish-task 时立即释放。
完整示例
该 Android Java 类将 AppServer 返回的 JSON 转换为 AoqConnectConfig,并组合前述连接、采集、任务和资源释放逻辑。
AsrClient.java 完整代码
AsrClient.java 完整代码
调用示例
将 AppServer 的 Token 响应传给 parseConnectConfig,然后创建客户端。首次连接成功后自动开始识别。停止按钮只结束当前任务;页面销毁时才释放连接和本地资源。
运行并验证
- 启动 AppServer,确认 Token 请求返回 HTTP 200,并包含 sid、aoqTokenForClient、clientRelayEndpoints、clientRelayCertFingerprint 和 extraInfo.workspaceIdHash。
- 在 Android 设备上安装并运行应用,授予麦克风权限,然后说一段话。
- 观察回调。正常事件顺序如下:
典型场景
同一连接多次识别
收到 task-finished 后调用 beginRecognition,可在同一 AOQ 连接上启动下一轮识别。每轮任务必须使用新的 task_id,不需要重新申请 Token 或重建连接;如果连接已经断开,则需要重新获取连接凭证。
Android 后台识别
Android 10 及以上版本中,如需在应用进入后台后继续采集麦克风音频,应使用 foregroundServiceType=microphone 的前台服务,并在应用仍对用户可见时启动该服务。
常见问题
| 问题 | 处理方法 |
|---|---|
| 连接失败 | 确认 Token 尚未过期、Endpoint 与业务地域一致,并检查 AppServer 是否传入了终端真实公网 IP。连接断开后不要复用旧 Token。 |
| 任务已启动但没有识别结果 | 确认收到 task-started 后才开启 Audio 轨发送,并根据当前模型的客户端事件检查音频格式、采样率等输入参数。 |
| 收不到最终结果 | 先关闭 Audio 轨发送,再发送 finish-task;等待最终 result-generated 和 task-finished,不要立即断开连接。 |
| Android 加载 SDK 失败 | 确认 AAR 已加入依赖,并且应用只打包 SDK 支持的 armeabi-v7a 或 arm64-v8a ABI。 |
| 同一连接的下一轮任务被拒绝 | 确认上一轮已经收到 task-finished,并为新一轮 run-task 生成新的 task_id。 |