complete method
Complete editing and return the story model
Implementation
Future<StoryModel> complete() async {
assets.value.forEach((StoryElement element) {
element.layerIndex = assets.value.indexOf(element);
});
assets.value.forEach((StoryElement element) {
element.videoController?.video.pause();
element.audioController?.pause();
});
final StoryModel result;
final bool isContainsVideo = assets.value
.any((StoryElement element) => element.type == ItemType.video);
storyModel.colorFilter = selectedFilter.value.name;
if (isContainsVideo) {
storyModel.isVideoIncluded = true;
}
final List<StoryElement> elements = <StoryElement>[...assets.value];
final DateTime startTime = DateTime.now();
print('#Comptression started# : ${startTime.toIso8601String()}');
bool isAudioIncluded = false;
bool isVideoIncluded = false;
bool isImageIncluded = false;
await Future.forEach(elements, (StoryElement element) async {
final String filePath = '${element.elementFile?.path}';
print('#element.elementFile?# : ${filePath}');
print('#element.type?# : ${element.type}');
final File file = File(filePath);
if (await file.exists()) {
final int sizeInBytes = await file.length();
print('element.elementFile? : ${sizeInBytes / (1024 * 1024)} MB');
} else {
print('element.elementFile? : File does not exist');
}
if (element.type == ItemType.video) {
isVideoIncluded = true;
if (element.videoController != null) {
storyModel.videoDuration = element
.videoController!.trimmedDuration.inMilliseconds
.toDouble();
element.elementFile = await CompressService.trimVideoAndCompress(
element.videoController!);
}
} else if (element.type == ItemType.image) {
isImageIncluded = true;
element.elementFile =
await CompressService.compressImage(XFile(element.value));
} else if (!storyModel.isVideoIncluded &&
element.type == ItemType.audio) {
isAudioIncluded = true;
storyModel.videoDuration = element.elementDuration + 0.0;
} else if (element.type == ItemType.audio) {
isAudioIncluded = true;
}
});
if (isAudioIncluded && isVideoIncluded) {
final StoryElement? videoElement = elements.firstWhereOrNull(
(StoryElement element) => element.type == ItemType.video,
);
final StoryElement? audioElement = elements.firstWhereOrNull(
(StoryElement element) => element.type == ItemType.audio,
);
if (audioElement != null && videoElement != null) {
final XFile videoWithNewAudio = await VideoUtils.addAudioToVideo(
audioPath: audioElement.elementFile!.path,
videoPath: videoElement.elementFile!.path,
);
videoElement.elementFile = videoWithNewAudio;
videoElement.value = videoWithNewAudio.path;
elements.removeWhere(
(StoryElement element) => element.id == audioElement.id);
}
} else if (isAudioIncluded && isImageIncluded) {
final StoryElement? audioElement = elements.firstWhereOrNull(
(StoryElement element) => element.type == ItemType.audio,
);
final StoryElement? imageElement = elements.firstWhereOrNull(
(StoryElement element) => element.type == ItemType.image,
);
if (audioElement != null && imageElement != null) {
if (imageElement.elementFile!.path.isNetworkImage()) {
final HttpClient httpClient = HttpClient();
try {
final Directory cacheDir = await getTemporaryDirectory();
final File imageFile = File(
'${cacheDir.path}/${DateTime.now().millisecondsSinceEpoch}.png');
final HttpClientRequest request = await httpClient
.getUrl(Uri.parse(imageElement.elementFile!.path));
final HttpClientResponse response = await request.close();
if (response.statusCode == 200) {
final Uint8List bytes =
await consolidateHttpClientResponseBytes(response);
await imageFile.writeAsBytes(bytes);
imageElement.elementFile = XFile(imageFile.path);
} else {}
} catch (ex) {
print(ex);
} finally {
httpClient.close();
}
}
final XFile videoWithNewAudio = await VideoUtils.addAudioImage(
audioPath: audioElement.elementFile!.path,
imagePath: imageElement.elementFile!.path,
);
imageElement.elementFile = videoWithNewAudio;
imageElement.type = ItemType.imageVideo;
imageElement.value = videoWithNewAudio.path;
elements.removeWhere(
(StoryElement element) => element.id == audioElement.id);
storyModel.isVideoIncluded = true;
}
}
result = storyModel.copyWith(
elements: elements,
);
result.isVideoIncluded = isVideoIncluded || isAudioIncluded;
assets.value.clear();
selectedFilter.value = PresetFilters.none;
selectedItem.value = null;
if (result.paletteColors.length == 1) {
result.paletteColors.add(result.paletteColors.first);
}
Future.delayed(const Duration(seconds: 5), () {
assets.value.forEach((StoryElement element) {
element.videoController?.dispose();
element.videoControllerView?.dispose();
element.audioController?.dispose();
});
});
final DateTime endTime = DateTime.now();
print('#Comptression end# : ${endTime.toIso8601String()}');
print(
'#Comptression Duration# : ${endTime.difference(startTime).inSeconds} seconds');
debugPrint('storyModel :${result.toJson()}');
return result;
}