diff --git a/app/modules_app/voice/transcribe.php b/app/modules_app/voice/transcribe.php index d18f476..0522e22 100644 --- a/app/modules_app/voice/transcribe.php +++ b/app/modules_app/voice/transcribe.php @@ -49,7 +49,11 @@ if ($rawAudio === false) { } $base64Audio = base64_encode($rawAudio); -$mimeType = detectAudioMimeType($tmpPath, (string)($audio['type'] ?? 'audio/m4a')); +$mimeType = detectAudioMimeType( + $tmpPath, + (string)($audio['type'] ?? ''), + (string)($audio['name'] ?? '') +); $intent = extractIntentFromAudio($base64Audio, $mimeType, $geminiApiKey); $execution = executeVoiceAction($decoded, $intent); @@ -58,19 +62,17 @@ json_success([ 'execution' => $execution, ], 'تم تحليل الأمر الصوتي وتنفيذه'); -function detectAudioMimeType(string $path, string $fallback): string +function detectAudioMimeType(string $path, string $fallback, string $fileName = ''): string { $allowed = [ - 'audio/mpeg', 'audio/mp3', - 'audio/mp4', - 'audio/m4a', + 'audio/mpeg', 'audio/wav', 'audio/x-wav', - 'audio/webm', - 'audio/ogg', + 'audio/aiff', 'audio/aac', - 'audio/x-m4a', + 'audio/ogg', + 'audio/flac', ]; $detected = $fallback; @@ -85,8 +87,13 @@ function detectAudioMimeType(string $path, string $fallback): string } } - // Keep a safe supported fallback for Gemini audio understanding. - return in_array($detected, $allowed, true) ? $detected : 'audio/m4a'; + if ($detected === 'audio/x-wav' || str_ends_with(strtolower($fileName), '.wav')) { + return 'audio/wav'; + } + + // The Flutter recorder now sends WAV. If the server cannot detect the part + // MIME type, use a Gemini-supported fallback instead of m4a/mp4. + return in_array($detected, $allowed, true) ? $detected : 'audio/wav'; } function extractIntentFromAudio(string $base64Audio, string $mimeType, string $apiKey): array diff --git a/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart b/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart index 62cd59a..f44948b 100644 --- a/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart +++ b/musadaq-app/lib/features/dashboard/controllers/dashboard_controller.dart @@ -251,14 +251,13 @@ class DashboardController extends GetxController { final tempDir = await getTemporaryDirectory(); final path = - '${tempDir.path}/voice_${DateTime.now().millisecondsSinceEpoch}.m4a'; + '${tempDir.path}/voice_${DateTime.now().millisecondsSinceEpoch}.wav'; await _audioRecorder.start( const RecordConfig( - encoder: AudioEncoder.aacLc, + encoder: AudioEncoder.wav, sampleRate: 16000, numChannels: 1, - bitRate: 64000, ), path: path, );