file_upload_check_helper.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import 'dart:io';
  2. import 'package:electronic_assistant/utils/pair.dart';
  3. import 'package:electronic_assistant/utils/toast_util.dart';
  4. import 'package:get/get.dart';
  5. import 'package:just_audio/just_audio.dart';
  6. import 'package:uuid/uuid.dart';
  7. import '../data/bean/talks.dart';
  8. import '../data/repositories/talk_repository.dart';
  9. import '../dialog/loading_dialog.dart';
  10. import '../module/talk/view.dart';
  11. import '../resource/string.gen.dart';
  12. import 'audio_picker_utils.dart';
  13. import 'package:path_provider/path_provider.dart';
  14. import 'error_handler.dart';
  15. class FileUploadCheckHelper {
  16. FileUploadCheckHelper._();
  17. static Future<void> choicePlatformLocalFileAndCreateOrder() async {
  18. TalkBean? bean;
  19. try {
  20. Pair<File, Duration>? pair =
  21. await FileUploadCheckHelper.pickerPlatformFile();
  22. if (pair == null) {
  23. //未选择文件
  24. return;
  25. }
  26. LoadingDialog.show(StringName.fileImporting.tr);
  27. bean = await FileUploadCheckHelper.createTalkFromLocalFile(
  28. pair.first, pair.second);
  29. TalkPage.start(bean);
  30. } catch (e) {
  31. if (e is PickerException) {
  32. ToastUtil.showToast(e.message);
  33. } else {
  34. ErrorHandler.toastError(e, message: StringName.fileImportFail.tr);
  35. }
  36. } finally {
  37. LoadingDialog.hide();
  38. }
  39. if (bean != null) {
  40. TalkPage.start(bean);
  41. }
  42. }
  43. static Future<Duration> checkCanUpload(File file) async {
  44. //文件不能超过500M
  45. if (file.lengthSync() > 500 * 1024 * 1024) {
  46. throw PickerException(StringName.fileChoiceSizeLimit.tr);
  47. }
  48. AudioPlayer? player;
  49. try {
  50. player = AudioPlayer();
  51. player.setAudioSource(AudioSource.uri(file.uri));
  52. Duration? duration = await player.durationStream
  53. .firstWhere((duration) => duration != null);
  54. if (duration == null) {
  55. throw PickerException(StringName.fileAudioDurationCannotObtained.tr);
  56. }
  57. //录音时长不能超过5小时
  58. if (duration.inHours > 5) {
  59. throw PickerException(StringName.fileAudioDurationLimit.tr);
  60. }
  61. return duration;
  62. } finally {
  63. player?.dispose();
  64. }
  65. }
  66. static Future<Pair<File, Duration>?> pickerPlatformFile() async {
  67. File? file = await AudioPickerUtils.pickSingleFileByPlatform();
  68. if (file == null) {
  69. return null;
  70. }
  71. Duration duration = await checkCanUpload(file);
  72. return Pair(file, duration);
  73. }
  74. static Future<TalkBean> createTalkFromLocalFile(
  75. File file, Duration duration) async {
  76. TalkBean bean = await talkRepository.talkCreate(
  77. const Uuid().v4(), duration.inSeconds,
  78. uploadType: FileUploadType.local);
  79. String childDirName = bean.id;
  80. Directory dir = await getChoiceUploadDir(childDirName);
  81. await moveFileToDirectory(file, dir);
  82. return bean;
  83. }
  84. static Future<Directory> getChoiceUploadDir(String talkId) async {
  85. Directory documentDir = await getApplicationDocumentsDirectory();
  86. return Directory("${documentDir.path}/.atmob/choice/$talkId");
  87. }
  88. static Future<File?> getChoiceUploadFile(String talkId) async {
  89. Directory dir = await getChoiceUploadDir(talkId);
  90. if (!dir.existsSync()) {
  91. return null;
  92. }
  93. List<FileSystemEntity> list = dir.listSync();
  94. if (list.isEmpty) {
  95. return null;
  96. }
  97. return list.first as File;
  98. }
  99. static Future<void> moveFileToDirectory(File file, Directory dir) async {
  100. if (!dir.existsSync()) {
  101. dir.createSync(recursive: true);
  102. }
  103. String newFilePath = '${dir.path}/${file.uri.pathSegments.last}';
  104. file.renameSync(newFilePath);
  105. }
  106. }
  107. class PickerException implements Exception {
  108. final String message;
  109. PickerException(this.message);
  110. @override
  111. String toString() {
  112. return 'PickerException: $message';
  113. }
  114. }