Table of contents
- need
- Execute ffmpeg commands across platforms based on JavaCV[^1]
- Pit 1 Insufficient memory
- Pit 2 Multiple ffmpeg processes in parallel lead to heavy IO load, which in turn leads to io error?
- Pit 3 When using Java to operate ffmpeg, it sometimes gets stuck
- Pit 4 Process's waitFor deadlock problem and solution
need
Automatically superimpose a background image on a video with a transparent background
Execute ffmpeg command 1 based on JavaCV cross-platform
The minimum dependency of this requirement found by my test:
<!-- Optional GPL builds with (almost) everything enabled -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform-gpl</artifactId>
<version>5.0-1.5.7</version>
</dependency>
Core code:
String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
String tempFilePath = newVideoName;
ProcessBuilder pb = new ProcessBuilder(ffmpeg,
"-y", "-i", BACKGROUND_PNG, "-c:v", "libvpx-vp9", "-i", aliVideoUrl, "-filter_complex",
"[0][1]overlay=0:0[video2];[video2]select=between(n\\,1\\,54000)", "-b:v", "2m", "-r",
"30", "-c:v", "libx264", "-pix_fmt", "yuv420p", "-profile:v", "high", "-preset:v",
"veryslow", "-tune", "film", "-level", "4.2", tempFilePath);
pb.inheritIO().start().waitFor();
File tempFile = new File(tempFilePath);
Pit 1 Insufficient memory
Insufficient memory of the server caused the actual failure of compositing videos. Many composite files are only 48B, but there is no error log related to them.
Each server node originally only had 2G memory, which was resolved after capacity expansion.
Pit 2 Multiple ffmpeg processes in parallel lead to heavy IO load, which in turn leads to io error?
This is just speculation. The phenomenon is that I will have multiple Java threads, and each thread will call the ffmpeg command. There is a probability that the synthesized video is missing the latter part, and io error, read error can be observed in the log. The larger the source video and the higher the number of Java threads, the greater the probability of this happening. When I change the Java program to single thread, there is no such problem. But when I tried to use the iostat command to observe the IO status of the server node, I did not observe evidence of the so-called heavy IO load. 2
Pit 3 When using Java to operate ffmpeg, it sometimes gets stuck
It only happens on my local Mac, not on the server. I searched for the reason for a long time, and finally found that my Mac automatically hibernated after running for a period of time. . But also record this pit that many people have encountered:
Pit 4 Process's waitFor deadlock problem and solution
The general idea is: when the Runtime object calls exec (cmd), the JVM will start a child process, which will establish three pipeline connections with the JVM process: standard input, standard output and standard error stream. Assuming that the program is constantly writing data to the standard output stream and standard error stream, and the JVM does not read it, it will not be able to continue writing data when the buffer is full, and Java's waitfor() is blocked waiting for the child process to complete. So it will eventually cause blocking in waitfor(). The main solution is that Java should consume the io stream of this buffer in time, or directly prevent ffmpeg from outputting logs. Some references:
As mentioned in the Java process.waitFor() stuck problem-loglevel quiet
, you can also directly add parameters to the ffmpeg command to prevent the output log.
Process's waitFor deadlock problem and solution