Browse Source

v001

newdev_shunjiawei
wolfplus 2 years ago
parent
commit
fffd010150
  1. 4
      android/app/src/main/kotlin/com/example/deep_voice/AzureAsrHelper.kt
  2. 6
      android/app/src/main/kotlin/com/example/deep_voice/AzureTtsHelper.kt
  3. 55
      android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt
  4. 32
      ios/Runner/AzureAsrHelper.swift
  5. 18
      lib/data/services/speech_impl/azure_tts_service.dart
  6. 8
      lib/modules/chat/controllers/chat_controller.dart
  7. 11
      lib/modules/translation/bindings/translation_binding.dart

4
android/app/src/main/kotlin/com/example/deep_voice/AzureAsrHelper.kt

@ -166,7 +166,7 @@ class AzureAsrHelper(private val context: Context) {
} else { } else {
currentLanguage currentLanguage
} }
FileLogger.d(TAG, "最终识别结果: ${event.result.text}") // FileLogger.d(TAG, "最终识别结果: ${event.result.text}")
callback.onResult(event.result.text, detectedLanguage) callback.onResult(event.result.text, detectedLanguage)
} }
} }
@ -181,7 +181,7 @@ class AzureAsrHelper(private val context: Context) {
} else { } else {
currentLanguage currentLanguage
} }
FileLogger.d(TAG, "识别中结果: ${event.result.text}") // FileLogger.d(TAG, "识别中结果: ${event.result.text}")
callback.onRecognizing(event.result.text, detectedLanguage) callback.onRecognizing(event.result.text, detectedLanguage)
} }
} }

6
android/app/src/main/kotlin/com/example/deep_voice/AzureTtsHelper.kt

@ -279,7 +279,7 @@ class AzureTtsHelper(private val context: Context) {
*/ */
fun speakText(text: String, callback: TTSCallback) { fun speakText(text: String, callback: TTSCallback) {
if (!isInitialized) { if (!isInitialized) {
callback.onError("TTS 引擎尚未初始化") callback.onError("TTS 引擎尚未初始化===")
return return
} }
@ -361,8 +361,8 @@ class AzureTtsHelper(private val context: Context) {
callback.onError("语音合成取消: ${cancellation.reason}, ${cancellation.errorDetails}") callback.onError("语音合成取消: ${cancellation.reason}, ${cancellation.errorDetails}")
} }
else -> { else -> {
FileLogger.e(TAG, "语音合成失败: ${result.reason}") FileLogger.e(TAG, "语音合成失败kt: ${result.reason}")
callback.onError("语音合成失败: ${result.reason}") callback.onError("语音合成失败kt: ${result.reason}")
} }
} }

55
android/app/src/main/kotlin/com/example/deep_voice/VoiceInteractionService.kt

@ -220,9 +220,33 @@ class VoiceInteractionService : Service() {
// 设置回调 // 设置回调
mediaSession.setCallback(object : MediaSessionCompat.Callback() { mediaSession.setCallback(object : MediaSessionCompat.Callback() {
override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean { override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean {
FileLogger.d(TAG, "initMediaSession收到媒体按钮事件: $mediaButtonEvent") val keyEvent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
handleDoubleClick() mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT, KeyEvent::class.java)
return true } else {
@Suppress("DEPRECATION")
mediaButtonEvent.getParcelableExtra(Intent.EXTRA_KEY_EVENT) as? KeyEvent
}
if (keyEvent != null) {
// 仅处理按下操作和相关按键
if (keyEvent.action == KeyEvent.ACTION_DOWN) {
when (keyEvent.keyCode) {
KeyEvent.KEYCODE_HEADSETHOOK,
KeyEvent.KEYCODE_MEDIA_PLAY,
KeyEvent.KEYCODE_MEDIA_PAUSE,
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
FileLogger.d(TAG, "接收到相关媒体按钮: keyCode=${keyEvent.keyCode}")
handleDoubleClick()
return true
}
}
}
FileLogger.d(TAG, "忽略不相关媒体按钮: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}")
return false
}
FileLogger.d(TAG, "收到无按键的媒体按钮事件")
return false
} }
override fun onPlay() { override fun onPlay() {
@ -650,10 +674,8 @@ class VoiceInteractionService : Service() {
if (keyEvent != null) { if (keyEvent != null) {
FileLogger.d(TAG, "从Intent中解析到按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") FileLogger.d(TAG, "从Intent中解析到按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}")
// 使用统一的按键处理逻辑
handleKeyEvent(keyEvent) handleKeyEvent(keyEvent)
} else {
FileLogger.d(TAG, "Intent中没有按键事件,直接处理双击")
handleDoubleClick()
} }
} else if (intent?.action == ACTION_PAUSE_VOICE_INTERACTION) { } else if (intent?.action == ACTION_PAUSE_VOICE_INTERACTION) {
// 处理来自 Flutter 的暂停请求 // 处理来自 Flutter 的暂停请求
@ -663,7 +685,7 @@ class VoiceInteractionService : Service() {
FileLogger.d(TAG, "收到其他Intent: action=${intent?.action}") FileLogger.d(TAG, "收到其他Intent: action=${intent?.action}")
} }
// 让 MediaSession 处理 Intent // 让 MediaSession 处理 Intent,MediaSession将通过callback处理事件
try { try {
MediaButtonReceiver.handleIntent(mediaSession, intent) MediaButtonReceiver.handleIntent(mediaSession, intent)
FileLogger.d(TAG, "MediaButtonReceiver处理Intent完成") FileLogger.d(TAG, "MediaButtonReceiver处理Intent完成")
@ -680,14 +702,13 @@ class VoiceInteractionService : Service() {
private fun handleKeyEvent(keyEvent: KeyEvent) { private fun handleKeyEvent(keyEvent: KeyEvent) {
FileLogger.d(TAG, "处理按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}") FileLogger.d(TAG, "处理按键事件: action=${keyEvent.action}, keyCode=${keyEvent.keyCode}")
// 只处理按下操作和相关媒体按键
if (keyEvent.action == KeyEvent.ACTION_DOWN) { if (keyEvent.action == KeyEvent.ACTION_DOWN) {
when (keyEvent.keyCode) { when (keyEvent.keyCode) {
KeyEvent.KEYCODE_MEDIA_PLAY -> { KeyEvent.KEYCODE_MEDIA_PLAY,
FileLogger.d(TAG, "处理MEDIA_PLAY按键") KeyEvent.KEYCODE_MEDIA_PAUSE,
handleDoubleClick() KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
} FileLogger.d(TAG, "处理标准媒体按键: ${keyEvent.keyCode}")
KeyEvent.KEYCODE_MEDIA_PAUSE -> {
FileLogger.d(TAG, "处理MEDIA_PAUSE按键")
handleDoubleClick() handleDoubleClick()
} }
KeyEvent.KEYCODE_HEADSETHOOK -> { KeyEvent.KEYCODE_HEADSETHOOK -> {
@ -712,16 +733,12 @@ class VoiceInteractionService : Service() {
} }
lastKeyEventTime = currentTime lastKeyEventTime = currentTime
} }
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
FileLogger.d(TAG, "处理MEDIA_PLAY_PAUSE按键")
handleDoubleClick()
}
else -> { else -> {
FileLogger.d(TAG, "处理其他按键: ${keyEvent.keyCode}") FileLogger.d(TAG, "忽略不相关的按键: ${keyEvent.keyCode}")
} }
} }
} else { } else {
FileLogger.d(TAG, "非ACTION_DOWN事件: ${keyEvent.action}") FileLogger.d(TAG, "忽略非ACTION_DOWN事件: ${keyEvent.action}")
} }
} }

32
ios/Runner/AzureAsrHelper.swift

@ -338,35 +338,19 @@ class AzureAsrHelper: NSObject {
_isContinuousRecognitionActive = false _isContinuousRecognitionActive = false
do { do {
try recognizer.stopContinuousRecognition() DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
do {
try recognizer.stopContinuousRecognition()
} catch {
print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)")
}
}
} catch { } catch {
print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)") print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)")
} }
// // 异步执行停止操作,避免阻塞主线程
// DispatchQueue.global(qos: .userInitiated).async { [weak self] in
// guard let self = self else { return }
// do {
// // 在后台线程执行停止操作
// try recognizer.stopContinuousRecognition()
// // 主线程回调通知结果
// DispatchQueue.main.async {
// print("[AzureAsrHelper] 连续识别已停止")
// self.eventHandler("sessionStopped", [:])
// }
// } catch {
// // 主线程回调通知错误
// DispatchQueue.main.async {
// print("[AzureAsrHelper] 错误: 停止连续识别失败: \(error.localizedDescription)")
// // 停止失败,恢复状态
// self._isContinuousRecognitionActive = true
// self.eventHandler("error", ["error": "停止识别失败: \(error.localizedDescription)"])
// }
// }
// }
// 立即返回,不阻塞调用方 // 立即返回,不阻塞调用方
return true return true

18
lib/data/services/speech_impl/azure_tts_service.dart

@ -94,26 +94,22 @@ class AzureTtsService extends GetxService implements TtsService {
return false; return false;
} }
// 始终优先使用中文作为默认语言
final String defaultLanguage = 'zh-CN';
// 更新支持的语音列表(如果提供) // 更新支持的语音列表(如果提供)
if (supportedLanguages != null && supportedLanguages.isNotEmpty) { final String language = supportedLanguages?.first ?? 'zh-CN';
// 如果支持中文,优先使用中文,否则使用提供的第一种语言
String language = supportedLanguages.contains(defaultLanguage)
? defaultLanguage
: supportedLanguages.first;
final result = await _channel.invokeMethod('initialize', { final result = await _channel.invokeMethod('initialize', {
'subscriptionKey': _subscriptionKey, 'subscriptionKey': _subscriptionKey,
'region': _serviceRegion, 'region': _serviceRegion,
'language': language, 'language': language,
}); });
_isInitialized = result; _isInitialized = true;
return result; return result;
}
return true;
} catch (e) { } catch (e) {
Logger.error('初始化失败: $e'); Logger.error('初始化失败: $e');
return false; return false;
@ -180,7 +176,7 @@ class AzureTtsService extends GetxService implements TtsService {
} catch (e) { } catch (e) {
// 发生错误时重置状态 // 发生错误时重置状态
_speakingCache = false; _speakingCache = false;
Logger.error('语音合成失败: $e'); Logger.error('1语音合成失败: $e');
return false; return false;
} }
} }

8
lib/modules/chat/controllers/chat_controller.dart

@ -15,8 +15,8 @@ import '../../../data/services/voice_interaction_service.dart';
class ChatController extends GetxController { class ChatController extends GetxController {
// 服务 // 服务
final VolcanoAIService _aiService = Get.find<VolcanoAIService>(); final VolcanoAIService _aiService = Get.find<VolcanoAIService>();
late TtsService _ttsService; final TtsService _ttsService = Get.find<TtsService>();
late AsrService _asrService; final AsrService _asrService = Get.find<AsrService>();
final ChatHistoryService _historyService = Get.find<ChatHistoryService>(); final ChatHistoryService _historyService = Get.find<ChatHistoryService>();
final VoiceInteractionService _voiceInteractionService = Get.find<VoiceInteractionService>(); final VoiceInteractionService _voiceInteractionService = Get.find<VoiceInteractionService>();
@ -83,8 +83,8 @@ class ChatController extends GetxController {
agent = foundAgent; agent = foundAgent;
_ttsService = Get.find<TtsService>(); _ttsService.initialize();
_asrService = Get.find<AsrService>(); _asrService.initialize();
// 设置语音交互模式 // 设置语音交互模式
_isVoiceInteractionMode = args['isVoiceInteraction'] == true; _isVoiceInteractionMode = args['isVoiceInteraction'] == true;

11
lib/modules/translation/bindings/translation_binding.dart

@ -1,19 +1,10 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../controllers/translation_controller.dart'; import '../controllers/translation_controller.dart';
import '../../../data/services/speech_impl/azure_asr_service.dart';
import '../../../data/services/speech_impl/azure_tts_service.dart';
import '../../../data/services/asr_service.dart';
import '../../../data/services/tts_service.dart';
import '../../../data/services/volcano_translation_service.dart';
import '../../../data/services/language_manager.dart';
class TranslationBinding implements Bindings { class TranslationBinding implements Bindings {
@override @override
void dependencies() { void dependencies() {
Get.put(LanguageManager(), permanent: true);
Get.lazyPut<AsrService>(() => AzureAsrService(), fenix: true);
Get.lazyPut<TtsService>(() => AzureTtsService(), fenix: true);
Get.put(VolcanoTranslationService(), permanent: true);
Get.put(TranslationController()); Get.put(TranslationController());
} }
} }
Loading…
Cancel
Save