Browse Source

播报打断开关控制

newdev_shunjiawei
fdp 1 year ago
parent
commit
6a86e9b9c0
  1. 15
      lib/modules/agent/controllers/agent_controller.dart
  2. 33
      lib/modules/agent/views/agent_view.dart
  3. 22
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt
  4. 9
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt
  5. 1
      local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt
  6. 9
      local_plugins/agent_service/lib/agent_service.dart

15
lib/modules/agent/controllers/agent_controller.dart

@ -80,6 +80,8 @@ class AgentController extends GetxController with WidgetsBindingObserver {
final isProcessing = false.obs; final isProcessing = false.obs;
// TTS启用状态 // TTS启用状态
final isTtsEnabled = true.obs; final isTtsEnabled = true.obs;
// TTS播报打断启用状态
final isTtsInterruptEnabled = true.obs;
// 图片处理状态 // 图片处理状态
final isImageProcessing = false.obs; final isImageProcessing = false.obs;
@ -260,6 +262,19 @@ class AgentController extends GetxController with WidgetsBindingObserver {
} }
} }
/// 切换TTS播报打断状态
/// 当启用播报打断时,用户说话会自动停止当前的TTS播放
Future<void> toggleTtsInterrupt() async {
isTtsInterruptEnabled.toggle();
// 保存偏好设置
try {
await AgentService.isInterrupt();
} catch (e) {
Logger.e(TAG, '保存TTS播报打断偏好设置失败: $e');
}
}
// 设置文本输入监听器 // 设置文本输入监听器
void _setupTextInputListener() { void _setupTextInputListener() {
textController.addListener(() { textController.addListener(() {

33
lib/modules/agent/views/agent_view.dart

@ -172,6 +172,39 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
), ),
color: isDarkMode ? Colors.grey[800] : Colors.white, color: isDarkMode ? Colors.grey[800] : Colors.white,
itemBuilder: (context) => [ itemBuilder: (context) => [
// 播报打断开关选项
PopupMenuItem(
child: Obx(() => Row(
children: [
Icon(
controller.isTtsInterruptEnabled.value
? Icons.voice_over_off
: Icons.voice_over_off_outlined,
color: controller.isTtsInterruptEnabled.value
? primaryColor
: (isDarkMode ? Colors.grey[400] : Colors.grey),
size: 20.sp,
),
SizedBox(width: 8.w),
Text(
//'ttsInterruptToggle'.tr,
"播报打断",
style: TextStyle(fontSize: 14.sp),
),
const Spacer(),
Switch(
value: controller.isTtsInterruptEnabled.value,
onChanged: (value) =>
controller.toggleTtsInterrupt(),
activeColor: primaryColor,
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
),
],
)),
onTap: () => controller.toggleTtsInterrupt(),
),
// 清除聊天记录选项
PopupMenuItem( PopupMenuItem(
child: Row( child: Row(
children: [ children: [

22
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentService.kt

@ -58,6 +58,9 @@ interface AgentServiceListener {
object AgentService : CoroutineScope { object AgentService : CoroutineScope {
private val TAG = "AgentService" private val TAG = "AgentService"
private var _isInterrupt = AtomicBoolean(true)
private var azureSpeechKey: String = "" private var azureSpeechKey: String = ""
private var azureSpeechRegion: String = "" private var azureSpeechRegion: String = ""
@ -359,6 +362,9 @@ object AgentService : CoroutineScope {
sendEvent("playback_started", mapOf("status" to "playback_started")) sendEvent("playback_started", mapOf("status" to "playback_started"))
// 确保气泡音已停止,避免与TTS播放重叠 // 确保气泡音已停止,避免与TTS播放重叠
audioPlayer?.stopAudio() audioPlayer?.stopAudio()
if(_isInterrupt.get()){
BleService.closeCodec()
}
// 发送AI说话开始广播 // 发送AI说话开始广播
val intent = val intent =
Intent("com.yunqiinnovation.music_service.AI_SAY_START").apply { Intent("com.yunqiinnovation.music_service.AI_SAY_START").apply {
@ -382,6 +388,9 @@ object AgentService : CoroutineScope {
setPackage(context.packageName) setPackage(context.packageName)
} }
context.sendBroadcast(intent) context.sendBroadcast(intent)
if(currentRecognitionMode == "ble_wakeup"&&_isInterrupt.get()){
BleService.openEncoder()
}
if(isplaymusic){ if(isplaymusic){
isplaymusic = false isplaymusic = false
Log.e(TAG, "QQ 音乐恢复播放") Log.e(TAG, "QQ 音乐恢复播放")
@ -513,7 +522,17 @@ object AgentService : CoroutineScope {
startIdleCheckForMode(currentRecognitionMode) startIdleCheckForMode(currentRecognitionMode)
} }
} }
/**
* 切换中断状态
* 如果当前为false,则设置为true;如果当前为true,则设置为false
* @return 切换后的状态值
*/
fun isInterrupt(): Boolean {
val currentValue = _isInterrupt.get()
val newValue = !currentValue
_isInterrupt.set(newValue)
return newValue
}
/** /**
* 开始语音识别 * 开始语音识别
* @param isExternalActive 是否使用外部音频源(蓝牙) * @param isExternalActive 是否使用外部音频源(蓝牙)
@ -997,6 +1016,7 @@ object AgentService : CoroutineScope {
override fun onComplete(sessionid: String) { override fun onComplete(sessionid: String) {
try { try {
if (sessionid == currsessionId) { if (sessionid == currsessionId) {
audioPlayer?.stopAudio() audioPlayer?.stopAudio()
} }
// 视情况决定是否朗读回复 // 视情况决定是否朗读回复

9
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/AgentServicePlugin.kt

@ -128,6 +128,15 @@ class AgentServicePlugin : FlutterPlugin, MethodCallHandler, EventChannel.Stream
result.error("START_ERROR", "启动对话失败: ${e.message}", null) result.error("START_ERROR", "启动对话失败: ${e.message}", null)
} }
} }
"isInterrupt" -> {
try {
val isInterrupt = AgentService.isInterrupt()
result.success(isInterrupt)
} catch (e: Exception) {
Log.e(TAG, "检查是否打断失败", e)
result.error("IS_INTERRUPT_ERROR", "检查是否打断失败: ${e.message}", null)
}
}
"recognizeCallback" -> { "recognizeCallback" -> {
val isStarted = AgentService.recognizeCallback() val isStarted = AgentService.recognizeCallback()
result.success(isStarted) result.success(isStarted)

1
local_plugins/agent_service/android/src/main/kotlin/com/yunqiinnovation/agent_service/BleAgent.kt

@ -66,6 +66,7 @@ object BleAgent : BleService.Callback, AgentServiceListener {
return false return false
} }
Log.d(TAG, "手动启动语音识别: ") Log.d(TAG, "手动启动语音识别: ")
AgentService.interruptCurrentResponse()
return AgentService.startRecognition(true, "ble_wakeup") return AgentService.startRecognition(true, "ble_wakeup")
} }

9
local_plugins/agent_service/lib/agent_service.dart

@ -266,6 +266,15 @@ class AgentService {
} }
} }
static Future<bool> isInterrupt() async {
try {
final bool result = await _channel.invokeMethod('isInterrupt');
return result;
} on PlatformException catch (e) {
throw AgentServiceException(e.code, e.message ?? '检查是否打断失败', e.details);
}
}
/// 设备识别器 /// 设备识别器
/// ///
/// 启动语音识别,开始监听用户语音输入 /// 启动语音识别,开始监听用户语音输入

Loading…
Cancel
Save