For the complete documentation index, see llms.txt. This page is also available as Markdown.

转录 API

使用转录外观接口从 Unity 脚本查询转录轮次、订阅实时变更、读取字幕并导出会话历史。

ConvaiTranscripts 是 Convai Unity SDK 的规范转录门面:一个实时、驻留内存的房间内所有玩家和角色回合时间线,支持拉取式查询、推送式变更事件、实时字幕以及会话导出辅助工具。在编写自定义聊天 UI、转录导出或回合级对话逻辑时,请使用此页面。通过以下方式访问该门面: ConvaiManager.ActiveManager.Transcripts.


推送 vs. 拉取

ConvaiCharacter.OnTranscriptReceived

事件转发组件(ConvaiTranscriptEventRelay, ConvaiEvents)

ConvaiTranscripts

传递

推送——普通 C# 事件在每次更新时触发,针对某个角色自己的语音台词

推送——检查器 UnityEvents 或 C# 事件在每次更新时触发

拉取(CurrentTimeline, GetTurns)和推送(已变更, Subscribe)

历史

仅当前更新,作用范围限于该角色

仅当前更新

完整历史:活动回合、已提交回合和实时字幕

使用场景

按角色范围的推送响应——凝视、手势、单角色字幕

字幕渲染、按角色的动画触发

自定义聊天 UI、会话后导出、回合级评估逻辑

访问

character.OnTranscriptReceived 在一个 ConvaiCharacter 引用

ConvaiTranscriptEventRelay, ConvaiManager.ActiveManager.Events

ConvaiManager.ActiveManager.Transcripts


ConvaiCharacter.OnTranscriptReceived

OnTranscriptReceived 是在以下对象上声明的普通 C# 事件: ConvaiCharacter: event Action<string, bool> OnTranscriptReceived。它是以下内容的按角色范围对应项: ConvaiTranscripts 下面的门面——当你已经持有某个其实例的引用时就使用它 ConvaiCharacter 并且希望直接接收该角色自己的语音台词推送通知,而无需订阅整个房间级门面或添加事件转发组件。

character.OnTranscriptReceived += HandleTranscript;

private void HandleTranscript(string text, bool isFinal)
{
    if (!isFinal) return; // 丢弃中间传递,这样句子不会被追加两次
    _log.text += $"\n{text}";
}

第一个参数是转录文本。第二个, isFinal,来自消息自身的生命周期——已稳定的台词会报告 是;仍在流式传输的台词会报告 否.

文本按句子到达,而不是按合成块到达。一个在稳定前就开始流式传输的句子会被传递 两次:一次带有 isFinal 否 当它仍在进行中时,另一次带有 isFinal 是 在其稳定后 isFinal 会重复该句子。

OnTranscriptReceived 仅会针对该角色自己的语音输出触发——安静的、未朗读的机器人文本会被过滤掉,传入消息会先按参与者 ID 与该角色匹配,若不匹配则回退到角色 ID。

使用 ConvaiCharacter.OnTranscriptReceived 用于单角色推送响应。使用 ConvaiTranscripts 下面的内容,当你需要完整房间历史、多角色或多玩家,或基于拉取的查询时。


ConvaiTranscripts 门面

ConvaiManager.ActiveManager.Transcripts 会抛出 InvalidOperationException 如果 SDK 尚未完成启动引导。使用 manager.TryGetTranscripts(out ConvaiTranscripts transcripts) 当调用方可能在初始化完成前运行时,例如 OnEnable.

属性

成员
类型
说明

CurrentTimeline

TranscriptTimeline

当前转录时间线。在底层引擎快照发生变化之前,返回同一个实例。

CurrentCaptions

TranscriptCaptionSnapshot

用于与语音对齐字幕的当前实时字幕快照。

IsPresentationEnabled

布尔值

随附的展示组件是否应渲染转录更新。只读;规范历史记录仍会继续记录。

事件

事件
参数
当

已变更

TranscriptChangeBatch

一个或多个回合被添加、更新、提交、中断、更正或移除

回合已更新

TranscriptTurn

某个回合收到新文本或非终态状态变更

回合已提交

TranscriptTurn

某个回合转换为 已提交 或 被打断

回合已更正

TranscriptTurn

先前已提交回合的文本被更正

回合已移除

字符串 (回合 ID)

某个回合从时间线中移除

字幕已变更

TranscriptCaptionSnapshot

实时字幕快照发生变化

展示启用状态已变更

布尔值

IsPresentationEnabled 发生变化

方法

方法
返回值
说明

GetTurns(TranscriptQuery query = null)

IReadOnlyList<TranscriptTurn>

返回所有匹配可选查询的回合。传入 null 可获取每个回合。

GetTurn(string turnId)

TranscriptTurn

按 ID 检索特定回合。返回 null 如果未找到则返回。

GetLatestTurn(TranscriptParticipantRef participant)

TranscriptTurn

返回给定参与者的最新回合。返回 null 如果没有则返回。

Subscribe(Action<TranscriptChange> callback, TranscriptSubscriptionOptions options = null)

IDisposable

为匹配的回合变更注册回调。释放返回值即可取消订阅。

SubscribeCommitted(Action<TranscriptChange> callback, TranscriptSubscriptionOptions options = null)

IDisposable

快捷方式,对应 Subscribe 与 IncludeActive = false 和 IncludeTerminal = true ——仅包含已提交和已中断的回合。

SubscribeCaptions(Action<TranscriptCaption> callback, TranscriptCaptionSubscriptionOptions options = null)

IDisposable

为实时字幕更新注册回调。

Clear()

void

清除规范转录历史。

Export(TranscriptExportFormat format)

字符串

将每个已提交回合序列化为纯文本、Markdown 或 JSON。

Dispose()

void

取消订阅内部引擎事件。在所属组件销毁时调用。


TranscriptTimeline

属性
类型
说明

Cursor

long

单调递增的值,每当时间线更新时都会变化

活动回合

IReadOnlyList<TranscriptTurn>

尚未提交的回合(倾听中, 传输中,或 Stable)

已提交回合

IReadOnlyList<TranscriptTurn>

处于终态的回合(已提交 或 被打断)

按 ID 索引的回合

IReadOnlyDictionary<string, TranscriptTurn>

所有回合按以下字段索引: TranscriptTurn.Id

回合

IReadOnlyList<TranscriptTurn>

活动回合 和 已提交回合 合并并按以下字段排序: 房间序列

TranscriptTimeline.Empty 是一个静态、可复用的空实例——在会话连接前的安全默认值。


TranscriptTurn

属性
类型
说明

ID

字符串

此回合的唯一标识符

MessageId

字符串

与此回合关联的消息标识符

ResponseId

字符串

与此回合关联的响应标识符(如适用)

房间序列

long

在房间内单调递增的序列号

修订

整数

每当回合内容或状态变化时递增

发言者

TranscriptSpeaker

是谁生成了此回合

状态

TranscriptTurnState

此回合当前的生命周期状态

主要文本来源

TranscriptTextSource

支撑此回合显示文本的主要文本来源

稳定文本

字符串

已定稿文本,后续更新不会再变化

中间文本

字符串

来自当前流式片段的进行中文本

显示文本

字符串

要为此回合渲染的文本——结合 稳定文本 和 中间文本

开始时间(UTC)

DateTime

回合开始的 UTC 时间

最后更新时间(UTC)

DateTime

最近一次更新的 UTC 时间

提交时间(UTC)

DateTime?

回合被提交的 UTC 时间; null 在活动期间

WasInterrupted

布尔值

是 当回合因中断而结束时

片段

IReadOnlyList<TranscriptSegment>

构成此回合的各个转录片段

有文本

布尔值

是 当 显示文本 非空

是否已提交

布尔值

是 当 状态 是 已提交 或 被打断

使用 显示文本 用于实时渲染。它结合了 稳定文本 和 中间文本,因此无论 状态.

TranscriptTurnState 枚举

值
说明

倾听中 (0)

回合处于开启状态,正在等待语音或文本输入;尚未捕获文本

传输中 (1)

回合正在主动接收文本; 中间文本 正在更新

Stable (2)

流式传输已暂停;文本已稳定,但回合尚未提交

已提交 (4)

回合已完全提交; 稳定文本 为最终

被打断 (5)

回合因被中断而结束(WasInterrupted 是 是)

已丢弃 (6)

回合在没有文本的情况下关闭,并被排除在两者之外 活动回合 和 已提交回合


TranscriptSegment

属性
类型
说明

ID

字符串

此片段的唯一标识符

TurnId

字符串

父项的 ID TranscriptTurn

发言者

TranscriptSpeaker

是谁生成了此片段

稳定文本

字符串

此片段的已定稿文本

中间文本

字符串

此片段的进行中文本

显示文本

字符串

要为此片段渲染的文本

状态

TranscriptTurnState

此片段的生命周期状态

来源

TranscriptTextSource

此片段文本的来源

开始时间(UTC)

DateTime

此片段开始的 UTC 时间

更新时间(UTC)

DateTime

最近一次更新的 UTC 时间

停止时间(UTC)

DateTime?

此片段停止的 UTC 时间; null 在活动期间

TranscriptTextSource 枚举

值
说明

未知 (0)

无法确定来源

中间 ASR (1)

进行中的语音转文本识别

ASR 最终 (2)

已定稿的语音转文本识别

处理后最终 (3)

经玩家端处理后的已定稿文本

输入文本 (4)

由玩家键入而非说出的文本

BotOutput (5)

已定稿的角色回复文本

机器人预览 (6)

进行中的角色回复预览(LLM 流式传输)

旧版机器人转录 (7)

来自旧版流水线的角色转录文本


TranscriptSpeaker

属性
类型
说明

类型

TranscriptSpeakerType

此发言者是否为 玩家, 角色,或 系统

ID

字符串

此发言者的角色 ID 或玩家 ID

DisplayName

字符串

人类可读名称

ParticipantId

字符串

房间级参与者标识符

TranscriptSpeakerType 枚举

值
说明

玩家 (0)

人类玩家参与者

角色 (1)

AI 角色参与者

系统 (2)

系统来源的发言者,不绑定到玩家或角色


TranscriptChange 和 TranscriptChangeBatch

TranscriptChange:

属性
类型
说明

类型

TranscriptChangeKind

此实例表示的变更类型

回合

TranscriptTurn

受影响的回合; null 当 类型 是 已移除

TurnId

字符串

受影响回合的 ID

TranscriptChangeBatch:

属性
类型
说明

时间线

TranscriptTimeline

此批变更后的完整时间线

变更

IReadOnlyList<TranscriptChange>

此批中包含的每一项变更

已变更回合

IReadOnlyList<TranscriptTurn>

便捷访问器:每个非空 回合 来自 变更

TranscriptChangeKind 枚举

值
说明

已添加 (0)

创建了一个新回合

已更新 (1)

现有回合收到了新文本或非终态状态变更

已提交 (2)

某个回合转换为 已提交

被打断 (3)

某个回合转换为 被打断

已更正 (4)

先前已提交回合的文本被更正

已移除 (5)

某个回合从时间线中移除


TranscriptQuery ——筛选 GetTurns 结果

字段
类型
默认
说明

参与者类型

TranscriptParticipantKind?

null (全部)

筛选为 玩家 或 角色 仅回合

PlayerOrCharacterId

字符串

null (全部)

筛选到特定玩家或角色 ID

ParticipantId

字符串

null (全部)

筛选到特定房间参与者 ID

包含活动回合

布尔值

是

包含仍处于活动状态(尚未提交)的回合

包含已提交回合

布尔值

是

包含已提交或已中断的回合

TranscriptQuery 使用以下 包含活动回合/包含已提交回合 字段名称。 TranscriptSubscriptionOptions,由以下内容使用: Subscribe,使用 IncludeActive/IncludeTerminal 改为此项。

TranscriptParticipantKind 枚举

值
说明

玩家 (0)

人类玩家参与者

角色 (1)

AI 角色参与者

TranscriptParticipantRef 结构体

用作 参与者 参数传入 GetLatestTurn.

属性
类型
说明

类型

TranscriptParticipantKind

此参与者是否为 玩家 或 角色

PlayerOrCharacterId

字符串

此参与者的角色 ID 或玩家 ID

DisplayName

字符串

人类可读名称

ParticipantId

字符串

房间级参与者标识符

IsEmpty

布尔值

是 当 PlayerOrCharacterId 为空或仅包含空白字符

使用以下方式构造: new TranscriptParticipantRef(TranscriptParticipantKind kind, string playerOrCharacterId, string displayName, string participantId = null)。实现 IEquatable<TranscriptParticipantRef> 以及 ==/!= 运算符。


TranscriptSubscriptionOptions ——筛选 Subscribe 回调,恢复了首轮 LipSync

字段
类型
默认
说明

重放现有内容

布尔值

否

当 是, Subscribe 会立即对已在其中的每个匹配回合调用回调 CurrentTimeline

IncludeActive

布尔值

是

包含尚未提交的回合

IncludeTerminal

布尔值

是

包含已提交或已中断的回合

SpeakerType

TranscriptSpeakerType?

null (全部)

筛选到特定发言者类型

SpeakerId

字符串

null (全部)

筛选到特定发言者 ID

ParticipantId

字符串

null (全部)

筛选到特定房间参与者 ID


实时字幕

字幕是语音对齐文本的独立、短暂投影——它与持久聊天历史分开存放,因此短暂的 TTS 预览文本绝不会被当作规范对话历史。

TranscriptCaption

属性
类型
说明

TurnId

字符串

此字幕所对齐的转录回合 ID

发言者

TranscriptSpeaker

是谁生成了此字幕

文本

字符串

字幕文本

状态

TranscriptCaptionState

当前字幕状态

更新时间(UTC)

DateTime

最近一次更新的 UTC 时间

有文本

布尔值

是 当 文本 非空

IsFinal

布尔值

是 当 状态 是 已完成 或 被打断

WasInterrupted

布尔值

是 当 状态 是 被打断

TranscriptCaptionState 枚举

值
说明

传输中 (0)

字幕文本正在积极更新

Stable (1)

字幕文本已暂停更新,但尚未最终确定

已完成 (2)

字幕正常结束

被打断 (3)

字幕因回合中断而结束

TranscriptCaptionSnapshot

属性
类型
说明

Cursor

long

单调递增的值,每当字幕更新时都会变化

字幕

IReadOnlyList<TranscriptCaption>

当前的实时字幕集合

TranscriptCaptionSnapshot.Empty 是一个静态、可复用的空实例。

TranscriptCaptionSubscriptionOptions

字段
类型
默认
说明

重放最新

布尔值

是

当 是, SubscribeCaptions 会立即对每个当前匹配的字幕调用回调

包含流式传输

布尔值

是

包含仍在更新的字幕

包含最终字幕

布尔值

是

包含已完成或已中断的字幕

SpeakerType

TranscriptSpeakerType?

null (全部)

筛选到特定发言者类型

SpeakerId

字符串

null (全部)

筛选到特定发言者 ID

ParticipantId

字符串

null (全部)

筛选到特定房间参与者 ID


导出转录

Export(TranscriptExportFormat format) 将其中的每个回合序列化为 CurrentTimeline.CommittedTurns,按以下字段排序: 房间序列,并合并为单个字符串。发言者标签将回退到 Speaker.Type 当 Speaker.DisplayName 为空。

TranscriptExportFormat 枚举

值
说明

PlainText (0)

每个回合一行: 发言者:文本

Markdown (1)

每个回合一行: **说话者:** 文本,轮次之间空一行

JSON (2)

已提交对象的缩进 JSON 数组 TranscriptTurn 对象


使用示例

示例 1 — 会话结束后转录导出

一个医疗培训模拟在会话结束后将完整会话转录导出为 JSON,供主管审阅。

示例 2 — 在提交时追加的响应式聊天日志

一个企业入职模拟会构建可滚动的聊天历史,仅在轮次被提交时追加消息——避免中间更新造成的闪烁。

示例 3 — 带实时字幕的聊天历史

一场工业安全演练在启用时重放已提交的聊天历史,然后让字幕行与实时字幕保持同步——与持久的聊天日志分开。


故障排查

症状
可能原因
修复方法

ConvaiManager.ActiveManager.Transcripts 会抛出 InvalidOperationException

在 SDK 完成引导之前被访问

使用 manager.TryGetTranscripts(out var transcripts) 而不是 转录 属性在早期 OnEnable 或 Awake

GetTurns() 返回空列表

尚无轮次,或者查询的 包含活动回合 是 否 而每个当前轮次仍然处于活动状态时

省略 TranscriptQuery,或设置 IncludeActiveTurns = true 以包含进行中的轮次

Subscribe 回调从未触发

订阅得太晚,或者 IncludeActive/IncludeTerminal 排除了所有匹配的轮次

在之前或紧接着之后订阅 ConnectAsync;设置 ReplayExisting = true 以立即接收现有轮次

TranscriptTurn.StableText 为空

轮次仍然 传输中 或 Stable ——在轮次提交之前,文本并不稳定

使用 显示文本 用于进行中的渲染,或者订阅时使用 SubscribeCommitted

SubscribeCaptions 回调从未触发

包含流式传输/包含最终字幕 或者说话人筛选器排除了所有匹配的字幕,或者 重放最新 是 否 且尚未收到新的字幕

检查 包含流式传输, 包含最终字幕, SpeakerType, SpeakerId以及 ParticipantId 时 TranscriptCaptionSubscriptionOptions;设置 ReplayLatest = true 以立即接收当前字幕


下一步

如需在不查询时间线的情况下进行事件驱动的转录响应,请使用 ConvaiCharacterEventRelay 或 ConvaiTranscriptEventRelay 来驱动目标——参见 角色事件。完整的角色脚本 API 请参见 角色与玩家 API。有关 facade 访问器的完整列表,请参见 ConvaiManager,请参见 ConvaiManager API.

最后更新于

这有帮助吗?