save_to_album_handler.dart 2.32 KB
import 'dart:convert';
import 'dart:io';
import 'package:appframe/services/dispatcher.dart';
import 'package:gallery_saver_plus/gallery_saver.dart';
import 'package:path_provider/path_provider.dart';

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

    var filePath = params['filePath'] as String?;
    if (filePath == null || filePath.isEmpty) {
      return false;
    }

    String actualFilePath;
    if (_isBase64(filePath)) {
      actualFilePath = await _saveBase64ToFile(filePath);
    } else {
      actualFilePath = filePath;
    }

    bool isVideo = _isVideoFile(actualFilePath);

    try {
      if (isVideo) {
        final bool? success = await GallerySaver.saveVideo(actualFilePath);
        return success ?? false;
      } else {
        final bool? success = await GallerySaver.saveImage(actualFilePath);
        return success ?? false;
      }
    } catch (e) {
      print(e);
      return false;
    }
  }

  bool _isBase64(String str) {
    if (str.startsWith('data:image/')) {
      return true;
    }
    try {
      base64Decode(str);
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<String> _saveBase64ToFile(String base64Str) async {
    String base64Data = base64Str;
    String fileExtension = 'png';

    if (base64Str.startsWith('data:image/')) {
      final regExp = RegExp(r'data:image/(\w+);base64,(.+)');
      final match = regExp.firstMatch(base64Str);
      if (match != null) {
        fileExtension = match.group(1) ?? 'png';
        base64Data = match.group(2) ?? '';
      }
    }

    final bytes = base64Decode(base64Data);
    final tempDir = await getTemporaryDirectory();
    final filePath = '${tempDir.path}/${DateTime.now().millisecondsSinceEpoch}.$fileExtension';
    final file = File(filePath);
    await file.writeAsBytes(bytes);
    return filePath;
  }

  bool _isVideoFile(String filePath) {
    return filePath.endsWith('.mp4') ||
        filePath.endsWith('.avi') ||
        filePath.endsWith('.mov') ||
        filePath.endsWith('.mkv') ||
        filePath.endsWith('.wmv') ||
        filePath.endsWith('.flv') ||
        filePath.endsWith('.webm') ||
        filePath.endsWith('.m4v') ||
        filePath.endsWith('.3gp');
  }
}