choose_file_handler.dart 3.34 KB
import 'dart:io';

import 'package:appframe/config/constant.dart';
import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/utils/file_type_util.dart';
import 'package:appframe/utils/thumbnail_util.dart';
import 'package:file_picker/file_picker.dart';
import 'package:image_size_getter/file_input.dart';
import 'package:image_size_getter/image_size_getter.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_player/video_player.dart';

class ChooseFileHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    if (params is! Map<String, dynamic>) {
      throw Exception('参数错误');
    }

    var count = 1;
    if (params.containsKey('count')) {
      count = params['count'] as int;
    }

    final fileTypes = params['fileTypes'] as List<dynamic>;

    FilePickerResult? filePickerResult = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: fileTypes.map((e) => e.toString()).toList(),
      allowMultiple: count > 1,
    );

    // 用户取消选择,返回空数组
    if (filePickerResult == null) {
      throw Exception('cancel');
    }

    // 限制最多count个文件
    if (filePickerResult.files.length > count) {
      filePickerResult.files.removeRange(count, filePickerResult.files.length);
    }

    final List<Map<String, dynamic>> result = [];
    for (var file in filePickerResult.files) {
      result.add(await _handleFile(file));
    }

    return {'tempFiles': result};
  }

  Future<Map<String, dynamic>> _handleFile(PlatformFile file) async {
    // 所选中的文件已经被插件复制到临时目录,所以不需要再复制
    final originalFile = File(file.path!);

    bool isImage = await FileTypeUtil.isImage(originalFile);
    bool isVideo = false;
    if (!isImage) {
      isVideo = await FileTypeUtil.isVideo(originalFile);
    }

    int? imgWidth, imgHeight;
    String? imgThumbFilePath;
    if (isImage) {
      // 通过image_size_getter获取图片尺寸
      var sizeResult = ImageSizeGetter.getSizeResult(FileInput(originalFile));
      var size = sizeResult.size;
      imgWidth = sizeResult.size.width;
      imgHeight = sizeResult.size.height;
      final tempDir = await getTemporaryDirectory();
      imgThumbFilePath = await ThumbnailUtil.genTempThumbnail(originalFile, tempDir);
    }

    double? videoWidth, videoHeight;
    String? videoThumbFilePath;
    if (isVideo) {
      // 获取视频尺寸
      VideoPlayerController controller = VideoPlayerController.file(originalFile);
      await controller.initialize();
      var size = controller.value.size;
      videoWidth = size.width;
      videoHeight = size.height;
      controller.dispose();

      final tempDir = await getTemporaryDirectory();
      videoThumbFilePath = await ThumbnailUtil.genVideoThumbnail(originalFile.path, tempDir);
    }

    // 返回临时文件信息
    return {
      'tempFilePath': '${Constant.localServerTempFileUrl}${file.path}',
      'size': file.size,
      'width': isImage ? imgWidth : (isVideo ? videoWidth : ''),
      'height': isImage ? imgHeight : (isVideo ? videoHeight : ''),
      'thumbTempFilePath': isImage
          ? '${Constant.localServerTempFileUrl}$imgThumbFilePath'
          : (isVideo ? '${Constant.localServerTempFileUrl}$videoThumbFilePath' : ''),
      'fileType': file.extension,
    };
  }
}