import 'dart:async'; import 'dart:typed_data'; /// 语音识别服务接口 abstract class AstService { /// 支持的语言 List get supportedLanguages; /// 初始化语音识别服务 /// [supportedLanguages] 支持的语言列表 /// [provider] 提供商:azure / volcano / alibaba / iflytek Future initialize( {required List supportedLanguages, String provider = 'azure'}); /// 设置低音量阈值 void setLowVolumeThreshold(int threshold); /// 开始录音 Future enableRecord(String filePath); /// 开始连续翻译 Future startContinuousTranslation(); /// 停止连续翻译 Future stopContinuousTranslation(); /// 返回一个包含识别事件的流 Future> recognizeCallback(); /// 开始录音 Future path(String filePath); /// 通话翻译:是否本地播报对方(B)翻译后的音频。 /// true → 原生层把 B 路 E2E PCM 直接播出,同时启用播放期 gate 防回环 /// false → 原生层丢弃 B 路播放,gate 永不触发 /// 未实现的原生端应 no-op 并返回 true Future setBroadcastPeerTranslate(bool enabled); /// 释放资源 Future dispose(); } // 识别事件类型 enum ASTEventType { /// 最终识别结果 finalResult, /// 中间识别结果(实时反馈) intermediateResult, /// 翻译结果 translationResult, /// 翻译中(实时反馈) translationInterim, /// 会话开始 sessionStarted, /// 会话结束 sessionStopped, /// 识别取消 canceled, /// 识别错误 error, } // 识别事件 class ASTEvent { /// 事件类型 final ASTEventType type; /// 识别ID final String utteranceId; /// 服务ID(A/B) final String serviceId; /// 识别文本(仅在 finalResult 和 intermediateResult 类型中有效) final String text; /// 检测到的语言 final String detectedLanguage; /// 原始音频 final Uint8List? audio; /// 错误信息(仅在 error 和 canceled 类型中有效) final String error; ASTEvent({ required this.type, this.utteranceId = '', this.text = '', this.detectedLanguage = '', this.audio, this.error = '', this.serviceId = '', }); /// 创建最终结果事件的快捷构造函数 factory ASTEvent.finalResult({ required String text, String utteranceId = '', String detectedLanguage = '', String serviceId = '', }) { return ASTEvent( type: ASTEventType.finalResult, utteranceId: utteranceId, text: text, detectedLanguage: detectedLanguage, serviceId: serviceId, ); } /// 创建错误事件的快捷构造函数 factory ASTEvent.error(String errorMessage) { return ASTEvent( type: ASTEventType.error, error: errorMessage, ); } /// 检查是否为最终结果 bool get isFinalResult => type == ASTEventType.finalResult; /// 检查是否为错误 bool get isError => type == ASTEventType.error || type == ASTEventType.canceled; @override String toString() { return 'ASTEvent{type: $type, text: $text, detectedLanguage: $detectedLanguage, error: $error}'; } }