You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
3.7 KiB

import 'dart:async';
import 'dart:typed_data';
/// 语音识别服务接口
abstract class AsrService {
/// 支持的语言
List<String> get supportedLanguages;
/// 初始化语音识别服务
Future<bool> initialize({
List<String>? supportedLanguages,
});
/// 执行一次性语音识别
///
/// 返回识别的最终结果
Future<RecognitionEvent> recognizeOnce();
/// 开始连续语音识别
///
/// 返回一个包含识别事件的流
Future<bool> startContinuousRecognition(
bool audioSourceType, {
bool isRemoveFirstPunctuation = true,
});
/// 停止连续语音识别
Future<bool> stopContinuousRecognition();
/// 设置识别回掉
///
/// 返回一个包含识别事件的流
Future<Stream<RecognitionEvent>> recognizeCallback();
/// 恢复原始音频状态
Future<void> restoreOriginalAudioState();
/// 禁用蓝牙音频
Future<void> disableBluetoothAudio();
/// 检查连续识别是否活跃
bool isContinuousRecognitionActive();
/// 开始录音
///
/// [filePath] 录音文件路径
/// [audioSourceType] 音频源类型
/// [acceptAudioData] 是否接受音频数据回调,默认为 false
Future<bool> enableRecord(bool audioSourceType, String filePath,
{bool acceptAudioData = false});
/// 获取音频数据流(如果支持)
Stream<Uint8List>? getAudioDataStream() => null;
/// 暂停录音
Future<bool> pauseRecord();
/// 继续录音
Future<bool> resumeRecord();
/// 设置音频配置
Future<bool> setAudioConfig({
int sampleRate = 16000,
int channels = 1,
});
// /// 移动文件到新路径
Future<bool> moveFile(String sourcePath, String destPath);
// /// 重命名指定路径的音频文件
Future<bool> renameFile(String filePath, String newName);
/// 结束录音
Future<bool> stopRecord(bool isSave);
/// 释放资源
Future<void> dispose();
}
/// 识别事件类型
enum RecognitionEventType {
/// 最终识别结果
finalResult,
/// 麦识别结果
finalResult1,
/// 中间识别结果(实时反馈)
intermediateResult,
/// 会话开始
sessionStarted,
/// 会话结束
sessionStopped,
/// 识别取消
canceled,
/// 识别错误
error,
}
/// 识别事件
class RecognitionEvent {
/// 事件类型
final RecognitionEventType type;
/// 识别文本(仅在 finalResult 和 intermediateResult 类型中有效)
final String text;
/// 检测到的语言
final String detectedLanguage;
/// 角色
final String role;
/// 原始音频
final Uint8List? audio;
/// 错误信息(仅在 error 和 canceled 类型中有效)
final String error;
RecognitionEvent({
required this.type,
this.text = '',
this.detectedLanguage = '',
this.role = '',
this.audio,
this.error = '',
});
/// 创建最终结果事件的快捷构造函数
factory RecognitionEvent.finalResult({
required String text,
String detectedLanguage = '',
}) {
return RecognitionEvent(
type: RecognitionEventType.finalResult,
text: text,
detectedLanguage: detectedLanguage,
);
}
/// 创建错误事件的快捷构造函数
factory RecognitionEvent.error(String errorMessage) {
return RecognitionEvent(
type: RecognitionEventType.error,
error: errorMessage,
);
}
/// 检查是否为最终结果
bool get isFinalResult => type == RecognitionEventType.finalResult;
/// 检查是否为错误
bool get isError =>
type == RecognitionEventType.error ||
type == RecognitionEventType.canceled;
@override
String toString() {
return 'RecognitionEvent{type: $type, text: $text, detectedLanguage: $detectedLanguage, error: $error}';
}
}