Update: 2026-05-07 18:27:10
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user