问题:FFmpegFrameGrabber.grabImage()为null

问题描述:本地有一个定时器,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();
            }
        });
    }
}

上一篇:牛客链表题目


下一篇:WPF实现-自定义图片按钮控件