简体   繁体   中英

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

I am working with ffmpeg to generate previews, but I get this error in the middle of the execution of my program:

"ffmpeg": java.io.IOException: error=24, Too many open files

Does anybody know how to solve or how to avoid it??
I add the piece of code where I use 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");
                                                }
 }

Check your ulimit -n output to see how many open files processes spawned from that shell are allowed to have. Historical Unix systems had a limit of 20 files, but default on my Ubuntu desktop is 1024 open files.

You may need to raise the number of open files you are allowed in the /etc/security/limits.conf file. Or, you may need to modify your application to more aggressively close open files.

Another possibility is a system-wide limit on number of files that may be open. I don't know which modern systems would still have such limits in place, but a first place to look would be sysctl -a output. (Well, maybe second place, after system documentation.)

Note that each call to Runtime.exec will spawn a new process that's run in parallel. Are you sure you want to spawn processes as fast as the loop can go? You probably want to int exitValue = p.waitFor() to wait for the process to complete. If you need some concurrency, I'd recommend scheduling tasks using a java.util.concurrent.ThreadPoolExecutor .

For example, without much error checking, something like so:

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();

}

Look at java.util.concurrent.Executors to pick an executor that fits your needs.

Process has a method: destroy() .
Try to add it at end.

Every time Runtime is used, it opens stdout , stderr and stdin . Make sure you close these streams when you're done with exec() . Something like

    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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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