Flutter 如何管理带有颤振的复杂过程
我的颤振应用程序中有一个非常复杂的计算过程。我正在使用Flutter 如何管理带有颤振的复杂过程,flutter,dart,Flutter,Dart,我的颤振应用程序中有一个非常复杂的计算过程。我正在使用ffmpeg处理大约100幅图像(缩放、创建缩略图、调整大小…),我从所有这些图像创建视频,包括音频文件和其他东西 实际上我是在主线程中这样做的。这是一个很大的功能。是否建议将此大函数放入compute()中,以将其移动到单独的线程 如果是,我如何处理这么大的函数和这么多的参数?如果使用与当前类完全不同的compute(),如何处理与UI的交互,例如进度条 这是我的职责 Future<void> _createVideoFromI
ffmpeg
处理大约100幅图像(缩放、创建缩略图、调整大小…),我从所有这些图像创建视频,包括音频文件和其他东西
实际上我是在主线程中这样做的。这是一个很大的功能。是否建议将此大函数放入compute()
中,以将其移动到单独的线程
如果是,我如何处理这么大的函数和这么多的参数?如果使用与当前类完全不同的compute()
,如何处理与UI的交互,例如进度条
这是我的职责
Future<void> _createVideoFromImages(Map settings) async {
var settingsFps = settings["fps"];
var settingsSong = settings["song"];
if (albumPicturesSum < 2) {
setState(() {
videoStatusMessage = tr("too_less_images");
isLoading = true;
});
toast(tr("too_less_images_desc"), "error");
Future.delayed(Duration(seconds: 2), () {
setState(() {
isLoading = false;
});
});
return false;
}
setState(() {
videoStatusMessage = tr("create_video");
isLoading = true;
progress = .1;
});
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
new Directory(tempPath).delete(recursive: true);
final allPictures = await picturesData.getPicturesFromAlbum(albumID);
//write to app path
Future<void> writeToFile(ByteData data, String path) {
final buffer = data.buffer;
return new File(path).writeAsBytes(
buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
// List<int> trimRect;
if (albumID == 99999999) {
for (var i = 0; i < demoImageList.length; i++) {
File file = File('$tempPath/img${i.toString().padLeft(4, '0')}.jpg');
final imageBytes = await rootBundle.load(demoImageList[i]);
final buffer = imageBytes.buffer;
await file.writeAsBytes(buffer.asUint8List(
imageBytes.offsetInBytes, imageBytes.lengthInBytes));
}
} else {
for (var i = 0; i < allPictures.length; i++) {
var file = File(allPictures[i].path);
file.copySync("$tempPath/img${i.toString().padLeft(4, '0')}.jpg");
}
}
setState(() {
progress = .2;
});
// Lied definieren
final filename = '$settingsSong.mp3';
var bytes = await rootBundle.load("assets/songs/$settingsSong.mp3");
String dir = (await syspath.getTemporaryDirectory()).path;
await writeToFile(bytes, '$dir/$filename');
var finalSong = File('$dir/$filename');
print(finalSong);
final videoFileName = "$APP_NAME-" + Uuid().v1();
/*final FlutterFFmpegConfig _flutterFFmpegConfig =
new FlutterFFmpegConfig();
_flutterFFmpegConfig.getLastCommandOutput().then((value) => print(value));*/
var rotateVideo = '';
bool isLandscape = false;
await _checkOrientation(File(tempPath + "/img0001.jpg"), tempPath)
.then((value) {
if (value == true) {
isLandscape = true;
}
});
if (isLandscape == false) {
rotateVideo = '-vf transpose=" 1" -metadata:s:v:0 rotate=0';
}
setState(() {
progress = .2;
});
await _flutterFFmpeg
.execute('''-r $settingsFps -i $tempPath/img%04d.jpg -vcodec libx264 -y -an -vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" -vf "scale=1920:-2,format=yuv420p" $tempPath/$videoFileName.mp4''').then(
(rc) async {
if (rc == 0) {
setState(() {
progress = .5;
});
// Save in Gallery
String videoPath = '$tempPath/$videoFileName.mp4';
if (await File(videoPath).exists() == true) {
// Video weiterverarbeiten und Ton druntermischen
final newVideoFileName = "$APP_NAME-" + Uuid().v1();
await _flutterFFmpeg
.execute(
'-i ${finalSong.path} -i $videoPath $rotateVideo -shortest $tempPath/$newVideoFileName.mp4')
.then((res) async {
if (res == 0) {
setState(() {
progress = .8;
});
String videoWithAudioFile = '$tempPath/$newVideoFileName.mp4';
print(videoWithAudioFile);
await GallerySaver.saveVideo(videoWithAudioFile,
albumName: "$APP_NAME")
.then((bool success) {
print("Hier? Success ist: $success");
if (success == true) {
setState(() {
progress = 1;
});
setState(() {
videoStatusMessage = tr("done");
Future.delayed(Duration(seconds: 2)).then((value) {
setState(() {
isLoading = false;
});
});
});
toast(tr("video_saved_desc"), "success");
} else {
_errorFlush();
videoStatusMessage = tr("error");
Future.delayed(Duration(seconds: 2)).then((value) {
setState(() {
isLoading = false;
});
});
}
}).whenComplete(() async {
// Delete created files on temporary folder
print("Dateien wieder löschen");
await _deleteCacheDir().whenComplete(() {
setState(() {
progress = 0;
});
});
});
} else {
_errorFlush();
}
});
} else {
setState(() {
videoStatusMessage = tr("error");
Future.delayed(Duration(seconds: 2)).then((value) {
setState(() {
isLoading = false;
});
});
});
_errorFlush();
}
} else {
setState(() {
videoStatusMessage = tr("error");
Future.delayed(Duration(seconds: 2)).then((value) {
setState(() {
isLoading = false;
});
});
});
_errorFlush();
}
});
}
Future\u createVideoFromImages(地图设置)异步{
var设置SFPS=设置[“fps”];
var settingsSong=设置[“歌曲];
如果(相册图片数<2){
设置状态(){
videoStatusMessage=tr(“太少图像”);
isLoading=true;
});
toast(tr(“太少图像描述”),“错误”);
未来。延迟(持续时间(秒:2),(){
设置状态(){
isLoading=false;
});
});
返回false;
}
设置状态(){
videoStatusMessage=tr(“创建视频”);
isLoading=true;
进展=.1;
});
目录tempDir=await getTemporaryDirectory();
字符串tempPath=tempDir.path;
新目录(tempPath).delete(递归:true);
final allPictures=等待picturesData.getPicturesFromAlbum(albumID);
//写入应用程序路径
未来写入文件(字节数据、字符串路径){
最终缓冲区=data.buffer;
返回新文件(路径)。writeAsBytes(
buffer.asUint8List(data.offsetingbytes,data.lengthInBytes));
}
//列表trimRect;
如果(albumID==9999999){
对于(var i=0;i打印(值))*/
var rotateVideo='';
布尔岛景观=假;
等待检查方向(文件(tempPath+“/img001.jpg”),tempPath)
.然后((值){
如果(值==true){
isLandscape=true;
}
});
if(isLandscape==false){
rotateVideo='-vf transpose=“1”-元数据:s:v:0 rotate=0';
}
设置状态(){
进展=.2;
});
等待
.execute(''-r$settingsFps-i$tempPath/img%04d.jpg-vcodec libx264-y-an-vf“pad=ceil(iw/2)*2:ceil(ih/2)*2“-vf”scale=1920:-2,format=yuv420p“$tempPath/$videoFileName.mp4”)。然后(
(rc)异步{
如果(rc==0){
设置状态(){
进展=.5;
});
//保存在图库中
字符串videoPath='$tempPath/$videoFileName.mp4';
if(等待文件(videoPath).exists()==true){
//视频Weiterverabeiten和Ton druntermischen
最终newVideoFileName=“$APP_NAME-”+Uuid().v1();
等待
.执行(
'-i${finalSong.path}-i$videoPath$rotateVideo-shortest$tempPath/$newVideoFileName.mp4')
.then((res)异步{
如果(res==0){
设置状态(){
进展=.8;
});
字符串videoWithAudioFile='$tempPath/$newVideoFileName.mp4';
打印(视频和音频文件);
等待GallerySaver.saveVideo(videoWithAudioFile,
相册名称:“$APP_NAME”)
.然后((bool success){
打印(“Hier?Success ist:$Success”);
if(success==true){
设置状态(){
进展=1;
});
设置状态(){
videoStatusMessage=tr(“完成”);
Future.delayed(持续时间(秒:2))。然后((值){
设置状态(){
isLoading=false;
});
});
});
toast(tr(“视频保存描述”),“成功”);
}否则{
_errorFlush();
videoStatusMessage=tr(“错误”);
Future.delayed(持续时间(秒:2))。然后((值){
设置状态(){
isLoading=false;
});
});
}
}).whenComplete(()异步{
//删除临时文件夹中创建的文件
印刷品(“Dateien wieder löschen”);
完成时等待_deleteCacheDir(){
设置状态(){
进度=0;
});
});