更新记录

1.0.0(2026-05-28)

tsw-maxluyin-uts

tsw-maxluyin-uts 是一个面向 uni-app App 端的 UTS 原生音频插件,服务于本项目里的阿里云实时语音对话场景。插件负责把设备麦克风采集到的 PCM 音频持续回传给 Vue 层,并在 iOS 上承担统一双工音频链路中的原生播放与打断能力。

这份文档同时介绍两部分内容:

  • 插件本身提供了什么能力
  • 当前示例项目如何基于这个插件接入阿里云百炼实时语音模型

1. 插件定位

这个插件不是通用播放器,也不是完整的语音 SDK,它主要解决的是实时语音通话里最麻烦的一段底层能力:

  • 持续采集麦克风音频
  • 输出适合实时上传的 16kHz / 单声道 / PCM16 数据
  • 在 iOS 上把录音和播放收敛到同一套原生双工音频会话里
  • 提供 AI 音频下发、原生播放、播放打断等控制接口

当前源码目录:uni_modules/tsw-maxluyin-uts

2. 项目介绍

本项目是一个 uni-app 实时语音聊天示例,前端页面负责参数配置和通话记录展示,实时会话由组件和原生插件共同完成。

项目当前的整体链路如下:

  • 首页 pages/index/index.vue 负责输入 API Key、地域、模型、音色、VAD 模式和系统提示词
  • components/realtimeChat/realtimeChat.vue 负责 WebSocket 建连、事件分发、上下行音频处理和插话打断
  • tsw-maxluyin-uts 负责原生录音能力;iOS 下还负责统一双工播放链路
  • 云端模型使用阿里云百炼实时模型,例如 qwen3.5-omni-plus-realtime

当前页面层可配置的核心参数包括:

  • 地域:dashscope.aliyuncs.com / dashscope-intl.aliyuncs.com
  • 模型:qwen3.5-omni-plus-realtime
  • 音色:默认 Ethan
  • VAD:semantic_vadserver_vad

3. 适用平台

  • Android
  • iOS
  • HarmonyOS:已保留基础录音接口适配

说明:当前这套实时语音主链路重点围绕 App 端设计,尤其是 iOS 双工音频体验的收敛。

4. 核心能力

4.1 实时录音

插件支持持续采集 PCM 数据,并通过回调把每段音频以 Base64 字符串形式抛给 JS。

音频规格:

  • 采样率:16kHz
  • 声道:单声道
  • 位深:16-bit
  • 编码:PCM
  • 回调格式:Base64 字符串

4.2 iOS 统一双工音频

为了避免实时通话里常见的“录音正常但 AI 无声”或“播放后麦克风失效”问题,iOS 侧当前改成了统一原生双工链路。

这条链路的目标是:

  • 录音和播放共用同一个 AVAudioSession
  • 由原生层统一接收 AI PCM 音频并播放
  • 支持在用户讲话时快速打断 AI 播放

4.3 打断播放

在实时对话中,用户插话时不仅需要前端停止本地播放,还需要尽快中断正在排队的 AI 音频。插件提供了原生播放打断能力,用于和上层的 response.cancel 事件配合。

5. 插件 API

startRecordWithPCM(onPCM)

开始实时录音,并持续返回 Base64 编码后的 PCM 数据。

参数:

  • onPCM: (base64: string) => void

示例:

import * as tswmaxluyinuts from '@/uni_modules/tsw-maxluyin-uts'

tswmaxluyinuts.startRecordWithPCM((base64) => {
    console.log('收到 PCM 数据长度:', base64.length)
})

stopRecordWithPCM()

停止实时录音。

tswmaxluyinuts.stopRecordWithPCM()

startDuplexAudio(onPCM)

启动统一双工音频链路。

当前建议:

  • iOS 实时通话优先使用这个接口
  • Android/HarmonyOS 当前保留兼容实现
tswmaxluyinuts.startDuplexAudio((base64) => {
    // 上传用户麦克风 PCM 到实时模型
})

stopDuplexAudio()

停止统一双工音频链路。

tswmaxluyinuts.stopDuplexAudio()

pushAssistantPCM(base64)

向原生层推送一段 AI 返回的 PCM 音频,用于播放。

tswmaxluyinuts.pushAssistantPCM(base64Audio)

interruptAssistantPlayback()

立即打断当前 AI 播放。

tswmaxluyinuts.interruptAssistantPlayback()

playPCMChunk(base64)

播放单段 PCM 音频。这个接口更偏底层控制,实时对话优先使用 pushAssistantPCM

stopPCMPlayback()

停止 PCM 播放。

6. 在项目中的使用方式

当前项目中的关键引入位置:components/realtimeChat/realtimeChat.vue

// #ifdef APP
import * as tswmaxluyinuts from '@/uni_modules/tsw-maxluyin-uts'
// #endif

推荐接入方式:

  • iOS:用 startDuplexAudio() 采集用户音频,并把 AI 返回音频通过 pushAssistantPCM() 交给原生层播放
  • Android:继续使用实时录音接口,开始通话前先请求麦克风权限
  • 用户插话时:上层先发 response.cancel 给服务端,再调用 interruptAssistantPlayback() 停止本地播放

7. 实时通话工作流

一个完整会话通常按下面顺序运行:

  1. 页面收集 API Key、模型、音色、VAD 等配置
  2. realtimeChat 组件建立到阿里云实时模型的 WebSocket 连接
  3. 原生插件开始采集麦克风 PCM
  4. Vue 层把 PCM 数据分片上传到服务端
  5. 服务端返回文本增量与音频增量
  6. 文本增量展示到页面
  7. 音频增量在 iOS 上经 pushAssistantPCM() 交给原生层播放
  8. 用户插话时,本地中断播放并通知服务端取消当前响应

8. 权限与配置

Android

插件目录中已声明录音权限:uni_modules/tsw-maxluyin-uts/utssdk/app-android/AndroidManifest.xml

项目层仍然建议在开始通话前主动申请权限,当前首页已经这样处理:

  • 权限:android.permission.RECORD_AUDIO
  • 入口:pages/index/index.vue

iOS

项目 manifest.json 已包含麦克风权限描述:

{
  "app-plus": {
    "distribute": {
      "ios": {
        "privacyDescription": {
          "NSMicrophoneUsageDescription": "该应用需要你的麦克风权限,用于实时语音转文字"
        }
      }
    }
  }
}

9. 注意事项

  • 这个插件主要面向实时语音通话,不适合拿来做长时录音文件管理
  • Base64 传输会带来体积膨胀,实时链路里要注意带宽和发送频率
  • iOS 双工音频链路已经改成原生统一方案,但仍建议每次改动后做真机回归
  • 快速结束后立即重开通话时,项目层已经做了约 2s 的重连冷却
  • H5 平台的输入框不要对 inputtextarea 设置 box-sizing: border-box

10. 目录说明

uni_modules/tsw-maxluyin-uts/
├── package.json
├── readme.md
└── utssdk/
    ├── interface.uts
    ├── app-android/
    └── app-ios/

各目录职责:

  • interface.uts:对外声明插件 API
  • app-android:Android 原生录音实现
  • app-ios:iOS 录音、原生播放、统一双工音频实现

11. 当前版本说明

当前插件版本:1.0.0

这一版已经覆盖:

  • App 端 PCM 实时录音
  • iOS 统一双工音频接口
  • AI 音频推送与打断播放接口
  • 与阿里云实时语音聊天示例项目的对接

如果后续继续迭代,建议优先补充:

  • 更完整的错误码说明
  • 真机平台差异说明
  • Android 原生播放链路
  • 自动化测试与回归检查清单

平台兼容性

uni-app(5.07)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × - - - - - - - - - -

uni-app x(5.07)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - - - - -

tsw-maxluyin-uts

tsw-maxluyin-uts 是一个面向 uni-app App 端的 UTS 原生音频插件,服务于本项目里的阿里云实时语音对话场景。插件负责把设备麦克风采集到的 PCM 音频持续回传给 Vue 层,并在 iOS 上承担统一双工音频链路中的原生播放与打断能力。

这份文档同时介绍两部分内容:

  • 插件本身提供了什么能力
  • 当前示例项目如何基于这个插件接入阿里云百炼实时语音模型

1. 插件定位

这个插件不是通用播放器,也不是完整的语音 SDK,它主要解决的是实时语音通话里最麻烦的一段底层能力:

  • 持续采集麦克风音频
  • 输出适合实时上传的 16kHz / 单声道 / PCM16 数据
  • 在 iOS 上把录音和播放收敛到同一套原生双工音频会话里
  • 提供 AI 音频下发、原生播放、播放打断等控制接口

当前源码目录:uni_modules/tsw-maxluyin-uts

2. 项目介绍

本项目是一个 uni-app 实时语音聊天示例,前端页面负责参数配置和通话记录展示,实时会话由组件和原生插件共同完成。

项目当前的整体链路如下:

  • 首页 pages/index/index.vue 负责输入 API Key、地域、模型、音色、VAD 模式和系统提示词
  • components/realtimeChat/realtimeChat.vue 负责 WebSocket 建连、事件分发、上下行音频处理和插话打断
  • tsw-maxluyin-uts 负责原生录音能力;iOS 下还负责统一双工播放链路
  • 云端模型使用阿里云百炼实时模型,例如 qwen3.5-omni-plus-realtime

当前页面层可配置的核心参数包括:

  • 地域:dashscope.aliyuncs.com / dashscope-intl.aliyuncs.com
  • 模型:qwen3.5-omni-plus-realtime
  • 音色:默认 Ethan
  • VAD:semantic_vadserver_vad

3. 适用平台

  • Android
  • iOS
  • HarmonyOS:已保留基础录音接口适配

说明:当前这套实时语音主链路重点围绕 App 端设计,尤其是 iOS 双工音频体验的收敛。

4. 核心能力

4.1 实时录音

插件支持持续采集 PCM 数据,并通过回调把每段音频以 Base64 字符串形式抛给 JS。

音频规格:

  • 采样率:16kHz
  • 声道:单声道
  • 位深:16-bit
  • 编码:PCM
  • 回调格式:Base64 字符串

4.2 iOS 统一双工音频

为了避免实时通话里常见的“录音正常但 AI 无声”或“播放后麦克风失效”问题,iOS 侧当前改成了统一原生双工链路。

这条链路的目标是:

  • 录音和播放共用同一个 AVAudioSession
  • 由原生层统一接收 AI PCM 音频并播放
  • 支持在用户讲话时快速打断 AI 播放

4.3 打断播放

在实时对话中,用户插话时不仅需要前端停止本地播放,还需要尽快中断正在排队的 AI 音频。插件提供了原生播放打断能力,用于和上层的 response.cancel 事件配合。

5. 插件 API

startRecordWithPCM(onPCM)

开始实时录音,并持续返回 Base64 编码后的 PCM 数据。

参数:

  • onPCM: (base64: string) => void

示例:

import * as tswmaxluyinuts from '@/uni_modules/tsw-maxluyin-uts'

tswmaxluyinuts.startRecordWithPCM((base64) => {
    console.log('收到 PCM 数据长度:', base64.length)
})

stopRecordWithPCM()

停止实时录音。

tswmaxluyinuts.stopRecordWithPCM()

startDuplexAudio(onPCM)

启动统一双工音频链路。

当前建议:

  • iOS 实时通话优先使用这个接口
  • Android/HarmonyOS 当前保留兼容实现
tswmaxluyinuts.startDuplexAudio((base64) => {
    // 上传用户麦克风 PCM 到实时模型
})

stopDuplexAudio()

停止统一双工音频链路。

tswmaxluyinuts.stopDuplexAudio()

pushAssistantPCM(base64)

向原生层推送一段 AI 返回的 PCM 音频,用于播放。

tswmaxluyinuts.pushAssistantPCM(base64Audio)

interruptAssistantPlayback()

立即打断当前 AI 播放。

tswmaxluyinuts.interruptAssistantPlayback()

playPCMChunk(base64)

播放单段 PCM 音频。这个接口更偏底层控制,实时对话优先使用 pushAssistantPCM

stopPCMPlayback()

停止 PCM 播放。

6. 在项目中的使用方式

当前项目中的关键引入位置:components/realtimeChat/realtimeChat.vue

// #ifdef APP
import * as tswmaxluyinuts from '@/uni_modules/tsw-maxluyin-uts'
// #endif

推荐接入方式:

  • iOS:用 startDuplexAudio() 采集用户音频,并把 AI 返回音频通过 pushAssistantPCM() 交给原生层播放
  • Android:继续使用实时录音接口,开始通话前先请求麦克风权限
  • 用户插话时:上层先发 response.cancel 给服务端,再调用 interruptAssistantPlayback() 停止本地播放

7. 实时通话工作流

一个完整会话通常按下面顺序运行:

  1. 页面收集 API Key、模型、音色、VAD 等配置
  2. realtimeChat 组件建立到阿里云实时模型的 WebSocket 连接
  3. 原生插件开始采集麦克风 PCM
  4. Vue 层把 PCM 数据分片上传到服务端
  5. 服务端返回文本增量与音频增量
  6. 文本增量展示到页面
  7. 音频增量在 iOS 上经 pushAssistantPCM() 交给原生层播放
  8. 用户插话时,本地中断播放并通知服务端取消当前响应

8. 权限与配置

Android

插件目录中已声明录音权限:uni_modules/tsw-maxluyin-uts/utssdk/app-android/AndroidManifest.xml

项目层仍然建议在开始通话前主动申请权限,当前首页已经这样处理:

  • 权限:android.permission.RECORD_AUDIO
  • 入口:pages/index/index.vue

iOS

项目 manifest.json 已包含麦克风权限描述:

{
  "app-plus": {
    "distribute": {
      "ios": {
        "privacyDescription": {
          "NSMicrophoneUsageDescription": "该应用需要你的麦克风权限,用于实时语音转文字"
        }
      }
    }
  }
}

9. 注意事项

  • 这个插件主要面向实时语音通话,不适合拿来做长时录音文件管理
  • Base64 传输会带来体积膨胀,实时链路里要注意带宽和发送频率
  • iOS 双工音频链路已经改成原生统一方案,但仍建议每次改动后做真机回归
  • 快速结束后立即重开通话时,项目层已经做了约 2s 的重连冷却
  • H5 平台的输入框不要对 inputtextarea 设置 box-sizing: border-box

10. 目录说明

uni_modules/tsw-maxluyin-uts/
├── package.json
├── readme.md
└── utssdk/
    ├── interface.uts
    ├── app-android/
    └── app-ios/

各目录职责:

  • interface.uts:对外声明插件 API
  • app-android:Android 原生录音实现
  • app-ios:iOS 录音、原生播放、统一双工音频实现

11. 当前版本说明

当前插件版本:1.0.0

这一版已经覆盖:

  • App 端 PCM 实时录音
  • iOS 统一双工音频接口
  • AI 音频推送与打断播放接口
  • 与阿里云实时语音聊天示例项目的对接

如果后续继续迭代,建议优先补充:

  • 更完整的错误码说明
  • 真机平台差异说明
  • Android 原生播放链路
  • 自动化测试与回归检查清单

隐私、权限声明

1. 本插件需要申请的系统权限列表:

麦克风权限

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: