繁体   English   中英

“ffmpeg”:java.io.IOException:error = 24,打开的文件过多

[英]“ffmpeg”: java.io.IOException: error=24, Too many open files

我正在使用ffmpeg生成预览,但是在我的程序执行过程中出现了这个错误:

“ffmpeg”:java.io.IOException:error = 24,打开的文件过多

有人知道如何解决或如何避免它?
我在使用ffmpeg的地方添加了一段代码:

    for (int j = 0; j < temp.length; j++) {
                                                if(j==2){
                                                    String preview = temp2[i] + temp[j] +".jpg";
                                                    Process p = Runtime.getRuntime().exec("ffmpeg -i anotados/" +temp2[i] + " -r 1 -ss 00:00:"+temp[j]+" -t 1 -s 158x116 imagenes/" + preview);

                                                    TextOut.write(preview+"\n");
                                                }
 }

检查ulimit -n输出以查看允许从该shell生成的打开文件进程数。 历史Unix系统限制为20个文件,但我的Ubuntu桌面默认为1024个打开的文件。

您可能需要在/etc/security/limits.conf文件中增加允许的打开文件数。 或者,您可能需要修改应用程序以更积极地关闭打开的文件。

另一种可能性是对可能打开的文件数量的系统范围限制。 我不知道哪些现代系统仍然有这样的限制,但首先要看的是sysctl -a输出。 (好吧,也许是系统文档之后的第二名 。)

请注意,每次调用Runtime.exec都会生成一个并行运行的新进程。 你确定要像循环一样快地生成进程吗? 您可能希望int exitValue = p.waitFor()等待进程完成。 如果您需要一些并发性,我建议使用java.util.concurrent.ThreadPoolExecutor安排任务。

例如,没有太多错误检查,如下所示:

final ExecutorService executor = Executors.newFixedThreadPool(2);

for (int j = 0; j < temp.length; j++) {
    if(j==2) {
        final String preview = temp2[i] + temp[j] +".jpg";
        final String ffmpegPreviewCommand = "ffmpeg -i anotados/" +temp2[i] + " -r 1 -ss 00:00:"+temp[j]+" -t 1 -s 158x116 imagenes/" + preview;

        executor.submit(new Callable() {
            @Override
            public Object call() throws Exception {
                final Process p = Runtime.getRuntime().exec(ffmpegPreviewCommand);
                final int exitValue = p.waitFor();
                //TODO Check ffmpeg's exit value.

                TextOut.write(preview+"\n");
            }
        });
}

// This waits for all scheduled tasks to be executed and terminates the executor.
executor.shutdown();

}

查看java.util.concurrent.Executors以选择适合您需求的执行程序。

进程有一个方法: destroy()
尝试在最后添加它。

每次使用Runtime ,它都会打开stdoutstderrstdin 完成exec()请确保关闭这些流。 就像是

    if(j==2){
       String preview = temp2[i] + temp[j] +".jpg";
       Process p = Runtime.getRuntime().exec("ffmpeg -i anotados/" +temp2[i] + " -r 1 -ss      00:00:"+temp[j]+" -t 1 -s 158x116 imagenes/" + preview);
       TextOut.write(preview+"\n");

       //try this here 
       //add exception handling if necessary
       InputStream is = p.getInputStream();
       InputStream es = p.getErrorStream();
       OutputStream os = p.getOutputStream();
       is.close();
       es.close();
       os.close();
}

暂无
暂无

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

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