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

import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/utils/video_util.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:uuid/uuid.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('参数错误');
    }

    Directory tempDir = await getTemporaryDirectory();
    String srcPath;
    if (url.startsWith('http')) {
      String ext = path.extension(url);
      srcPath = '${tempDir.path}/${Uuid().v4()}$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('文件不存在');
    }
    print('原视频大小:${originFile.lengthSync()}');

    final outputPath = '${tempDir.path}/${Uuid().v4()}.mp4';
    var result = await VideoUtil.compressVideo(srcPath, outputPath, quality);
    if (!result) {
      throw Exception('视频压缩失败');
    }
    print('压缩后视频大小:${File(outputPath).lengthSync()}');

    return {
      "tempFilePath": '/temp$outputPath',
      "size": File(outputPath).lengthSync(),
    };

    // 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,
    // };
  }
}