【问题标题】:How to encode jpeg images to H264 very fast (transform images to video)如何快速将 jpeg 图像编码为 H264(将图像转换为视频)
【发布时间】:2013-06-11 15:33:05
【问题描述】:

我有 30 张 JPEG 图像 (.jpg),分辨率为 480 x 640。 每张图片大约需要 20KB(全部大约需要 600KB)。

我正在使用 FFmpeg 命令将这些图像编码为 H264 格式的视频。

我需要快速完成 - 大约 1 秒。

使用经典命令:

ffmpeg -y  -f  image2   -r 1/5   -i image_%d.jpg   -c:v libx264   -r 30   video.mp4

大约需要 90 秒

添加-preset ultrafast后:

ffmpeg -y  -f  image2   -r 1/5   -i image_%d.jpg   -c:v libx264   -preset ultrafast    -r 30   video.mp4

编码大约需要 15 秒,这要好得多,但仍然不够

我也尝试过其他参数,例如:

-profile:v baseline

-qscale:v

-b:v 1000k

-crf 24

但编码时间不低于 10 秒。

我不熟悉 FFmpeg 命令,也不熟悉我需要使用的参数,这就是我在这里发布这个问题的原因。

视频质量需要没问题,不需要完美。

请注意:我正在使用 ProcessBuilder 的 Android 应用程序中运行这些命令,其中我有 ffmpeg 可执行文件。

回复 1(给罗伯特·朗特里):

ArrayList<String> l2 = new ArrayList<String>();

        //l2.add("ffmpeg");
        l2.add("/data/data/" + packageName + "/ffmpeg");
        l2.add("-y");
        l2.add("-loop");
        l2.add("1");

        l2.add("-i");
        l2.add("frame_%d.jpg");

//            l2.add("-t");
//            l2.add(strngs[3]);

        l2.add("-r");
        l2.add("1/2");
        l2.add("-preset");
        l2.add("superfast");
        l2.add("-tune");
        l2.add("zerolatency");

//            l2.add("-pass");
//            l2.add(Integer.valueOf(pass).toString());

        l2.add("-vcodec");
        l2.add("libx264");
        l2.add("-b:v");
        l2.add("200k");
        l2.add("-bt");
        l2.add("50k");
        l2.add("-threads");
        l2.add("0");
        l2.add("-b_strategy");
        l2.add("1");

//            if(pass ==1){
//                l2.add("-an");
//            } else {
//                l2.add("-acodec");
//                l2.add("copy");
//            }

        l2.add("-f");
        l2.add("mp4");
        l2.add("-strict");
        l2.add("-2");
//            l2.add("-passlogfile");
//            l2.add(strngs[4]);

//            if(pass ==1){
//                l2.add("/dev/null");
//            } else {
//                l2.add(strngs[5]);
//            }

        l2.add("video.mp4");
        //return l2;

【问题讨论】:

  • 我需要一个快速的解决方案。我不太关心视频质量。谢谢。

标签: android encoding ffmpeg h.264 video-encoding


【解决方案1】:

您可以尝试使用recordvideo 的硬件编码器。即使您不构建整个系统,也可以下载和编译 stagefright 命令行工具。您将需要系统库(来自您的设备)进行链接。生成的可执行文件会将 YUV 缓冲区转换为 mp4。您仍然需要将一系列 JPEG 转换为单个 YUV 文件。我认为使用 ffmpeg 会足够快,但你也可以使用libjpeg-turbo for android

【讨论】:

  • 感谢您的回复和链接。不幸的是,目前我需要使用 ffmpeg ...也许将来我会尝试您的建议并让您知道结果。谢谢
  • 编译ffmpeg使用stagefright怎么样?还是使用多线程 x264?
  • 在 S3 上使用硬件编码器可以达到每秒 60 VGA 帧,在 sw 编码器上使用 2 个线程可以达到 30 帧。不知道ffmpeg Jpeg解码器需要多少时间。
  • 我现在需要一个紧急、快速的解决方案。
【解决方案2】:

IMO - android 上的 ffmpeg 仍然是所有软件(没有 gpu 或硬件加速)。您可以尝试通过 libstagefright/ffmpeg 组合 questions 查找。无论如何,如果你对快速感兴趣,你应该在 android 上找到一个硬件加速解决方案。否则,与任何其他平台相比,受限平台(电池寿命、低功耗 CPU)上的 ffmpeg 会非常慢。

另外,请参阅接受的答案 herethis too

由于速度不够,我放弃了 android 并选择了一个云实例来上传媒体,然后在下载到 android 设备之前在那里进行 ffmpeg 编码。 想知道您是否在 android 上获得快速结果。

顺便说一句,在放弃使用 android 进行编码之前,我使用了你在下面看到的 2-pass H264 表达式。

private ArrayList<String> mapFfmpegSwitches(String... strngs){
    ArrayList<String> l2 = new ArrayList<String>();
    l2.add("ffmpeg");
    l2.add("-y");
    l2.add("-loop");
    l2.add("1");
    l2.add("-i");
    l2.add(strngs[1]);
    l2.add("-i");
    l2.add(strngs[2]);
    l2.add("-t");
    l2.add(strngs[3]);
    l2.add("-r");
    l2.add("1/2");
    l2.add("-preset");
    l2.add("superfast");
    l2.add("-tune");
    l2.add("zerolatency");              
    l2.add("-pass");
    l2.add(Integer.valueOf(pass).toString());
    l2.add("-vcodec");
    l2.add("libx264");
    l2.add("-b:v");
    l2.add("200k");
    l2.add("-bt");
    l2.add("50k");
    l2.add("-threads");
    l2.add("0");
    l2.add("-b_strategy");
    l2.add("1");
    if(pass ==1){
        l2.add("-an");
    } else {
        l2.add("-acodec");
        l2.add("copy");
    }
    l2.add("-f");
    l2.add("mp4");
    l2.add("-strict");
    l2.add("-2");
    l2.add("-passlogfile");
    l2.add(strngs[4]);

    if(pass ==1){
        l2.add("/dev/null");
    } else {
        l2.add(strngs[5]);
    }       
    return l2;
}

【讨论】:

  • 嗨。感谢您的回答。我将在几个小时内试用您的版本。您能否告诉我您尝试使用上述命令编码多少帧以及所需的时间?
  • 我认为在 android 上大约 4 FPS...需要大约 25 FPS 才能使 android 成为一个有价值的多路视频平台。
  • 或 10 秒。带有 2 张图片和 -r 1/2 的声音输入在 android 上需要超过 1 分钟,而在云上的 Heroku 实例上混合大约需要 4 秒。
  • 嗨,我试过你的代码,但编码永远不会结束..我认为它会不断重复我拥有的帧......无论如何我无法使用你编写的确切命令 - 我已经更新我对我使用过的命令的问题。许多参数对我来说是未知的......
  • "-loop" 这就是它在循环中的原因。
【解决方案3】:

去掉 -r 1/5 怎么样?它加快了我的编码速度。

【讨论】:

  • 是的,看来我不需要第一个-r,因为它用于强制输入文件的帧速率(仅对原始格式有效)并且我有jpecg文件。
  • 我不确定如何使用第二个 r(因为我需要为 putput 文件指定 fps)才能获得 5 帧/秒。我使用了 1/02,但似乎并非所有帧都包含在视频中,我不知道为什么......你知道为什么会这样吗?
  • 难道 -r 5 使用所有输入帧每秒不给你 5 帧吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
相关资源
最近更新 更多