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

5
我有30张分辨率为480 x 640的JPEG图像(.jpg)。 每张图像大约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命令,也不知道需要使用哪些参数,这就是我在这里发帖问问题的原因。

视频质量需要好,但没有必要完美。

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

回复1(给Robert Rowntree):

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;

我需要一个快速的解决方案。视频质量并不是很重要。谢谢。 - Paul
3个回答

0

在安卓上,IMO-ffmpeg仍然是全软件(没有GPU或硬件加速)。您可以尝试查看libstagefright/ffmpeg的组合问题。无论如何,如果您想要快速处理,您应该在安卓上找到一个硬件加速解决方案。否则,在受限平台(电池寿命、低功耗CPU)上使用ffmpeg会比其他任何平台都慢。

此外,请参见已接受的答案这里这个

由于速度不够快,我放弃了安卓,并选择了云实例来上传媒体文件,然后在下载到安卓设备之前进行ffmpeg编码。很有兴趣听听您在安卓上是否获得了快速结果。

顺便说一下,在放弃安卓之前,我使用了下面所见的两遍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;
}

嗨。感谢您的回答。我将在几个小时内尝试您的版本。请问您尝试编码了多少帧并使用上述命令需要多长时间? - Paul
我认为在安卓上大约只有4帧每秒的速度...如果要使安卓成为混合视频的值得平台,需要将速度提高到至少25帧每秒。 - Robert Rowntree
使用-r 1/2的10秒声音输入,如果在Android上处理,则需要超过1分钟的时间,而在云端Heroku实例上混合大约只需要4秒钟。 - Robert Rowntree
嗨,我尝试了你的代码,但编码永远不会结束...我认为它一直重复我拥有的帧...无论如何,我不能使用你写的确切命令 - 我已经更新了我的问题,并附上了我使用的命令。很多参数对我来说都是未知的... - Paul
我使用了“循环(loop)”和“持续时间(duration)”参数结合的方式进行处理,这是一种不同的处理方式。 - Robert Rowntree
显示剩余2条评论

0

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


感谢您的回复和提供的链接。不幸的是,目前我需要使用ffmpeg...也许将来我会尝试您的建议,并告诉您结果。谢谢。 - Paul
编译FFmpeg以使用Stagefright?或者使用多线程x264呢? - Alex Cohn
硬件编з ҒеҷЁеңЁS3дёҠеҸҜд»ҘиҫҫеҲ°жҜҸз§’60дёӘVGAеё§пјҢ2дёӘзәҝзЁӢзҡ„иҪҜ件编з ҒеҷЁеҸҜд»ҘиҫҫеҲ°30её§гҖӮжҲ‘дёҚзҹҘйҒ“FFMPEGзҡ„JPEGи§Јз ҒеҷЁйңҖиҰҒеӨҡе°‘ж—¶й—ҙгҖӮ - Alex Cohn
我需要一个紧急、快速的解决方案。 - Paul

0
如何考虑去掉“-r 1/5”?这加速了我的编码过程。

是的,看起来我不需要第一个-r,因为它用于强制输入文件的帧速率(仅适用于原始格式),而我有jpecg文件。 - Paul
我不确定如何使用第二个r(因为我需要为输出文件指定fps)以便每秒有5帧。我已经使用了1/02,但似乎视频中并没有包含所有帧,我不知道为什么...你有任何想法为什么会发生这种情况吗? - Paul
“-r 5” 不是使用所有输入帧每秒给你 5 帧吗? - av501

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接