video_util.dart 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. import 'dart:io';
  2. import 'package:flutter/services.dart';
  3. import 'package:path/path.dart';
  4. import 'package:path_provider/path_provider.dart';
  5. class VideoUtil {
  6. static Future<Directory> get tempDirectory async {
  7. return await getTemporaryDirectory();
  8. }
  9. static Future<File> copyFileAssets(String assetName, String localName) async {
  10. final ByteData assetByteData = await rootBundle.load(assetName);
  11. final List<int> byteList = assetByteData.buffer.asUint8List(assetByteData.offsetInBytes, assetByteData.lengthInBytes);
  12. final String fullTemporaryPath = join((await tempDirectory).path, localName);
  13. return new File(fullTemporaryPath).writeAsBytes(byteList, mode: FileMode.writeOnly, flush: true);
  14. }
  15. static Future<String> assetPath(String assetName) async {
  16. return join((await tempDirectory).path, assetName);
  17. }
  18. static String generateEncodeVideoScript(String image1Path, String image2Path, String image3Path, String videoFilePath, String videoCodec, String customOptions) {
  19. return "-hide_banner -y -loop 1 -i " + image1Path + " " +
  20. "-loop 1 -i " + image2Path + " " +
  21. "-loop 1 -i " + image3Path + " " +
  22. "-filter_complex " +
  23. "[0:v]setpts=PTS-STARTPTS,scale=w=\'if(gte(iw/ih,640/427),min(iw,640),-1)\':h=\'if(gte(iw/ih,640/427),-1,min(ih,427))\',scale=trunc(iw/2)*2:trunc(ih/2)*2,setsar=sar=1/1,split=2[stream1out1][stream1out2];" +
  24. "[1:v]setpts=PTS-STARTPTS,scale=w=\'if(gte(iw/ih,640/427),min(iw,640),-1)\':h=\'if(gte(iw/ih,640/427),-1,min(ih,427))\',scale=trunc(iw/2)*2:trunc(ih/2)*2,setsar=sar=1/1,split=2[stream2out1][stream2out2];" +
  25. "[2:v]setpts=PTS-STARTPTS,scale=w=\'if(gte(iw/ih,640/427),min(iw,640),-1)\':h=\'if(gte(iw/ih,640/427),-1,min(ih,427))\',scale=trunc(iw/2)*2:trunc(ih/2)*2,setsar=sar=1/1,split=2[stream3out1][stream3out2];" +
  26. "[stream1out1]pad=width=640:height=427:x=(640-iw)/2:y=(427-ih)/2:color=#00000000,trim=duration=3,select=lte(n\\,90)[stream1overlaid];" +
  27. "[stream1out2]pad=width=640:height=427:x=(640-iw)/2:y=(427-ih)/2:color=#00000000,trim=duration=1,select=lte(n\\,30)[stream1ending];" +
  28. "[stream2out1]pad=width=640:height=427:x=(640-iw)/2:y=(427-ih)/2:color=#00000000,trim=duration=2,select=lte(n\\,60)[stream2overlaid];" +
  29. "[stream2out2]pad=width=640:height=427:x=(640-iw)/2:y=(427-ih)/2:color=#00000000,trim=duration=1,select=lte(n\\,30),split=2[stream2starting][stream2ending];" +
  30. "[stream3out1]pad=width=640:height=427:x=(640-iw)/2:y=(427-ih)/2:color=#00000000,trim=duration=2,select=lte(n\\,60)[stream3overlaid];" +
  31. "[stream3out2]pad=width=640:height=427:x=(640-iw)/2:y=(427-ih)/2:color=#00000000,trim=duration=1,select=lte(n\\,30)[stream3starting];" +
  32. "[stream2starting][stream1ending]blend=all_expr=\'if(gte(X,(W/2)*T/1)*lte(X,W-(W/2)*T/1),B,A)\':shortest=1[stream2blended];" +
  33. "[stream3starting][stream2ending]blend=all_expr=\'if(gte(X,(W/2)*T/1)*lte(X,W-(W/2)*T/1),B,A)\':shortest=1[stream3blended];" +
  34. "[stream1overlaid][stream2blended][stream2overlaid][stream3blended][stream3overlaid]concat=n=5:v=1:a=0,scale=w=640:h=424,format=yuv420p[video]" +
  35. " -map [video] -vsync 2 -async 1 " + customOptions + "-c:v " + videoCodec + " -r 30 " + videoFilePath;
  36. }
  37. }