简体   繁体   English

如何快速将 jpeg 图像编码为 H264(将图像转换为视频)

[英]How to encode jpeg images to H264 very fast (transform images to video)

I have 30 JPEG images (.jpg) at a resolution of 480 x 640. Each image takes aboout 20KB (all of them takes about 600KB).我有 30 张 JPEG 图像 (.jpg),分辨率为 480 x 640。每张图像大约需要 20KB(所有图像大约需要 600KB)。

I am using FFmpeg command to encode these images into a video in H264 format.我正在使用FFmpeg命令将这些图像编码为H264格式的视频。

I need this to be done very fast - about 1 second.我需要非常快地完成这个 - 大约 1 秒。

Using the classic command:使用经典命令:

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

takes about 90 seconds .大约需要90 秒

After adding -preset ultrafast :添加-preset ultrafast后:

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

the encoding takes about 15 seconds which is much better, but still not enough编码大约需要15 秒,这要好得多,但仍然不够

I've tried others parameters also, like:我也尝试了其他参数,例如:

-profile:v baseline

-qscale:v

-b:v 1000k

-crf 24

but the encoding time does not fall below 10 seconds.但编码时间不低于 10 秒。

I'm not familiar with FFmpeg commands nor with the parameters I need to use, and this is the reason I post here this question.我不熟悉 FFmpeg 命令,也不熟悉我需要使用的参数,这就是我在这里发布这个问题的原因。

The video quality needs to be ok, doesn't need to be perfect.视频质量需要没问题,不需要完美。

As a note: I am running these commands in an Android application where I have the ffmpeg executable, using an ProcessBuilder.注意:我正在使用 ProcessBuilder 在具有 ffmpeg 可执行文件的 Android 应用程序中运行这些命令。

Reply1 (to Robert Rowntree):回复 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;

How about getting rid of -r 1/5?摆脱 -r 1/5 怎么样? It speeded up my encoding.它加快了我的编码速度。

IMO - ffmpeg on android is still all software ( no gpu or Hardware accel ). IMO - android 上的 ffmpeg 仍然是所有软件(没有 gpu 或硬件加速)。 You could try looking thru libstagefright/ffmpeg combined questions .您可以尝试通过 libstagefright/ffmpeg 组合问题查看。 At any rate, if u are interest in fast, you should find a hardware accel solution on android.无论如何,如果你对快速感兴趣,你应该在 android 上找到一个硬件加速解决方案。 Otherwise ffmpeg on the constrained platform ( battery life, low power CPU ) is gonna be quite slow in compare to any other platform.否则,与任何其他平台相比,受限平台(电池寿命、低功耗 CPU)上的 ffmpeg 会非常慢。

also , see accepted answer here and this too另外,请在此处查看已接受的答案, 这也是

I gave up on android due to lack of speed and settled for a cloud instance to upload media to and then todo the ffmpeg encode there before download to the android device.由于速度不足,我放弃了 android,并选择了一个云实例来上传媒体,然后在下载到 android 设备之前在那里进行 ffmpeg 编码。 Would be interest to hear whether u get fast result on android.想知道您是否在 android 上获得快速结果。

BTW, i used the 2-pass H264 expression u see below before giving up on android for the encode.顺便说一句,在放弃 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;
}

You could try hardware encoder with recordvideo .您可以尝试使用recordvideo的硬件编码器。 You can download and compile the stagefright command-line tools even if you don't build the whole system.即使您不构建整个系统,也可以下载和编译 stagefright 命令行工具。 You will need the system libraries (from your device) to link.您将需要系统库(来自您的设备)进行链接。 The resulting executable will convert YUV buffer into mp4.生成的可执行文件会将 YUV 缓冲区转换为 mp4。 You still need to convert the series of JPEGs into a single YUV file.您仍然需要将一系列 JPEG 转换为单个 YUV 文件。 I think it will be fast enough with ffmpeg, but you can also use libjpeg-turbo for android .我认为使用 ffmpeg 会足够快,但您也可以将libjpeg-turbo 用于 android

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM