javacv
javacv copied to clipboard
FFmpegFrameGrabber.grabFrame,AVPacket.stream_index,Lock
Hi everyone,I'm having an unsolvable problem when trying to take a screenshot of a video
The version number I use : 1.5.6
my code
private static void cutOutFirstOfVideo(String path,File targetFile) throws FrameGrabber.Exception {
StopWatch stopWatch = new StopWatch("javacv-screenshot");
stopWatch.start();
FFmpegFrameGrabber ff = FFmpegFrameGrabber.createDefault(path);
OpenCVFrameConverter.ToIplImage converter = null;
IplImage src = null;
Frame f = null;
try{
ff.start();
int lenght = ff.getLengthInFrames();
int i = 0;
while (i < lenght) {
f = ff.grabFrame();
if ((i > 1) && (f.image != null)) {
f.close();
break;
}
i++;
f.close();
}
String rotate =ff.getVideoMetadata("rotate");
f =ff.grabImage();
if(null != rotate && rotate.length() > 1) {
converter = new OpenCVFrameConverter.ToIplImage();
src = converter.convert(f);
f = converter.convert(rotate(src, Integer.parseInt(rotate)));
}
doExecuteFrame(f,targetFile);
} finally {
if(src != null){
src.close();
}
if(f != null){
f.close();
}
if(converter != null){
converter.close();
}
stopWatch.stop();
log.info("截图处理: javacv 截图结束 耗时={}毫秒",stopWatch.getTotalTimeMillis());
}
}
private static void doExecuteFrame(Frame f,File targetFile) {
if (null ==f || null ==f.image) {
return;
}
try (Java2DFrameConverter converter =new Java2DFrameConverter();
FileOutputStream fileOutputStream = new FileOutputStream(targetFile)){
BufferedImage buffImg =converter.getBufferedImage(f);
ImageIO.write(buffImg,FileSuffixConstant.JPEG,fileOutputStream);
buffImg.flush();
}catch (IOException e) {
log.error("视频保存失败",e);
throw new RuntimeException(e.getMessage(),e);
}
}
jstack
"pool-16-thread-3" #527 prio=5 os_prio=0 tid=0x00007fbe48058000 nid=0x232 runnable [0x00007fba7026c000]
java.lang.Thread.State: RUNNABLE
at org.bytedeco.ffmpeg.avcodec.AVPacket.stream_index(Native Method)
at org.bytedeco.javacv.FFmpegFrameGrabber.grabFrame(FFmpegFrameGrabber.java:1357)
- locked <0x00000004cb29e470> (a org.bytedeco.javacv.FFmpegFrameGrabber)
at org.bytedeco.javacv.FFmpegFrameGrabber.grabImage(FFmpegFrameGrabber.java:1283)
at com.fcbox.vas.dispatch.util.JavacvUtil.cutOutFirstOfVideo(JavacvUtil.java:82)
at com.fcbox.vas.dispatch.util.JavacvUtil.cutOutFirstOfVideo(JavacvUtil.java:43)
at com.fcbox.vas.dispatch.util.VideoUtil.cutPicture(VideoUtil.java:67)
at com.fcbox.vas.dispatch.task.handle.ScreenshotHandle.transFileAndCutPicture(ScreenshotHandle.java:182)
at com.fcbox.vas.dispatch.task.handle.ScreenshotHandle.run(ScreenshotHandle.java:139)
at com.fcbox.vas.dispatch.task.handle.ScreenshotHandle.lambda$handle$20(ScreenshotHandle.java:103)
at com.fcbox.vas.dispatch.task.handle.ScreenshotHandle$$Lambda$1071/1600206385.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
It's been stuck here for more than 5 hours,no sign of release. Seems to be stuck somewhere in FFmpegFrameGrabber.grabFrame、AVPacket.stream_index.
It should be noted that this method I will use in multi-threading
This happens occasionally, and it can't be fixed. This has caused me a lot of trouble. What can I do to fix it?
There's nothing related to FFmpeg in AVPacket.stream_index() than can block, it's just literally return stream_index
. What is causing this issue is thus JNI and something in the JVM. You'll need to figure out what that is, but it's unrelated to JavaCV, JavaCPP, or FFmpeg.
Thank you very much, I found the problem, because the network is unstable, the URL has been blocked, maybe I need to add a timeout mechanism
Thank you very much, I found the problem, because the network is unstable, the URL has been blocked, maybe I need to add a timeout mechanism
how do you resolve it,i found the same problem,grabber.grabFrame() gets stuck for a long time。