使用ffmpeg_kit_flutter在Flutter中合并两个视频

huangapple go评论78阅读模式
英文:

How to use ffmpeg_kit_flutter to merge two videos in Flutter

问题

我想将位于我的项目资产文件夹中的intro.mp4视频与cameraRecord输出视频(假设为output.mp4)合并。

我尝试了以下代码,但结果不好(输出视频是并排的而不是顺序的),而且似乎无法使用资产文件夹,我认为所有路径应该来自设备而不是项目(资产...)。

Future<void> mergeRecordWithIntro(String outputPath, String videoPath) async {
  emit(MergeVideoLoading());
  const String introPath = 'assets/logo.mp4';
  const filter = "[0:v]scale=480:640,setsar=1[l];[1:v]scale=480:640,setsar=1[r];[l][r]hstack;[0][1]amix -vsync 0 ";

  await FFmpegKit.execute('-y -i $videoPath -i $introPath -filter_complex $filter $outputPath')
    .then((value) async {
      final returnCode = await value.getReturnCode();

      if (ReturnCode.isSuccess(returnCode)) {
        GallerySaver.saveVideo(outputPath);
        emit(MergeVideoSuccess());
      } else if (ReturnCode.isCancel(returnCode)) {
        emit(MergeVideoError());
      }
    });
}

这是我的更新日志屏幕截图,使用以下命令:

-y -i $firstVideoPath -i $secondVideoPath -filter_complex "[0:v]scale=480:640[v0];[1:v]scale=480:640[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" $outputPath
英文:

i want to merge an intro.mp4 (located in the assets folder of my project) video with the cameraRecord Output video (let's say output.mp4)

i tried this (code below) but it gives a bad result (the output video is side by side not sequential ) also it didn't work with the assets folder i think all the paths should come from the device and not from the project (assets ...)

Future&lt;void&gt; mergeRecordWithIntro(String outputPath, String videoPath) async {
emit(MergeVideoLoading());
const String introPath = &#39;assets/logo.mp4&#39;;
const filter =
    &quot; [0:v]scale=480:640,setsar=1[l];[1:v]scale=480:640,setsar=1[r];[l][r]hstack;[0][1]amix -vsync 0 &quot;;

await FFmpegKit.execute(
        &#39;-y -i $videoPath -i $videoPath -filter_complex $filter $outputPath&#39;)
        
    .then((value) async {
  final returnCode = await value.getReturnCode();

  if (ReturnCode.isSuccess(returnCode)) {
    GallerySaver.saveVideo(outputPath);
    emit(MergeVideoSucces());
  } else if (ReturnCode.isCancel(returnCode)) {
    emit(MergeVideoError());
  }
});

this is my updates log screen shot using this command :

-y -i $firstVideoPath -i $secondVideoPath -filter_complex &quot;[0:v]scale=480:640[v0];[1:v]scale=480:640[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]&quot; -map &quot;[outv]&quot; -map &quot;[outa]&quot; $outputPath

答案1

得分: 0

首先,将视频保存到项目的资产文件夹中,然后将其移到临时文件夹并使用该路径。

final byteData = await rootBundle.load('assets/logo.mp4');
final file = await File('${Directory.systemTemp.path}${path.replaceAll('assets', '')}').create();
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
final firstVideoPath = file.path;

接下来,合并视频的命令是 concat,请修复它。*如果您使用不同的分辨率或编解码器,可能需要进行调整。

await FFmpegKit.execute('-y -i "concat:$firstVideoPath|$secondVideoPath" -c copy $outputPath')

最后,使用 gal package 而不是 gallery_saver,后者已经两年未维护。

await Gal.putVideo($outputPath);
英文:

First, save the video in the project's assets folder to a temporary folder and use the path there.

final byteData = await rootBundle.load(&#39;assets/logo.mp4&#39;);
final file = await File(&#39;${Directory.systemTemp.path}${path.replaceAll(&#39;assets&#39;, &#39;&#39;)}&#39;).create();
await file.writeAsBytes(byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
final firstVideoPath = file.path;

Next, the command to merge videos is concat, so fix it. *If you have a different resolution or codec, you may need to fix it.

await FFmpegKit.execute(&#39;-y -i &quot;concat:$firstVideoPath|$secondVideoPath&quot; -c copy $outputPath&#39;)

Finally, use the gal package instead of the gallery_saver, which is already two years out of maintenance.

await Gal.putVideo($outputPath);

答案2

得分: 0

这个命令对我有效,唯一的问题是输出视频质量非常低,所以...!! :

-y -i $firstVideoPath -i $videoPath -r 24000/1001 -filter_complex "[0:v]scale=1080:1920[v0];[1:v]scale=1080:1920[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" -vsync 2 $outputPath

英文:

this command worked for me the only problem is the output video quality is very low so... !! :

-y -i $firstVideoPath -i $videoPath -r 24000/1001 -filter_complex &quot;[0:v]scale=1080:1920[v0];[1:v]scale=1080:1920[v1];[v0][0:a][v1][1:a]concat=n=2:v =1:a=1[outv][outa]&quot; -map &quot;[outv]&quot; -map &quot;[outa]&quot; -vsync 2 $outputPath

huangapple
  • 本文由 发表于 2023年6月26日 19:15:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76556163.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定