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.
164 lines
5.0 KiB
164 lines
5.0 KiB
import 'dart:async';
|
|
import '../../../data/models/appconfig.dart';
|
|
import 'package:flutter/services.dart';
|
|
import '../../../core/utils/logger.dart';
|
|
import 'package:get/get.dart';
|
|
import '../ast_service.dart';
|
|
|
|
/// 音频源类型
|
|
enum AudioSourceType {
|
|
microphone, // 使用设备麦克风
|
|
external // 使用外部提供的音频数据
|
|
}
|
|
|
|
/// Azure 语音识别服务
|
|
///
|
|
/// 该服务提供了通过平台通道与原生 Microsoft Speech SDK 交互的接口
|
|
class AzureAstService extends GetxService implements AstService {
|
|
static final AzureAstService to = Get.put(AzureAstService());
|
|
static const MethodChannel _channel = MethodChannel('azure_speech/ast');
|
|
static const EventChannel _eventChannel =
|
|
EventChannel('azure_speech/ast_events');
|
|
// final GetStorage _storage = GetStorage();
|
|
bool _isInitialized = false;
|
|
late final String _subscriptionKey;
|
|
late final String _serviceRegion;
|
|
late String _baseUrl;
|
|
final String _endpoint = '/'; // 修改为根路径
|
|
late final String _accessKey;
|
|
late final String _secretKey;
|
|
late final String _region;
|
|
late final String _service;
|
|
|
|
final List<String> _defaultSupportedLanguages = ['zh-CN', 'en-US'];
|
|
@override
|
|
List<String> get supportedLanguages => _defaultSupportedLanguages;
|
|
|
|
// 连续识别相关
|
|
// bool _isContinuousRecognitionActive = false;
|
|
// StreamController<RecognitionEvent>? _eventStreamController;
|
|
// StreamSubscription? _eventSubscription;
|
|
|
|
// 最新的识别结果
|
|
String _latestRecognizedText = '';
|
|
String get latestRecognizedText => _latestRecognizedText;
|
|
|
|
// 最新检测到的语言
|
|
String _latestDetectedLanguage = '';
|
|
String get latestDetectedLanguage => _latestDetectedLanguage;
|
|
|
|
// 当前音频源类型
|
|
AudioSourceType _audioSourceType = AudioSourceType.microphone;
|
|
|
|
AzureAstService() {
|
|
_loadConfig();
|
|
}
|
|
|
|
/// 从环境变量加载配置
|
|
void _loadConfig() {
|
|
// final _env = _storage.read("ENV") as Map<String, String>;
|
|
_subscriptionKey = AppConfig.env('AZURE_SPEECH_KEY') ?? '';
|
|
_serviceRegion = AppConfig.env('AZURE_SPEECH_REGION') ?? '';
|
|
_accessKey = AppConfig.env('VOLCANO_TRANSLATION_ACCESS_KEY') ?? '';
|
|
_secretKey = AppConfig.env('VOLCANO_TRANSLATION_SECRET_KEY') ?? '';
|
|
_region = AppConfig.env('VOLCANO_TRANSLATION_REGION') ?? 'cn-north-1';
|
|
_service = 'translate';
|
|
_baseUrl = 'https://translate.volcengineapi.com';
|
|
if (_subscriptionKey.isEmpty || _serviceRegion.isEmpty) {
|
|
throw Exception(
|
|
'未找到 Azure 语音服务配置。请在 .env 文件中设置 AZURE_SPEECH_KEY 和 AZURE_SPEECH_REGION');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<bool> enableRecord(String filePath) async {
|
|
try {
|
|
final bool result = await _channel.invokeMethod('enableRecord', {
|
|
'filePath': filePath,
|
|
});
|
|
|
|
return result;
|
|
} catch (e) {
|
|
Logger.error('开始录音: ${e.toString()}');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<bool> path(String filePath) async {
|
|
try {
|
|
final bool result = await _channel.invokeMethod('path', {
|
|
'filePath': filePath,
|
|
});
|
|
|
|
return result;
|
|
} catch (e) {
|
|
Logger.error('开始录音: ${e.toString()}');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<bool> stopContinuousTranslation(bool isSave) async {
|
|
try {
|
|
final bool result =
|
|
await _channel.invokeMethod('stopContinuousTranslation', {
|
|
'isSave': isSave,
|
|
});
|
|
|
|
return result;
|
|
} catch (e) {
|
|
Logger.error('停止录音: ${e.toString()}');
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
@override
|
|
Future<bool> initialize({
|
|
List<String>? supportedLanguages,
|
|
bool useExternalAudio = false,
|
|
bool useEchoCancellation = false,
|
|
}) async {
|
|
try {
|
|
final List<String> languages =
|
|
supportedLanguages ?? _defaultSupportedLanguages;
|
|
//底层会初始化前释放
|
|
// // 检查是否需要重新初始化
|
|
// if (_isInitialized) {
|
|
// await dispose();
|
|
// }
|
|
|
|
// 设置音频源类型
|
|
_audioSourceType = useExternalAudio
|
|
? AudioSourceType.external
|
|
: AudioSourceType.microphone;
|
|
// Future<bool> initialize({
|
|
// required String subscriptionKey,
|
|
// required String region,
|
|
// required List<String> supportedLanguages,
|
|
// required String audioSourceType,
|
|
// required String translationAccessKey,
|
|
// required String translationSecretKey,
|
|
// String translationRegion = 'cn-north-1',
|
|
// });
|
|
|
|
final bool result = await _channel.invokeMethod('initialize', {
|
|
'subscriptionKey': _subscriptionKey,
|
|
'region': _serviceRegion,
|
|
'supportedLanguages': languages,
|
|
'audioSourceType': _audioSourceType.toString().split('.').last,
|
|
'translationAccessKey': _accessKey,
|
|
'translationSecretKey': _secretKey,
|
|
'translationRegion': _region,
|
|
});
|
|
|
|
_isInitialized = result;
|
|
Logger.info('Azure 语音识别服务初始化${result ? '成功' : '失败'}');
|
|
return result;
|
|
} catch (e) {
|
|
Logger.error('Azure 语音识别服务初始化失败: ${e.toString()}');
|
|
_isInitialized = false;
|
|
rethrow;
|
|
}
|
|
}
|
|
}
|
|
|