Update: 2026-05-07 18:29:37

This commit is contained in:
Hamza-Ayed
2026-05-07 18:29:38 +03:00
parent 230609e0a0
commit 10432e7b81
2 changed files with 50 additions and 5 deletions

View File

@@ -11,10 +11,20 @@ class VoiceAssistantService {
Future<Map<String, dynamic>> processVoiceCommand(File audioFile) async { Future<Map<String, dynamic>> processVoiceCommand(File audioFile) async {
final fileName = audioFile.uri.pathSegments.isNotEmpty final fileName = audioFile.uri.pathSegments.isNotEmpty
? audioFile.uri.pathSegments.last ? 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({ 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( final response = await _dio.post(
@@ -40,4 +50,14 @@ class VoiceAssistantService {
AppLogger.print('Voice API success: ${body['message']}'); AppLogger.print('Voice API success: ${body['message']}');
return Map<String, dynamic>.from(payload); return Map<String, dynamic>.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';
}
} }

View File

@@ -250,12 +250,37 @@ class DashboardController extends GetxController {
} }
final tempDir = await getTemporaryDirectory(); 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 = 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( await _audioRecorder.start(
const RecordConfig( RecordConfig(
encoder: AudioEncoder.wav, encoder: encoder,
sampleRate: 16000, sampleRate: 16000,
numChannels: 1, numChannels: 1,
), ),