uploadFileInChunks method

Future<CloudinaryResponse?> uploadFileInChunks(
  1. CloudinaryFile file, {
  2. String? uploadPreset,
  3. ProgressCallback? onProgress,
  4. int chunkSize = 20000000,
})

Upload file in chunks default chunk size is 20 MB chunk size must be less than 20 MB and greater than 5 MB

Implementation

Future<CloudinaryResponse?> uploadFileInChunks(
  CloudinaryFile file, {
  String? uploadPreset,
  ProgressCallback? onProgress,
  int chunkSize = 20000000, // 20MB
}) async {
  if (chunkSize > 20000000 || chunkSize < 5000000) {
    throw CloudinaryException(
      'Chunk size must be less than 20 MB and greater than 5 MB',
      0,
      request: {
        'url': file.url,
        'path': file.filePath,
        'public_id': file.identifier,
        'identifier': file.identifier,
      },
    );
  }
  CloudinaryResponse? cloudinaryResponse;

  Response? finalResponse;

  int maxChunkSize = min(file.fileSize, chunkSize);

  int chunksCount = (file.fileSize / maxChunkSize).ceil();

  List<MultipartFile>? chunks = file.createChunks(chunksCount, maxChunkSize);

  Map<String, dynamic> data = file.toFormData(
    uploadPreset: uploadPreset ?? _uploadPreset,
  );

  try {
    for (int i = 0; i < chunksCount; i++) {
      final start = i * maxChunkSize;
      final end = min((i + 1) * maxChunkSize, file.fileSize);

      final formData = FormData.fromMap({
        'file': chunks[i],
        ...data,
      });

      finalResponse = await _dioClient.post(
        _createUrl(file.resourceType),
        data: formData,
        options: Options(
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'multipart/form-data',
            'X-Unique-Upload-Id': file.identifier,
            'Content-Range': 'bytes $start-${end - 1}/${file.fileSize}',
          },
        ),
        onSendProgress: (sent, total) {
          // total progress
          final s = sent + i * maxChunkSize;
          onProgress?.call(s, file.fileSize);
        },
      );
    }

    if (finalResponse?.statusCode != 200 || finalResponse == null) {
      throw CloudinaryException(
        finalResponse?.data,
        finalResponse?.statusCode ?? 0,
        request: {
          'url': file.url,
          'path': file.filePath,
          'public_id': file.identifier,
          'identifier': file.identifier,
        },
      );
    }

    cloudinaryResponse = CloudinaryResponse.fromMap(
      finalResponse.data,
    );
  } catch (e) {
    rethrow;
  }
  return cloudinaryResponse;
}