问题描述:本地有一个定时器,5秒执行一次;也就是说,每5秒截取一次图片;问题就出现在,当任务开始执行时,大概在1分半至2分半时,grabber.grabImage() 会出现null的问题;目前解决办法是,当grabber.grabImage()为 null 时, grabber.restart();可以解决问题,但是会少截取一张图片;有大神了解么?
/**
* @author deilsky
* @date 2021/11/29 15:11
* @description TODO
*/
@Component
public class RecordUtils {
public Logger logger = LoggerFactory.getLogger(getClass());
private ConcurrentMap<String, FFmpegFrameGrabber> grabberMap = new ConcurrentHashMap<>();
private FFmpegFrameGrabber addFrameGrabber(String key, String rtsp) {
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtsp);
grabber.setOption("rtsp_transport", "tcp");
grabber.setOption("stimeout", "2000000");
grabber.setOption("Connection","keep-alive");
grabber.setImageWidth(1024);
grabber.setImageHeight(768);
try {
grabber.startUnsafe(false);
grabberMap.put(key, grabber);
return grabber;
} catch (FFmpegFrameGrabber.Exception e) {
e.printStackTrace();
try {
grabber.stop();
} catch (FFmpegFrameGrabber.Exception ex) {
ex.printStackTrace();
}
grabberMap.remove(key);
}
return grabber;
}
private void delFrameGrabber(String key) {
FFmpegFrameGrabber grabber = grabberMap.get(key);
boolean exists = null != grabber;
if (exists) {
try {
grabber.stop();
} catch (FFmpegFrameGrabber.Exception e) {
e.printStackTrace();
}
grabberMap.remove(key);
}
}
private FFmpegFrameGrabber getFrameGrabber(String key, String rtsp) {
FFmpegFrameGrabber grabber = grabberMap.get(key);
boolean exists = null == grabber;
logger.info("grabber is null {}", exists);
if (exists) {
grabber = addFrameGrabber(key, rtsp);
}
return grabber;
}
public void frameRecordBase64(String rtsp, String dir, String key, RecordListener listener) throws Exception {
BasicThreadFactory threadFactory = new BasicThreadFactory.Builder()
.namingPattern("example-schedule-pool-%d")
.daemon(true)
.build();
ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(5, threadFactory);
FFmpegFrameGrabber.tryLoad();
executor.submit(() -> {
FFmpegFrameGrabber grabber = getFrameGrabber(key, rtsp);
try {
//frameGrabbed;
Frame frame = grabber.grabImage();
boolean frameIsNull = null != frame;
logger.info("frame isn't null {}", frameIsNull);
if (!frameIsNull) {
grabber.restart();
//frame为null时,grabber重新开始;可以正常截图,但是会少截取一张图
//delFrameGrabber(key);
} else {
String format = "png";
String pix = String.format("%d*%d", frame.imageWidth, frame.imageHeight);
int bitDepth = frame.imageDepth;
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bi = converter.convert(frame);
boolean bufferedImageIsNull = null != bi;
logger.info("BufferedImage isn't null {}", bufferedImageIsNull);
if (bufferedImageIsNull) {
File fileDir = new File(dir);
boolean existDir = fileDir.exists();
boolean isDir = fileDir.isDirectory();
if (!existDir || !isDir) {
fileDir.mkdirs();
}
String date = DateFormatUtils.format(new Date(Instant.now().toEpochMilli()), "HH_mm_ss");
String fileName = String.format("%s.png", date);
logger.info("file:{}", fileDir);
File file = new File(fileDir, fileName);
if (!file.exists()) {
file.createNewFile();
}
ImageIO.write(bi, "png", file);
stream.close();
frame.close();
}
}
} catch (FFmpegFrameGrabber.Exception e) {
logger.error("ERROR:grabber.grabImage:error");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
}
}