choose_video_handler.dart 3.91 KB
import 'dart:io';

import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/utils/thumbnail_util.dart';
import 'package:image_picker/image_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';

class ChooseVideoHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(params) async {
    if (params is! Map<String, dynamic>) {
      throw Exception('参数错误');
    }
    var sourceType = params['sourceType'] as String;
    if (sourceType != 'album' && sourceType != 'camera') {
      throw Exception('参数错误');
    }
    // 暂时忽略对此参数的处理
    List<dynamic>? sizeType;
    if (params.containsKey('sizeType')) {
      sizeType = params['sizeType'] as List<dynamic>;
      if (sizeType.isEmpty || sizeType.length > 2) {
        throw Exception('参数错误');
      }
    }

    int count = 1;
    if (params.containsKey('count')) {
      count = params['count'] as int;
      if (count < 1 || count > 9) {
        throw Exception('参数错误');
      }
    }

    int number = 60;
    if (params.containsKey('number')) {
      number = params['number'] as int;
      if (number < 1 || number > 60) {
        throw Exception('参数错误');
      }
    }

    // 从相册选择
    if (sourceType == 'album') {
      if (count == 1) {
        return await _selectSingleVideo();
      } else {
        return await _selectMultiVideo(count);
      }
    }
    // 拍摄
    else {
      return await _cameraSingle();
    }
  }

  Future<List<dynamic>> _selectSingleVideo() async {
    final ImagePicker picker = ImagePicker();
    final XFile? pickedVideo = await picker.pickVideo(source: ImageSource.gallery);

    // 用户取消选择,返回空数组
    if (pickedVideo == null) {
      return [];
    }

    // 获取临时目录
    final Directory tempDir = await getTemporaryDirectory();

    return [await _handleOne(pickedVideo, tempDir)];
  }

  Future<List<dynamic>> _selectMultiVideo(int limit) async {
    final ImagePicker picker = ImagePicker();
    final List<XFile> pickedVideoList = await picker.pickMultiVideo(limit: limit);

    // 用户取消选择,返回空数组
    if (pickedVideoList.isEmpty) {
      return [];
    }

    // 限制最多limit张
    if (pickedVideoList.length > limit) {
      pickedVideoList.removeRange(limit, pickedVideoList.length);
    }

    // 获取临时目录
    final Directory tempDir = await getTemporaryDirectory();

    final List<Map<String, dynamic>> result = [];
    for (final XFile? file in pickedVideoList) {
      if (file != null) {
        result.add(await _handleOne(file, tempDir));
      }
    }
    return result;
  }

  ///
  /// 拍照
  ///
  Future<List<Map<String, dynamic>>?> _cameraSingle() async {
    final ImagePicker picker = ImagePicker();

    final XFile? pickedFile = await picker.pickVideo(source: ImageSource.camera);

    // 用户取消选择,返回空数组
    if (pickedFile == null) {
      return [];
    }

    // 获取临时目录
    final Directory tempDir = await getTemporaryDirectory();

    return [await _handleOne(pickedFile, tempDir)];
  }

  Future<Map<String, dynamic>> _handleOne(XFile pickedFile, Directory tempDir) async {
    var sourceFile = File(pickedFile.path);

    final thumbnailPath = await ThumbnailUtil.genVideoThumbnail(pickedFile.path, tempDir);
    // 暂时这样进行接口测试
    // 根据视频预览图,获取视频的宽度和高度
    final sizeResult = ImageSizeGetter.getSizeResult(FileInput(File(thumbnailPath!)));

    // 返回一个元素的数组
    return {
      "tempFilePath": "/temp${sourceFile.path}",
      "size": sourceFile.lengthSync(),
      "width": sizeResult.size.width,
      "height": sizeResult.size.height,
      "thumbTempFilePath": '/temp$thumbnailPath',
      "fileType": sourceFile.path.split('/').last.split('.').last,
    };
  }
}