语音转文字
Flutter IMKit 支持对语音消息进行转文字展示。用户在聊天界面长按语音消息,在弹出的菜单中点击"转文字"即可调用 IMLib 的语音转文字能力,转换完成后在语音气泡下方显示转写结果。
准备工作
- 请确保已在 IM 服务的服务购买页面开通语音转文字功能。
- 使用的 SDK 需支持语音转文字能力(Flutter IMKit SDK 版本 >= 1.0.1)。
- 语音消息录制建议参数:采样率 8000Hz 或 16000Hz,单声道,编码
aac(默认实现已按此配置),单条语音消息建议不超过 60 秒。
功能说明
- 长按语音消息气泡 → 菜单出现"转文字"选项。
- 触发后会立即更新 UI 为"转换中"状态,等待回调结果。
- 成功后在语音气泡下方展示文字,失败会显示失败提示(可选气泡提示或 toast)。
- IMKit 会记录"某条消息的转文字是否可见"的 UI 状态,以便二次进入会话时保持显示。
效果展示





组件关系
- Engine 层:监听 IMLib 回调,派发语音转文字完成事件。
- Chat Provider:发起转换请求、接收完成事件、维护 UI 状态(可见性/动画/失败提示)。
- Voice 气泡:在主气泡下方追加一个"转文字"附加气泡,展示转换中/成功/失败的不同状态。
关键代码
1)触发转换请求
从语音消息的长按菜单进入:
实际发起请求的实现:
rongcloud_im_kit.dart
Future<void> voiceMessageToText(RCIMIWVoiceMessage message) async {
if (message.messageUId == null || message.messageId == null) {
return;
}
engineProvider.engine?.requestSpeechToTextForMessage(message.messageUId!,
callback: IRCIMIWOperationCallback(
onSuccess: () {
debugPrint('requestSpeechToTextForMessage success');
},
onError: (code) {
debugPrint('requestSpeechToTextForMessage error: $code');
for (int i = 0; i < _messages.length; i++) {
if (_messages[i].messageId == message.messageId) {
(_messages[i] as RCIMIWVoiceMessage).speechToTextInfo?.status =
RCIMIWSpeechToTextStatus.failed;
final ctx = _messageListKey.currentContext;
if (ctx != null && speechToTextFailShowToast) {
ScaffoldMessenger.of(ctx).showSnackBar(
const SnackBar(content: Text('转文字失败,请稍后重试')),
);
}
notifyListeners();
break;
}
}
},
));
for (int i = 0; i < _messages.length; i++) {
if (_messages[i].messageId == message.messageId) {
(_messages[i] as RCIMIWVoiceMessage).speechToTextInfo?.status =
RCIMIWSpeechToTextStatus.converting;
break;
}
}
addSpeechToTextMessageIdVisible(message.messageId!);
notifyListeners();
}
2)接收转换结果回调
Engine 层监听 IMLib 回调并派发:
engine_provider.dart
engine?.onSpeechToTextCompleted = (info, messageUId, code) {
RCIMIWVoiceMessage voiceMessage = RCIMIWVoiceMessage.fromJson({});
voiceMessage.speechToTextInfo = info;
voiceMessage.messageUId = messageUId;
if (code != 0) {
voiceMessage.speechToTextInfo?.status = RCIMIWSpeechToTextStatus.failed;
}
speechToTextMessageNotifier.value = voiceMessage;
...
};
Chat Provider 同步 UI 状态:
rongcloud_im_kit.dart
void _onSpeechToTextCompleted() {
final speechToTextMessage =
engineProvider.speechToTextMessageNotifier.value;
if (speechToTextMessage != null) {
for (int i = 0; i < _messages.length; i++) {
if (_messages[i].messageUId == speechToTextMessage.messageUId) {
(_messages[i] as RCIMIWVoiceMessage).speechToTextInfo =
speechToTextMessage.speechToTextInfo;
if (speechToTextMessage.speechToTextInfo?.status ==
RCIMIWSpeechToTextStatus.failed) {
final ctx = _messageListKey.currentContext;
if (ctx != null && speechToTextFailShowToast) {
ScaffoldMessenger.of(ctx).showSnackBar(
const SnackBar(content: Text('转文字失败,请稍后重试')),
);
}
}
break;
}
}
notifyListeners();
}
}
3)UI 展示:在语音气泡下方追加"转文字"气泡
展示转换中/失败/成功三种状态与动画:
4)可用性开关与菜单展示
语音转文字开关取自 AppSettings:
engine_provider.dart
Future<void> _setAppSettings() async {
final appSettings = await engine?.getAppSettings();
enableSpeechToText = appSettings?.speechToTextEnable ?? false;
}
弹出菜单中控制"转文字/取消转文字"的展示:
使用说明
- 在聊天页面集成
ChatPage与 Provider(示例详见快速开始文档)。 - 确保语音消息能正常录制与发送(默认录音配置如下,满足转写要求):
voice_record_provider.dart
void startRecord(BuildContext context) async {
...
await _recorder.start(
RecordConfig(
encoder: AudioEncoder.aacLc,
sampleRate: 16000,
bitRate: 32000,
numChannels: 1,
),
path: voicePath,
);
...
_volumeTimer = Timer.periodic(const Duration(milliseconds: 20), (timer) async {
if (await _recorder.isRecording()) {
...
if (voiceDuration >= 60 && context.mounted) {
finishRecord(context);
}
notifyListeners();
}
});
}
- 进入聊天,长按语音消息,选择"转文字"。
- 等待转换完成,结果自动显示于语音气泡下方;再次长按可选择"