feat: Implement audio recording and transcription for rapid order creation across platforms.

This commit is contained in:
Achintha Isuru
2026-02-27 11:49:17 -05:00
parent 52bdf48155
commit 55a31661a1
31 changed files with 260 additions and 21 deletions

View File

@@ -31,3 +31,4 @@ export 'src/services/device/camera/camera_service.dart';
export 'src/services/device/gallery/gallery_service.dart';
export 'src/services/device/file/file_picker_service.dart';
export 'src/services/device/file_upload/device_file_upload_service.dart';
export 'src/services/device/audio/audio_recorder_service.dart';

View File

@@ -40,6 +40,7 @@ class CoreModule extends Module {
i.addSingleton<CameraService>(() => CameraService(i.get<ImagePicker>()));
i.addSingleton<GalleryService>(() => GalleryService(i.get<ImagePicker>()));
i.addSingleton<FilePickerService>(FilePickerService.new);
i.addSingleton<AudioRecorderService>(AudioRecorderService.new);
i.addSingleton<DeviceFileUploadService>(
() => DeviceFileUploadService(
cameraService: i.get<CameraService>(),

View File

@@ -0,0 +1,55 @@
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:record/record.dart';
import 'package:krow_domain/krow_domain.dart';
/// Service for recording audio using the device microphone.
class AudioRecorderService extends BaseDeviceService {
/// Creates an [AudioRecorderService].
AudioRecorderService() : _recorder = AudioRecorder();
final AudioRecorder _recorder;
/// Starts recording audio to a temporary file.
///
/// Returns the path where the audio is being recorded.
Future<void> startRecording() async {
return action(() async {
if (await _recorder.hasPermission()) {
final Directory tempDir = await getTemporaryDirectory();
final String path =
'${tempDir.path}/rapid_order_audio_${DateTime.now().millisecondsSinceEpoch}.m4a';
// Configure the recording
const RecordConfig config = RecordConfig(
encoder: AudioEncoder.aacLc, // Good balance of quality and size
bitRate: 128000,
sampleRate: 44100,
);
await _recorder.start(config, path: path);
} else {
throw Exception('Microphone permission not granted');
}
});
}
/// Stops the current recording.
///
/// Returns the path to the recorded audio file, or null if no recording was active.
Future<String?> stopRecording() async {
return action(() async {
return await _recorder.stop();
});
}
/// Checks if the recorder is currently recording.
Future<bool> isRecording() async {
return await _recorder.isRecording();
}
/// Disposes the recorder resources.
void dispose() {
_recorder.dispose();
}
}

View File

@@ -25,4 +25,6 @@ dependencies:
image_picker: ^1.1.2
path_provider: ^2.1.3
file_picker: ^8.1.7
record: ^5.2.0
firebase_auth: ^6.1.4