From 10432e7b81f2847b4a09fb0086636010a6a403d3 Mon Sep 17 00:00:00 2001 From: Hamza-Ayed Date: Thu, 7 May 2026 18:29:38 +0300 Subject: [PATCH] Update: 2026-05-07 18:29:37 --- .../services/voice_assistant_service.dart | 24 ++++++++++++-- .../controllers/dashboard_controller.dart | 31 +++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/musadaq-app/lib/core/services/voice_assistant_service.dart b/musadaq-app/lib/core/services/voice_assistant_service.dart index 31cee7c..0366b82 100644 --- a/musadaq-app/lib/core/services/voice_assistant_service.dart +++ b/musadaq-app/lib/core/services/voice_assistant_service.dart @@ -11,10 +11,20 @@ class VoiceAssistantService { Future> processVoiceCommand(File audioFile) async { final fileName = audioFile.uri.pathSegments.isNotEmpty ? audioFile.uri.pathSegments.last - : 'voice_command.m4a'; + : 'voice_command.wav'; + final mimeType = _mimeTypeForFileName(fileName); + final fileSize = await audioFile.length(); + + AppLogger.print( + 'Voice upload file=$fileName, bytes=$fileSize, mime=$mimeType, path=${audioFile.path}', + ); final formData = FormData.fromMap({ - 'audio': await MultipartFile.fromFile(audioFile.path, filename: fileName), + 'audio': await MultipartFile.fromFile( + audioFile.path, + filename: fileName, + contentType: DioMediaType.parse(mimeType), + ), }); final response = await _dio.post( @@ -40,4 +50,14 @@ class VoiceAssistantService { AppLogger.print('Voice API success: ${body['message']}'); return Map.from(payload); } + + String _mimeTypeForFileName(String fileName) { + final lower = fileName.toLowerCase(); + if (lower.endsWith('.wav')) return 'audio/wav'; + if (lower.endsWith('.flac')) return 'audio/flac'; + if (lower.endsWith('.mp3')) return 'audio/mp3'; + if (lower.endsWith('.aac')) return 'audio/aac'; + if (lower.endsWith('.ogg')) return 'audio/ogg'; + return 'audio/wav'; + } } diff --git a/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart b/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart index f44948b..9d6842e 100644 --- a/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart +++ b/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart @@ -250,12 +250,37 @@ class DashboardController extends GetxController { } final tempDir = await getTemporaryDirectory(); + final wavSupported = + await _audioRecorder.isEncoderSupported(AudioEncoder.wav); + final flacSupported = + await _audioRecorder.isEncoderSupported(AudioEncoder.flac); + + final AudioEncoder encoder; + final String extension; + if (wavSupported) { + encoder = AudioEncoder.wav; + extension = 'wav'; + } else if (flacSupported) { + encoder = AudioEncoder.flac; + extension = 'flac'; + } else { + AppSnackbar.showError( + 'الصوت', + 'هذا الجهاز لا يدعم صيغة صوت مناسبة لـ Gemini حالياً', + ); + return; + } + final path = - '${tempDir.path}/voice_${DateTime.now().millisecondsSinceEpoch}.wav'; + '${tempDir.path}/voice_${DateTime.now().millisecondsSinceEpoch}.$extension'; + + AppLogger.print( + 'Voice recorder selected encoder=$encoder, wavSupported=$wavSupported, flacSupported=$flacSupported, path=$path', + ); await _audioRecorder.start( - const RecordConfig( - encoder: AudioEncoder.wav, + RecordConfig( + encoder: encoder, sampleRate: 16000, numChannels: 1, ),