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.