import 'dart:io'; import 'package:electronic_assistant/utils/pair.dart'; import 'package:electronic_assistant/utils/toast_util.dart'; import 'package:get/get.dart'; import 'package:just_audio/just_audio.dart'; import 'package:uuid/uuid.dart'; import '../data/bean/talks.dart'; import '../data/repositories/talk_repository.dart'; import '../dialog/loading_dialog.dart'; import '../module/talk/view.dart'; import '../resource/string.gen.dart'; import 'audio_picker_utils.dart'; import 'package:path_provider/path_provider.dart'; import 'error_handler.dart'; class FileUploadCheckHelper { FileUploadCheckHelper._(); static Future choicePlatformLocalFileAndCreateOrder() async { TalkBean? bean; try { Pair? pair = await FileUploadCheckHelper.pickerPlatformFile(); if (pair == null) { //未选择文件 return; } LoadingDialog.show(StringName.fileImporting.tr); bean = await FileUploadCheckHelper.createTalkFromLocalFile( pair.first, pair.second); TalkPage.start(bean); } catch (e) { if (e is PickerException) { ToastUtil.showToast(e.message); } else { ErrorHandler.toastError(e, message: StringName.fileImportFail.tr); } } finally { LoadingDialog.hide(); } if (bean != null) { TalkPage.start(bean); } } static Future checkCanUpload(File file) async { //文件不能超过500M if (file.lengthSync() > 500 * 1024 * 1024) { throw PickerException(StringName.fileChoiceSizeLimit.tr); } AudioPlayer? player; try { player = AudioPlayer(); player.setAudioSource(AudioSource.uri(file.uri)); Duration? duration = await player.durationStream .firstWhere((duration) => duration != null); if (duration == null) { throw PickerException(StringName.fileAudioDurationCannotObtained.tr); } //录音时长不能超过5小时 if (duration.inHours > 5) { throw PickerException(StringName.fileAudioDurationLimit.tr); } return duration; } finally { player?.dispose(); } } static Future?> pickerPlatformFile() async { File? file = await AudioPickerUtils.pickSingleFileByPlatform(); if (file == null) { return null; } Duration duration = await checkCanUpload(file); return Pair(file, duration); } static Future createTalkFromLocalFile( File file, Duration duration) async { TalkBean bean = await talkRepository.talkCreate( const Uuid().v4(), duration.inSeconds, uploadType: FileUploadType.local); String childDirName = bean.id; Directory dir = await getChoiceUploadDir(childDirName); await moveFileToDirectory(file, dir); return bean; } static Future getChoiceUploadDir(String talkId) async { Directory documentDir = await getApplicationDocumentsDirectory(); return Directory("${documentDir.path}/.atmob/choice/$talkId"); } static Future getChoiceUploadFile(String talkId) async { Directory dir = await getChoiceUploadDir(talkId); if (!dir.existsSync()) { return null; } List list = dir.listSync(); if (list.isEmpty) { return null; } return list.first as File; } static Future moveFileToDirectory(File file, Directory dir) async { if (!dir.existsSync()) { dir.createSync(recursive: true); } String newFilePath = '${dir.path}/${file.uri.pathSegments.last}'; file.renameSync(newFilePath); } } class PickerException implements Exception { final String message; PickerException(this.message); @override String toString() { return 'PickerException: $message'; } }