import 'dart:io'; import 'dart:math'; import 'package:file_picker/file_picker.dart'; import 'package:http/http.dart' as http; class SelectedAudio { const SelectedAudio({required this.name, required this.path}); final String name; final String path; } Future pickAudio(List supportedExtensions) async { final result = await FilePicker.platform.pickFiles( type: FileType.custom, allowedExtensions: supportedExtensions, allowMultiple: false, ); final pickedFile = result?.files.single; final path = pickedFile?.path; if (pickedFile == null || path == null) { return null; } return SelectedAudio(name: pickedFile.name, path: path); } Future audioFromRecorderPath( String path, String fallbackName, ) async { return SelectedAudio( name: path.split(Platform.pathSeparator).last, path: path, ); } Future> buildWavePreview(SelectedAudio audio) async { final bytes = await File(audio.path).readAsBytes(); return _wavePoints(bytes); } Future multipartFileFromAudio( String fieldName, SelectedAudio audio, ) { return http.MultipartFile.fromPath(fieldName, audio.path); } String recordingFilePath(String fileName) { return '${Directory.systemTemp.path}${Platform.pathSeparator}$fileName'; } List _wavePoints(List bytes) { if (bytes.isEmpty) { return const []; } const pointCount = 96; final step = max(1, bytes.length ~/ pointCount); final points = []; for (var index = 0; index < bytes.length; index += step) { final normalized = (bytes[index] - 128) / 128.0; points.add(normalized.clamp(-1.0, 1.0)); if (points.length == pointCount) { break; } } return points; }