import 'dart:async'; import 'package:audio_service/audio_service.dart'; import 'package:get/get.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'background_agent_service.dart'; import '../../data/providers/agent_provider.dart'; /// 自定义 AudioHandler,用于捕获媒体按键事件(例如蓝牙耳机按钮) class MyAudioHandler extends BaseAudioHandler { // 定义一个 StreamController 用于向 UI 发送自定义事件 final StreamController _customEventController = StreamController.broadcast(); bool _isDisposed = false; BackgroundAgentService? _backgroundAgent; String _systemPrompt = ''; // 添加一个标志,表示是否正在处理交互 bool _isHandlingInteraction = false; Stream get customEventStream => _customEventController.stream; MyAudioHandler() { _initializeHandler(); _initializeBackgroundAgent(); _initializeSystemPrompt(); print('MyAudioHandler 已创建,准备接收媒体按钮事件'); } void _initializeSystemPrompt() { try { final agent = AgentProvider.getAgentById('personal_assistant'); _systemPrompt = agent?.systemPrompt ?? ''; } catch (e) { print('初始化 SystemPrompt 失败: $e'); _systemPrompt = ''; } } void _initializeBackgroundAgent() { try { if (Get.isRegistered()) { _backgroundAgent = Get.find(); } else { _backgroundAgent = Get.put(BackgroundAgentService(), permanent: true); } print('BackgroundAgent 初始化成功'); } catch (e) { print('初始化 BackgroundAgent 失败: $e'); _backgroundAgent = null; } } void _initializeHandler() { try { // 设置初始播放状态 playbackState.add(PlaybackState( controls: [ MediaControl.play, MediaControl.pause, MediaControl.stop, MediaControl.skipToPrevious, MediaControl.skipToNext, ], systemActions: { MediaAction.play, MediaAction.pause, MediaAction.stop, MediaAction.skipToPrevious, MediaAction.skipToNext, MediaAction.seek, }, androidCompactActionIndices: const [0, 1, 2], processingState: AudioProcessingState.idle, playing: false, )); // 设置媒体元数据 final item = MediaItem( id: 'deep_voice_audio', title: 'Deep Voice Audio', album: 'Deep Voice', artist: 'Deep Voice', genre: 'Speech', duration: const Duration(seconds: 1), artUri: null, // 移除图片URI playable: true, displayTitle: 'Deep Voice Audio', displaySubtitle: 'Voice Assistant', displayDescription: 'TTS Audio', extras: const {'source': 'deep_voice'}, ); mediaItem.add(item); print('AudioHandler 媒体项已设置'); } catch (e) { print('初始化 AudioHandler 失败: $e'); } } // 更新播放状态 void _updatePlaybackState({ required bool playing, required AudioProcessingState processingState, }) { if (_isDisposed) return; try { playbackState.add(playbackState.value.copyWith( playing: playing, processingState: processingState, updatePosition: Duration.zero, )); } catch (e) { print('更新播放状态失败: $e'); } } Future _handleInteraction() async { print('处理媒体按钮交互'); // 防止重复处理 if (_isHandlingInteraction) { print('已经在处理交互,忽略此次请求'); return; } _isHandlingInteraction = true; try { if (_systemPrompt.isEmpty) { print('系统提示为空,无法激活语音助手'); return; } if (Get.context != null && WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) { // 应用在前台,导航到聊天页面 print('应用在前台,导航到聊天页面'); final agent = AgentProvider.getAgentById('personal_assistant'); if (agent != null) { // 导航到聊天页面,并标记需要在进入时播放语音应答 Get.toNamed('/chat', arguments: { 'agentId': agent.id, 'agentName': agent.name, 'agentAvatar': agent.avatarUrl, 'agentSubtitle': agent.description, 'systemPrompt': agent.systemPrompt, 'welcomeMessage': agent.welcomeMessage, 'playVoiceOnEnter': true, }); } } else { // 应用在后台,使用 BackgroundAgent 处理交互 print('应用在后台,使用 BackgroundAgent 处理交互'); if (_backgroundAgent != null) { // 调用 BackgroundAgent 的语音识别和 AI 交互功能 await _backgroundAgent!.handleAgentInteraction(_systemPrompt); } else { print('BackgroundAgent 未初始化,无法处理交互'); } } } catch (e) { print('处理媒体按钮交互失败: $e'); } finally { _isHandlingInteraction = false; } } @override Future play() async { print('收到播放命令'); try { await _handleInteraction(); _updatePlaybackState( playing: true, processingState: AudioProcessingState.ready, ); } catch (e) { print('处理播放命令失败: $e'); } } @override Future pause() async { print('收到暂停命令'); try { await _handleInteraction(); _updatePlaybackState( playing: false, processingState: AudioProcessingState.ready, ); } catch (e) { print('处理暂停命令失败: $e'); } } @override Future stop() async { print('停止 AudioHandler'); _isDisposed = true; try { await super.stop(); _customEventController.close(); _updatePlaybackState( playing: false, processingState: AudioProcessingState.idle, ); } catch (e) { print('停止 AudioHandler 时发生错误: $e'); } } @override Future skipToPrevious() async { print('收到上一曲命令'); try { await _handleInteraction(); } catch (e) { print('处理上一曲命令失败: $e'); } } @override Future skipToNext() async { print('收到下一曲命令'); try { await _handleInteraction(); } catch (e) { print('处理下一曲命令失败: $e'); } } @override Future seek(Duration position) async { print('收到跳转命令: $position'); } @override Future customAction(String name, [Map? extras]) async { print('收到自定义命令: $name'); try { if (name == 'media_button') { print('收到媒体按钮事件'); await _handleInteraction(); } } catch (e) { print('处理自定义命令失败: $e'); } return null; } @override Future onTaskRemoved() async { print('服务被系统移除'); try { await stop(); } catch (e) { print('处理服务移除失败: $e'); } } @override Future onNotificationDeleted() async { print('通知被用户移除'); try { await stop(); } catch (e) { print('处理通知移除失败: $e'); } } }