> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/troubleshooting/audio-and-microphone-issues.md).

# 音频和麦克风问题

修复所有 Convai Unity SDK 平台上的麦克风输入失败和角色语音播放问题，包括 Android、iOS 和 WebGL。

Convai Unity SDK 中的音频故障分为两类：阻止 SDK 捕获玩家语音的麦克风输入问题，以及阻止角色语音播放的音频输出问题。两类问题都会产生特定的错误代码和控制台消息，直接指向原因。本页涵盖这两类问题，并提供 Android、iOS 和 WebGL 的平台特定指导。

### 一线检查

{% stepper %}
{% step %}

#### 检查控制台中的音频错误代码

打开 Unity 控制台并筛选 `audio`。音频故障会以以下项上的会话错误形式出现： `ConvaiSessionEventRelay.OnSessionError`。请查看这些错误代码：

* `audio.mic_unavailable` — 未找到麦克风设备
* `audio.mic_permission_denied` — 用户拒绝了权限，或平台需要用户手势
* `audio.mic_publish_failed` — 麦克风轨道无法发布到房间

还要查找以前缀 `[RoomAudioRuntimeAdapter]` 或 `[AudioTrackManager]` 的控制台消息——它们提供的信息比单独的错误代码更详细。
{% endstep %}

{% step %}

#### 验证 ConvaiAudioOutput 是否位于正确的 GameObject 上

`ConvaiAudioOutput` 必须位于 **相同的** GameObject 上，和 `ConvaiCharacter`。该组件具有 `[RequireComponent(typeof(ConvaiCharacter))]` — 当你通过 Add Component 添加它时，Unity 会强制执行这一点，但手动编辑预制体或复制粘贴可能会违反该要求。

如果 `ConvaiAudioOutput` 位于不同的 GameObject 上，你会在播放时看到此错误：

`[ConvaiAudioOutput] 未在 {gameObjectName} 上找到 ConvaiCharacter 组件`

该 GameObject 还需要一个 `AudioSource` 组件。Unity 会通过 `[RequireComponent(typeof(AudioSource))]` 添加 `ConvaiAudioOutput`时自动添加它，但请确认它存在且已启用。

`ConvaiAudioOutput` 用于原生平台（Windows、macOS、Linux、Android、iOS）上的角色语音播放。在 WebGL 上，音频通过浏览器音频上下文路由—— `ConvaiAudioOutput` 不使用，而且在 WebGL 构建中也不需要它存在。
{% endstep %}

{% step %}

#### 检查 AudioSource 设置

选择 NPC 的 GameObject 并检查 `AudioSource` 组件：

* **音量** 必须大于 0
* **静音** 必须未勾选
* **AudioMixer** 输出组（如果已分配）不得处于 −80 dB
* **空间混合** 对于 UI 风格角色应为 0（2D），对于场景内定位的角色应为 1（3D）。当摄像机离角色很远时，空间混合为 1 会衰减音频。

还要检查 `ConvaiAudioOutput` NPC 检视器中的自身字段：

| 字段            | 默认    | 它控制什么                             |
| ------------- | ----- | --------------------------------- |
| **音量**        | 1.0   | 角色语音增益（0–1）。叠加在 AudioSource 音量之上。 |
| **是否静音**      | false | 独立于 AudioSource 静音切换，静音角色语音。      |
| **使用 3D 音频**  | true  | 启用 3D 空间音频。对于 UI 风格角色请设为 false。   |
| **最小距离**      | 1     | 音频开始衰减的距离。                        |
| **最大距离**      | 50    | 音频达到最小音量的距离。                      |
| {% endstep %} |       |                                   |

{% step %}

#### 确认用户手势会触发连接（WebGL）

浏览器会阻止麦克风访问，直到用户与页面交互。在 WebGL 构建中， `ConvaiManager.ConnectAsync()` 必须从用户手势处理程序（例如按钮 `onClick` 事件）中调用，而不是在场景加载时自动调用。

如果 SDK 在手势之前连接，麦克风发布将被中止，并显示：

`[RoomAudioRuntimeAdapter] 由于音频播放需要用户手势，麦克风发布已中止。`
{% endstep %}
{% endstepper %}

### 音频错误代码

| 错误代码                          | 说明                    | 常见原因                         |
| ----------------------------- | --------------------- | ---------------------------- |
| `audio.mic_unavailable`       | 未找到麦克风设备              | 机器上未连接麦克风                    |
| `audio.mic_permission_denied` | 访问麦克风的权限被拒绝           | 用户拒绝了系统权限对话框；WebGL 在用户手势之前调用 |
| `audio.mic_publish_failed`    | 麦克风轨道无法发布到 LiveKit 房间 | 房间未连接；内部工厂未注册                |

### ConvaiAudioOutput 设置错误

#### 组件位于错误的 GameObject 上

**控制台消息：** `[ConvaiAudioOutput] 未在 {gameObjectName} 上找到 ConvaiCharacter 组件`

**原因：** `ConvaiAudioOutput` 不在与以下项相同的 GameObject 上 `ConvaiCharacter`.

**修复：** 在层级视图中选择 NPC。确认 `ConvaiAudioOutput`, `ConvaiCharacter`，以及 `AudioSource` 都位于同一个 GameObject 上。必要时将 `ConvaiAudioOutput` 移动过去。

**验证：** 重新进入播放模式。 `[ConvaiAudioOutput] 未找到 ConvaiCharacter 组件` 错误不再出现在控制台中。

### 平台权限

{% tabs %}
{% tab title="Android" %}
Android 需要 `RECORD_AUDIO` 权限。没有它，麦克风将不可用，并且 `audio.mic_permission_denied` 触发后。

**步骤 1 — 将权限添加到 AndroidManifest.xml：**

如果你没有自定义 `AndroidManifest.xml`，请在 `Assets/Plugins/Android/AndroidManifest.xml`处创建一个。将以下行添加到 `<manifest>` 标记中：

```xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
```

**步骤 2 — 无需配置 Player Settings 字段：**

Android 在 Player Settings 中没有 **麦克风使用说明** 字段——该字段仅适用于 iOS 和 macOS 构建。SDK 会在运行时通过 `RECORD_AUDIO` 自动请求 `ConvaiPermissionService`权限，使用 Unity 的 `Permission.RequestUserPermission` API。除了步骤 1 中的 manifest 条目外，不需要额外的 Player Settings 配置。

**运行时行为：** Android 在首次请求麦克风时会显示系统权限对话框。如果用户拒绝， `audio.mic_permission_denied` 会触发。SDK 不会自动重新请求该权限——如果用户最初拒绝了，应用必须引导用户在设备设置中授予权限。

如果权限对话框从未出现，请检查 `RECORD_AUDIO` 权限是否存在于 manifest 中。缺少权限会阻止对话框出现，并静默拒绝访问。
{% endtab %}

{% tab title="iOS" %}
iOS 需要 `NSMicrophoneUsageDescription` 在 `Info.plist`。如果没有它，应用在首次访问麦克风时会立即崩溃。

**在 Player Settings 中设置说明：**

打开 **Edit → Project Settings → Player → iOS → Other Settings**。将 **麦克风使用说明** 设置为面向用户的说明，例如： `"用于与 AI 角色进行语音交互。"`

Unity 会在构建期间将此值写入 `Info.plist` 。

**运行时行为：** iOS 在首次访问麦克风时会显示系统权限对话框。如果用户拒绝， `audio.mic_permission_denied` 会触发。SDK 不会重新请求该权限——请引导用户前往 iOS **设置 → 隐私与安全性 → 麦克风** 以重新启用它。

{% hint style="danger" %}
提交 iOS 构建到 App Store 时，如果没有 `NSMicrophoneUsageDescription` 会导致自动拒绝。即使麦克风访问在你的训练模拟或体验中是可选的，也要设置此字段。
{% endhint %}
{% endtab %}

{% tab title="WebGL" %}
WebGL 有两个会影响麦克风访问的限制：

**1. 单个占位设备。** SDK 的 WebGL 麦克风源工厂（`WebGLMicrophoneSourceFactory.GetAvailableDevices()`）只返回一个占位条目， `"Default Microphone"`，而不是每个物理设备一个条目。浏览器在其自身的 `getUserMedia` 权限提示中处理实际设备选择——SDK 无法在此平台上枚举或选择特定的物理麦克风。

**2. 需要用户手势。** 浏览器强制要求：麦克风访问只能在用户手势处理程序中请求（按钮点击、按键等）。在没有事先用户交互的情况下于场景加载时自动调用 connect，会导致：

`[RoomAudioRuntimeAdapter] 由于音频播放需要用户手势，麦克风发布已中止。`

**WebGL 的推荐模式：**

添加一个 **“开始对话”** 按钮添加到场景中。将其 `onClick` 连接到调用你的连接逻辑。不要在 `Start()` 或 `Awake()`.

```csharp
// 从 UI Button 的 onClick 事件调用——这就是一个用户手势
[SerializeField] private ConvaiManager _convaiManager;

public void OnStartButtonClicked()
{
    _ = _convaiManager.ConnectAsync();
}
```

{% hint style="danger" %}
**访问麦克风需要 HTTPS。** 浏览器只会在 HTTPS 页面上授予麦克风访问权限。HTTP 部署将静默失败，无法获取麦克风，从而导致 `audio.mic_permission_denied`。唯一的例外是 `localhost` ——大多数浏览器允许在 `http://localhost` 上进行本地开发时访问麦克风。
{% endhint %}
{% endtab %}
{% endtabs %}

### 排查音频故障

| 症状                                                                   | 可能原因                                                 | 修复方法                                                                           | 验证                                          |
| -------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------- |
| `audio.mic_permission_denied` 在 Android 上                            | `RECORD_AUDIO` 在以下位置缺失 `AndroidManifest.xml`         | 添加该权限；重新构建                                                                     | 应用启动时请求麦克风权限；语音到达角色                         |
| `audio.mic_permission_denied` 在 iOS 上                                | `NSMicrophoneUsageDescription` 在 Player Settings 中缺失 | 设置该说明；重新构建                                                                     | 应用首次启动时请求麦克风权限；语音到达角色                       |
| `audio.mic_permission_denied` 在 WebGL 上                              | 连接前没有用户手势                                            | 通过 UI 按钮点击触发连接                                                                 | `audio.mic_permission_denied` 不再触发；麦克风输入已激活 |
| `audio.mic_unavailable`                                              | 机器上未连接麦克风                                            | 连接麦克风；检查操作系统音频设备                                                               | `audio.mic_unavailable` 连接时不再触发             |
| `[ConvaiAudioOutput] 在 X 上未找到 ConvaiCharacter 组件`                    | `ConvaiAudioOutput` 位于错误的 GameObject 上               | 将其移动到与以下项相同的 GameObject 上 `ConvaiCharacter`                                    | 在播放时控制台中不再出现错误                              |
| 角色转录出现，但没有音频播放                                                       | `AudioSource` 已静音、音量为 0，或混音器在 −80 dB                 | 检查 `AudioSource` 组件在 NPC 上的                                                    | 角色语音通过 NPC 播放 `AudioSource`                 |
| 角色音频在 3D 中只从一只耳朵播放                                                   | `AudioSource.spatialBlend` 设为 1 且摄像机太远               | 降低 AudioSource 的 Max Distance，或让摄像机更近                                          | 音频在适当距离下会在双耳中播放                             |
| `[RoomAudioRuntimeAdapter] 由于房间音频路径尚未初始化，麦克风发布已中止。`                  | `ConnectAsync` 在调用麦克风发布时尚未完成                         | 等待 `OnSessionStateChanged` 使用 `已连接` 后再发布麦克风                                    | 在 `已连接` state                               |
| `[AudioTrackManager] PublishMicrophoneAsync 已中止：LocalParticipant 为空` | 尝试发布时房间未连接                                           | 在任何音频发布之前确保处于完整的 Connected 状态                                                  | 麦克风发布成功，无错误                                 |
| `[AudioTrackManager] PublishMicrophoneAsync 失败：轨道为空`                 | 轨道创建在内部失败                                            | 检查 SDK 版本；重新安装包                                                                | 重新安装后麦克风发布成功，无错误                            |
| `[RoomAudioRuntimeAdapter] 麦克风发布失败：未注册 IMicrophoneSourceFactory。`    | SDK 内部接线失败                                           | 重新安装 SDK；确认包版本为 <code class="expression">space.vars.unity\_sdk\_version</code> | 重新安装后麦克风发布成功，无错误                            |
| 编辑器中麦克风可用，但在构建中不可用                                                   | 缺少构建权限                                               | 检查上面的平台权限设置                                                                    | 设备构建中麦克风激活                                  |

### 控制台日志参考

这些是来自音频子系统的确切消息。筛选控制台中的 `RoomAudioRuntimeAdapter` 或 `AudioTrackManager` 即可直接看到它们。

| Message                                                                  | 级别    | 含义                                              |
| ------------------------------------------------------------------------ | ----- | ----------------------------------------------- |
| `[RoomAudioRuntimeAdapter] 由于音频播放需要用户手势，麦克风发布已中止。`                       | 警告    | WebGL：在用户手势之前触发了连接                              |
| `[RoomAudioRuntimeAdapter] 由于房间音频路径尚未初始化，麦克风发布已中止。`                      | 警告    | 在房间音频路径就绪之前就调用了麦克风发布                            |
| `[RoomAudioRuntimeAdapter] 麦克风发布失败：未注册 IMicrophoneSourceFactory。`        | Error | 缺少内部工厂——SDK 安装问题                                |
| `[RoomAudioRuntimeAdapter] 在创建麦克风源时麦克风发布失败：{exception}`                  | Error | 创建麦克风源时发生异常——检查异常消息                             |
| `[AudioTrackManager] PublishMicrophoneAsync 已中止：LocalParticipant 为空`     | Error | 房间未连接；没有本地参与者                                   |
| `[AudioTrackManager] PublishMicrophoneAsync 失败：轨道为空`                     | Error | 麦克风轨道创建返回空值                                     |
| `[AudioTrackManager] PublishMicrophoneAsync 中的异常：{exception}`            | Error | 意外异常——检查异常详细信息                                  |
| `[AudioTrackManager] SetMicMuted 在 MicrophoneSource 上设置静音失败：{exception}` | Error | 静音操作失败——通常是时序问题                                 |
| `[ConvaiAudioOutput] 已为角色 '{characterId}' 注册 AudioSource`                | 调试    | AudioSource 已成功注册（仅在编辑器或 Development Build 中可见） |
| `[ConvaiAudioOutput] 在 {name} 上未找到 ConvaiCharacter 组件`                   | Error | `ConvaiAudioOutput` 位于错误的 GameObject 上          |

### 下一步

关于如何启用详细音频日志记录并使用 `音频` 日志类别覆盖以查看所有 SDK 音频消息，请参阅《调试工具参考》。

{% content-ref url="/pages/41fb22d336940f24c4bfbf2655c6122580016b9b" %}
[调试工具参考](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/troubleshooting/debug-tools-reference.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/troubleshooting/audio-and-microphone-issues.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
