gpt4 book ai didi

android - FFmpeg将图像水印添加到视频过程中非常慢

转载 作者:行者123 更新时间:2023-12-04 23:04:58 31 4
gpt4 key购买 nike

我在 FFmpeg 的帮助下将图像水印添加到视频中,但是 FFmpeg 使用以下命令花费了过多的时间-

String[] cmd = {"-i",videoPath, "-i", waterMark.toString(),"-filter_complex","overlay=5:5","-codec:a", "copy", outputPath};

所以我尝试了另一个更快但增加输出文件大小的命令(我不想要)
String[] cmd = {"-y","-i", videoPath, "-i", waterMark.toString(), "-filter_complex", "overlay=5:5", "-c:v","libx264","-preset", "ultrafast", outputPath};

有人请向我解释如何在不增加输出大小的情况下提高 FFmpeg 水印速度的速度。
谢谢。

最佳答案

你提到一个 7MB 的视频需要 30-60 秒。
在速度和质量之间进行选择时总是需要权衡取舍。
我使用 7MB 文件在手机上进行了测试,耗时 13 秒,仍然很慢,但我们不能指望比这更好。
提高速度的方法:

  • 使用 -r 降低帧速率命令
  • 使用 -b:v 更改比特率和 -b:a命令
  • 使用 -crf 更改恒定速率因子.默认值为 21

  • The range of the quantizer scale is 0-51: where 0 is lossless, 23 is default, and 51 is worst possible. A lower value is a higher quality and a subjectively sane range is 18-28. Consider 18 to be visually lossless or nearly so: it should look the same or nearly the same as the input but it isn't technically lossless.


    这是我发现在大多数安卓设备上效果最好的:
    String[] s = {"-i", VideoPath, "-i", ImagePath, "-filter_complex", "[0:v]pad=iw:if(lte(ih\\,iw)\\,ih\\,2*trunc(iw*16/9/2)):(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]", "-map", "[v]", "-map", "0:a", "-c:v", "libx264", "-preset", "ultrafast", "-r", myFrameRate, directoryToStore[0] + "/" + SavedVideoName};
    我稍微降低了帧率,您可以尝试最适合您的方法。我正在使用 mp4parser检索帧速率。
    我必须感谢@Gyan,它为我提供了一种完美缩放放置在视频顶部的图像的方法,您可以查看我提出的问题 here .
    如果您不确定帧速率,可以将其从命令中删除,并首先测试您的速度是否降低。
    试试看,有什么问题请追问。

    OP 选择使用以下命令:
    String[] cmd = {"-y","-i", videoPath, "-i", waterMark.toString(), "-filter_complex", "overlay=(main_w-overlay_w-10):5", "-map", "0:a","-c:v", "libx264", "-crf", "28","-preset", "ultrafast" ,outputPath};

    编辑
    只是添加我提到的命令并提供有关如何使用它的详细说明等:
    String[] cmd = {"-i", videoPath, "-i", waterMark.toString(), "-filter_complex", "[0:v]pad=iw:if(lte(ih\\,iw)\\,ih\\,2*trunc(iw*16/9/2)):(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]", "-map", "[v]", "-map", "0:a", "-c:v", "libx264", "-preset", "ultrafast", "-r", myFrameRate, outputPath};
    这适用于显示纵横比为 16:9 的设备.如果您希望此过滤器适用于所有设备,则必须获取设备的纵横比并更改过滤器 16/9/2分别。
    您可以通过创建以下方法获取设备纵横比:
    int gcd(int p, int q) { 
    if (q == 0) return p;
    else return gcd(q, p % q);
    }
    void ratio(int a, int b) {
    final int gcd = gcd(a,b);
    if(a > b) {
    setAspectRatio(a/gcd, b/gcd);
    } else {
    setAspectRatio(b/gcd, a/gcd);
    }
    }
    void setAspectRatio(int a, int b) {
    System.out.println("aspect ratio = "+a + " " + b);
    //This is the string that will be used in the filter (instead of hardcoding 16/9/2
    filterAspectRatio = a + "/" + b + "/" + "2";
    }
    现在您有了正确的纵横比,您可以相应地更改过滤器。
    接下来,创建一个水印并将其添加到 View 中,将该 View 设置为设备的大小 ( match_parent),然后将水印缩放/放置在您想要的位置。然后,您可以通过调用获取位图:
    Bitmap waterMarkBitmap = watermarkView.getDrawingCache();
    并从 Bitmap 创建一个文件, 像这样:
    String outputFilename = "myCoolWatermark.png"; //provide a name for you saved watermark
    File path = Environment.getExternalStorageDirectory(); //this can be changed to where you want to store the bitmap
    File waterMark = new File(path, outputFilename);

    try (FileOutputStream out = new FileOutputStream(waterMark)) {
    waterMarkBitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // PNG is a lossless format, the compression factor (100) is ignored
    } catch (IOException e) {
    e.printStackTrace();
    }
    水印已创建并可重复使用,或者您可以在完成后将其删除。
    现在你可以调用上面提到的命令了。

    关于android - FFmpeg将图像水印添加到视频过程中非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55589904/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com