本文档介绍如何在 TUILiveKit 中集成 AI 字幕功能。通过该功能,用户可以在进入房间后,将房间内的实时语音内容转写为文字字幕,并支持将识别出的文字实时翻译为多种目标语言,方便不同语言背景的用户进行跨语种沟通。
说明:
AI 字幕当前支持实时语音转写与多语言翻译能力。同声传译功能 TUILiveKit 暂不支持,后续版本将开放。
开通服务 后,使用 AI 字幕能力将产生相应费用,详细计费规则请参考 AI 智能语音计费说明。
核心概念
在正式接入 AI 字幕前,建议先了解以下核心概念:
环境配置
AI 字幕功能基于 AtomicXCore SDK 提供的
AITranscriberStore 接口实现。在正式调用接口前,请确保已完成对应平台的 AtomicXCore SDK 集成,并成功进房。已集成
atomicxcore 依赖,并在工程中引入 io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStore。确保已在房间内(完成
startLive 或 joinLive)再调用字幕相关接口。已通过 CocoaPods 集成
AtomicXCore,并在源码中 import AtomicXCore。确保已在房间内(完成
startLive 或 joinLive)再调用字幕相关接口。已在
pubspec.yaml 中引入 atomic_x_core 依赖。确保已在房间内(完成
startLive 或 joinLive)再调用字幕相关接口。创建 AITranscriberStore 实例
AI 字幕相关接口通过
AITranscriberStore 管理,需使用工厂方法按房间 ID 创建实例。同一房间 ID 多次创建会返回同一实例。import io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStore// 按房间 ID 创建实例(同一房间多次调用返回同一实例)val transcriberStore = AITranscriberStore.create("your_room_id")
import AtomicXCore// 按房间 ID 创建实例(同一房间多次调用返回同一实例)let transcriberStore = AITranscriberStore.create(roomID: "your_room_id")
import 'package:atomic_x_core/api/ai/ai_transcriber_store.dart';// 按房间 ID 创建实例(同一房间多次调用返回同一实例)final transcriberStore = AITranscriberStore.create("your_room_id");
订阅字幕状态
字幕的实时数据(消息列表、运行状态、配置等)通过状态发布器(State / StateFlow / ValueListenable)对外提供。建议在开启字幕前先完成订阅,以便及时刷新 UI。
状态字段说明
字段 | 类型 | 说明 |
selfLanguage | SourceLanguage | 当前用户设置的源语言 |
realtimeMessageList | List<TranscriberMessage> | 实时字幕消息列表,随转写进度自动更新 |
isTranscriptionRunning | Bool | 转写服务是否正在运行 |
transcriptionConfig | TranscriptionConfig | 当前转写配置 |
订阅示例
import kotlinx.coroutines.launchimport androidx.lifecycle.lifecycleScopeimport io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStore// 订阅实时字幕消息列表lifecycleScope.launch {transcriberStore.transcriberState.realtimeMessageList.collect { messages ->messages.forEach { message ->println("Speaker: ${message.speakerUserName}")println("Source text: ${message.sourceText}")message.translationTexts.forEach { (lang, text) ->println("Translation[$lang]: $text")}}}}// 订阅转写运行状态lifecycleScope.launch {transcriberStore.transcriberState.isTranscriptionRunning.collect { running ->println("Transcription running: $running")}}
// 订阅字幕整体状态transcriberStore.state.subscribe { state infor message in state.realtimeMessageList {print("Speaker: \\(message.speakerUserName)")print("Source text: \\(message.sourceText)")for (lang, text) in message.translationTexts {print("Translation[\\(lang)]: \\(text)")}}print("Transcription running: \\(state.isTranscriptionRunning)")}
import 'package:atomic_x_core/api/ai/ai_transcriber_store.dart';// 订阅实时字幕消息列表transcriberStore.transcriberState.realtimeMessageList.addListener(() {final messages = transcriberStore.transcriberState.realtimeMessageList.value;for (final message in messages) {print("Speaker: ${message.speakerUserName}");print("Source text: ${message.sourceText}");message.translationTexts.forEach((lang, text) {print("Translation[$lang]: $text");});}});// 订阅转写运行状态transcriberStore.transcriberState.isTranscriptionRunning.addListener(() {final running = transcriberStore.transcriberState.isTranscriptionRunning.value;print("Transcription running: $running");});
开启 AI 字幕
完成实例创建与状态订阅后,调用
startTranscription 开启实时转写。如需同时开启翻译,请在 TranscriptionConfig 中将 enableTranslation 设置为 true。开启 AI 字幕后,系统会根据麦上成员的语音流生成转写内容;若同时开启翻译,系统会根据说话人的源语言与当前配置的目标语言生成译文。使用时请注意以下规则:
只有当麦上其他成员设置的源语言和自己的源语言不同时,才会显示翻译语言。
myLanguage 表示当前用户希望看到的字幕语言,也会作为当前用户本人说话语言的默认判断依据。 例如,房主开启了字幕和翻译,并将自己的
myLanguage 设置为英语。如果当前麦上只有房主一人,且房主本人说话,系统会认为该语音的源语言就是英语,因此只会看到原文,不会额外生成“翻译后的英语内容”。如需验证翻译效果,可以让另一位说不同语言的麦上成员参与发言。例如麦上观众使用中文发言,房主侧即可看到该成员的原文及对应译文。
建议麦上成员主动传入自己的说话语言。
myLanguage 用于声明当前用户的说话语言,传入与实际语言匹配的值可以提升识别准确率。如果麦上成员未调用相关接口传入
myLanguage,系统会默认读取该用户的手机系统语言作为兜底语言。因此,即使未显式设置语言,用户开启 AI 字幕后仍可能看到字幕内容,但为了获得更准确的识别效果,建议引导用户主动选择或传入自己的常用说话语言。麦下观众开启字幕不会主动触发转写任务,但可以追加翻译任务。
麦下观众开启字幕时,只会订阅房间内已有的转写结果,不会单独触发转写机器人进房拉取麦上成员的音频流进行识别。
如果房间内已有麦上成员开启字幕,并且转写任务正在运行,麦下观众开启字幕后即可看到转写内容;此时麦下观众也可以开启翻译,系统会基于已有转写结果为该观众追加对应的翻译任务。
说明:
源语言
myLanguage 表示当前用户希望看到的字幕语言,同时也会作为当前用户本人发言时的识别语言。建议传入与当前用户使用语言一致的值。开启翻译后,系统会将其他语言的麦上成员发言翻译为 myLanguage 对应的语言。import io.trtc.tuikit.atomicxcore.api.ai.SourceLanguageimport io.trtc.tuikit.atomicxcore.api.ai.TranscriptionConfigimport io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStore// 1. 配置转写参数:开启翻译val config = TranscriptionConfig(enableTranslation = true)// 2. 开启转写,指定源语言为中英混合transcriberStore.startTranscription(myLanguage = SourceLanguage.CHINESE_ENGLISH,config = config) { code, message ->if (code != 0) {println("Start transcription failed: $message")} else {println("Start transcription success")}}
import AtomicXCore// 1. 配置转写参数:开启翻译let config = TranscriptionConfig(enableTranslation: true)// 2. 开启转写,指定源语言为中英混合transcriberStore.startTranscription(myLanguage: .chineseEnglish, config: config) { error inif let error = error {print("Start transcription failed: \\(error)")} else {print("Start transcription success")}}
import 'package:atomic_x_core/api/ai/ai_transcriber_store.dart';// 1. 配置转写参数:开启翻译final config = TranscriptionConfig(enableTranslation: true);// 2. 开启转写,指定源语言为中英混合final result = await transcriberStore.startTranscription(SourceLanguage.chineseEnglish,config: config,);if (!result.isSuccess) {print("Start transcription failed: ${result.errorMessage}");} else {print("Start transcription success");}
更新字幕配置
转写服务运行期间,可调用
updateTranscription 动态修改源语言或翻译开关,无需停止后重启。import io.trtc.tuikit.atomicxcore.api.ai.SourceLanguageimport io.trtc.tuikit.atomicxcore.api.ai.TranscriptionConfigimport io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStore// 运行中切换源语言为英语,并关闭翻译val newConfig = TranscriptionConfig(enableTranslation = false)transcriberStore.updateTranscription(myLanguage = SourceLanguage.ENGLISH,config = newConfig) { code, message ->if (code != 0) {println("Update transcription failed: $message")}}
import AtomicXCore// 运行中切换源语言为英语,并关闭翻译var newConfig = TranscriptionConfig(enableTranslation: false)transcriberStore.updateTranscription(myLanguage: .english, config: newConfig) { error inif let error = error {print("Update transcription failed: \\(error)")}}
import 'package:atomic_x_core/api/ai/ai_transcriber_store.dart';// 运行中切换源语言为英语,并关闭翻译final newConfig = TranscriptionConfig(enableTranslation: false);final result = await transcriberStore.updateTranscription(SourceLanguage.english,config: newConfig,);if (!result.isSuccess) {print("Update transcription failed: ${result.errorMessage}");}
停止 AI 字幕
当需要停止转写时,调用
stopTranscription。停止后转写机器人将不再识别语音,字幕消息列表也不再更新。import io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStoretranscriberStore.stopTranscription { code, message ->if (code != 0) {println("Stop transcription failed: $message")} else {println("Stop transcription success")}}
import AtomicXCoretranscriberStore.stopTranscription { error inif let error = error {print("Stop transcription failed: \\(error)")} else {print("Stop transcription success")}}
import 'package:atomic_x_core/api/ai/ai_transcriber_store.dart';final result = await transcriberStore.stopTranscription();if (!result.isSuccess) {print("Stop transcription failed: ${result.errorMessage}");} else {print("Stop transcription success");}
字幕消息结构
每条字幕消息对应说话人的一段连续语音,结构如下:
属性 | 类型 | 说明 |
segmentId | String | 字幕段唯一标识 |
speakerUserId | String | 说话人用户 ID |
speakerUserName | String | 说话人昵称 |
sourceText | String | 识别出的原文 |
translationTexts | Map<TranslationLanguage, String> | 目标语言的译文 |
timestamp | Int / Long | 消息时间戳 |
isCompleted | Bool | 该段语音是否已结束。为 true 后原文与译文不再更新 |
说明:
同一段语音在说话过程中会持续更新
sourceText 与 translationTexts,直到 isCompleted 置为 true 表示该段结束。建议 UI 层在段未结束时实时刷新当前段文本,段结束后将其归档为历史字幕。translationTexts 中仅有一个键值对,Key 是与接口传入的 myLanguage 相对应的 TranslationLanguage,Value 是对应的翻译文本。可通过 Key 取值,也可直接打印 Map。完整使用示例
以下示例展示从创建实例、订阅状态到开启字幕的完整流程。
import io.trtc.tuikit.atomicxcore.api.ai.AITranscriberStoreimport io.trtc.tuikit.atomicxcore.api.ai.SourceLanguageimport io.trtc.tuikit.atomicxcore.api.ai.TranscriptionConfigimport androidx.lifecycle.lifecycleScopeimport kotlinx.coroutines.launchfun setupAITranscriber(roomID: String) {// 1. 创建实例val store = AITranscriberStore.create(roomID)// 2. 订阅字幕消息lifecycleScope.launch {store.transcriberState.realtimeMessageList.collect { messages ->messages.forEach { msg ->Log.d("AITranscriber", "[${msg.speakerUserName}] ${msg.sourceText}")}}}// 3. 开启字幕(含翻译)val transConfig = TranscriptionConfig(enableTranslation = true)store.startTranscription(myLanguage = SourceLanguage.CHINESE_ENGLISH,config = transConfig) { code, message ->if (code != 0) Log.e("AITranscriber", "start failed: $message")}}
import AtomicXCorefunc setupAITranscriber(roomID: String) {// 1. 创建实例let store = AITranscriberStore.create(roomID: roomID)// 2. 订阅字幕状态store.state.subscribe { state infor msg in state.realtimeMessageList {print("[\\(msg.speakerUserName)] \\(msg.sourceText)")}}// 3. 开启字幕(含翻译)let transConfig = TranscriptionConfig(enableTranslation: true)store.startTranscription(myLanguage: .chineseEnglish, config: transConfig) { error inif let error = error {print("start failed: \\(error)")}}}
import 'package:atomic_x_core/api/ai/ai_transcriber_store.dart';Future<void> setupAITranscriber(String roomID) async {// 1. 创建实例final store = AITranscriberStore.create(roomID);// 2. 订阅字幕消息store.transcriberState.realtimeMessageList.addListener(() {final messages = store.transcriberState.realtimeMessageList.value;for (final msg in messages) {print("[${msg.speakerUserName}] ${msg.sourceText}");}});// 3. 开启字幕(含翻译)final transConfig = TranscriptionConfig(enableTranslation: true);final transResult = await store.startTranscription(SourceLanguage.chineseEnglish,config: transConfig,);if (!transResult.isSuccess) {print("start failed: ${transResult.errorMessage}");}}
支持语言列表
源语言列表
转写服务支持以下 20 种源语言,请选择与说话人语言匹配的项以获得最佳识别准确率。中英混合场景建议使用
chineseEnglish。语言 | 取值 | 说明 |
chineseEnglish | zh_en | 中英文混合 |
chinese | zh | 中文 |
english | en | 英语 |
cantonese | zh-yue | 粤语 |
vietnamese | vi | 越南语 |
japanese | ja | 日语 |
korean | ko | 韩语 |
indonesian | id | 印尼语 |
thai | th | 泰语 |
portuguese | pt | 葡萄牙语 |
turkish | tr | 土耳其语 |
arabic | ar | 阿拉伯语 |
spanish | es | 西班牙语 |
hindi | hi | 印地语 |
french | fr | 法语 |
malay | ms | 马来语 |
filipino | fil | 菲律宾语 |
german | de | 德语 |
italian | it | 意大利语 |
russian | ru | 俄语 |
翻译语言列表
转写文字支持实时翻译为以下 15 种目标语言。
语言 | 取值 | 说明 |
chinese | zh | 中文 |
english | en | 英语 |
vietnamese | vi | 越南语 |
japanese | ja | 日语 |
korean | ko | 韩语 |
indonesian | id | 印尼语 |
thai | th | 泰语 |
portuguese | pt | 葡萄牙语 |
arabic | ar | 阿拉伯语 |
spanish | es | 西班牙语 |
french | fr | 法语 |
malay | ms | 马来语 |
german | de | 德语 |
italian | it | 意大利语 |
russian | ru | 俄语 |
常见问题
开启字幕失败,调用 startTranscription 接口报错。
请确认以下前置条件是否满足:
1. 当前 SDKAppID 可能未开通直播 AI 实时转写服务,请先在控制台开通对应能力。
2. 已成功进房(房间状态为已连接),AI 字幕仅在房内可用。
3. 源语言
myLanguage 已正确传入,且取值在支持的语言列表内。4. 房间内至少存在一路有效的音频流,否则转写机器人无语音可识别。
开启翻译后,为什么只看到原文,没有看到译文。
请确认当前麦上是否存在使用其他语言发言的成员。
myLanguage 表示当前用户希望看到的字幕语言,也会作为当前用户本人说话语言的默认判断依据。例如,房主开启字幕和翻译时传入
myLanguage 为英语,如果当前麦上只有房主一人或者其他麦上成员的 myLanguage 也为英语,系统会默认认为两位麦上成员说的都是英语,因此只会返回原文,不会再生成一份英语译文。如需验证翻译效果,可以让另一位说不同语言的麦上成员发言。例如中文观众上麦发言,房主侧即可看到该成员的原文和翻译结果。
麦上成员没有传入 myLanguage,是否还能使用 AI 字幕?
可以,如果麦上成员未显式传入
myLanguage,系统会读取该成员的手机系统语言作为兜底语言。用户开启 AI 字幕后仍可以看到字幕内容。但手机系统语言不一定等同于用户实际说话语言,因此建议在业务侧引导用户选择或传入自己的实际说话语言,以提升语音识别准确率。
麦下观众开启字幕或翻译后,为什么没有内容?
1. 麦下观众开启字幕不会主动触发转写任务。只有麦上成员开启了 AI 字幕,房间内已有转写任务正在运行时,麦下观众开启字幕后才能接收到字幕内容。
2. 如果麦上主播没有开启字幕,麦下观众单独开启字幕不会产生内容,因为此时房间内没有可订阅的转写结果。
3. 当已有转写任务运行时,麦下观众可以在接收原文字幕的基础上开启翻译,系统会基于已有转写结果追加对应的翻译任务。
字幕消息一直不更新,realtimeMessageList 为空。
请检查:
1. 房间内是否有成员正在说话(有音频上行)。
2. 是否已正确订阅
realtimeMessageList 状态,且订阅时机早于或等于开启转写的时机。3. 转写服务是否处于运行中(
isTranscriptionRunning 为 true)。转写过程中切换源语言后,历史字幕是否会保留?
切换源语言不会清空历史字幕消息列表。历史消息保持不变,新的语音段将以新的源语言进行识别。如需清空展示,可在 UI 层自行处理列表数据。