compress_handler.dart 4.25 KB
import 'dart:io';

import 'package:appframe/services/dispatcher.dart';
import 'package:dio/dio.dart';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:video_compress/video_compress.dart';

/// 压缩图片
///
class CompressImageHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    if (params is! Map<String, dynamic>) {
      throw Exception('参数错误');
    }
    final url = params['url'] as String?;
    if (url == null || url.isEmpty) {
      throw Exception('参数错误');
    }
    final quality = params['quality'] as int?;
    if (quality == null) {
      throw Exception('参数错误');
    }
    var compressedWidth = params['compressedWidth'] as int?;
    // if (compressedWidth == null) {
    //   throw Exception('参数错误');
    // }
    var compressedHeight = params['compressedHeight'] as int?;
    // if (compressedHeight == null) {
    //   throw Exception('参数错误');
    // }

    if (compressedWidth == null && compressedHeight == null) {
      throw Exception('参数错误');
    }

    if (compressedWidth == null) {
      compressedWidth = compressedHeight;
    } else if (compressedHeight == null) {
      compressedHeight = compressedWidth;
    }

    // 获取后缀名
    String ext = path.extension(url);
    final Directory tempDir = await getTemporaryDirectory();

    String srcPath;
    // 如果是远程文件,先进行下载
    if (url.startsWith('http')) {
      srcPath = path.join(tempDir.path, '${DateTime.now().millisecondsSinceEpoch}$ext');
      // Dio 下载文件
      final resp = await Dio().download(url, srcPath);
      if (resp.statusCode != 200) {
        throw Exception('远程文件下载失败');
      }
    } else {
      srcPath = url;
    }

    var originFile = File(srcPath);
    if (!originFile.existsSync()) {
      throw Exception('文件不存在');
    }

    final String uniqueFileName = '${DateTime.now().millisecondsSinceEpoch}$ext';
    final String tempPath = path.join(tempDir.path, uniqueFileName);

    // 压缩处理
    var croppedFile = await FlutterImageCompress.compressAndGetFile(
      originFile.absolute.path,
      tempPath,
      quality: quality,
      minWidth: compressedWidth!,
      minHeight: compressedHeight!,
    );

    if (croppedFile == null) {
      throw Exception('图片压缩失败');
    }

    return {"tempFilePath": "/temp${croppedFile.path}", "size": await croppedFile.length()};
  }
}

/// 压缩视频
///
class CompressVideoHandler extends MessageHandler {
  @override
  Future<dynamic> handleMessage(dynamic params) async {
    if (params is! Map<String, dynamic>) {
      throw Exception('参数错误');
    }
    final url = params['url'] as String?;
    if (url == null || url.isEmpty) {
      throw Exception('参数错误');
    }
    final quality = params['quality'] as String?;
    if (quality == null || quality.isEmpty) {
      throw Exception('参数错误');
    }
    final resolution = params['resolution'] as double?;
    if (resolution == null || resolution > 1 || resolution <= 0) {
      throw Exception('参数错误');
    }

    String srcPath;
    if (url.startsWith('http')) {
      String ext = path.extension(url);
      final Directory tempDir = await getTemporaryDirectory();
      srcPath = path.join(tempDir.path, '${DateTime.now().millisecondsSinceEpoch}$ext');
      // Dio 下载文件
      final resp = await Dio().download(url, srcPath);
      if (resp.statusCode != 200) {
        throw Exception('远程文件下载失败');
      }
    } else {
      srcPath = url;
    }

    VideoQuality videoQuality;
    switch (quality) {
      case 'low':
        videoQuality = VideoQuality.LowQuality;
        break;
      case 'middle':
        videoQuality = VideoQuality.MediumQuality;
        break;
      case 'high':
        videoQuality = VideoQuality.HighestQuality;
        break;
      default:
        throw Exception('参数错误');
    }

    final mediaInfo = await VideoCompress.compressVideo(
      srcPath,
      quality: videoQuality,
      deleteOrigin: false,
      includeAudio: true,
    );

    return {"tempFilePath": "/temp${mediaInfo!.path}", "size": mediaInfo.filesize};
  }
}