javacv FFmpegFrameGrabber 阻塞问题解决方法

<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.5.7</version>
</dependency>

修改org.bytedeco.javacv.FFmpegFrameGrabber.java源码  

//1、在createDefault方法后添加  以下代码
    /**
     * 读流超时时间 : 20秒
     */
    private static final int FRAME_READ_TIMEOUT = 20 * 1000;
    // 增加监听
    private final AtomicLong lastFrameTime = new AtomicLong(System.currentTimeMillis());
    private boolean interrupt_grab = false;

    public boolean isInterrupt_grab() {
        return interrupt_grab;
    }

    private final org.bytedeco.ffmpeg.avformat.AVIOInterruptCB.Callback_Pointer cp = new org.bytedeco.ffmpeg.avformat.AVIOInterruptCB.Callback_Pointer() {
        @Override
        public int call(Pointer pointer) {
            // 0:continue, 1:exit
            if (lastFrameTime.get() + FRAME_READ_TIMEOUT < System.currentTimeMillis()) {
                interrupt_grab = true;
                try {
                    // 读流时使用了Process p = Runtime.getRuntime().exec() ; 执行了ffmpeg命令
                    // p.waitFor(); 该方法使线程阻塞, 使用interrupt()取消/退出线程
                    Thread.currentThread().interrupt();
                 
                } catch (java.lang.Exception e) {
                    log.error("Thread interrupt", e);
                }
                return 1;
            }
            return 0;
        }
    };


//2、在startUnsafe()方法中
        //if ((ret = avformat_open_input(oc, filename, f, options)) < 0)  代码前 添加
        // 回调
        lastFrameTime.set(System.currentTimeMillis());
        oc = avformat_alloc_context();
        org.bytedeco.ffmpeg.avformat.AVIOInterruptCB cb = new org.bytedeco.ffmpeg.avformat.AVIOInterruptCB();
        cb.callback(cp);
        oc.interrupt_callback(cb);



//3、在grabFrame方法中if (oc == null || oc.isNull()) 判断结束后添加
        // 回调
        lastFrameTime.set(System.currentTimeMillis());


// 4 在使用FFmpegFrameGrabber读取帧时, isInterrupt_grab()进行退出循环
while (true) {
				frame = grabber.grab();
				if (grabber.isInterrupt_grab()) {
					log.info("grabber Interrupt_read");
					break;
				}
				if (frame.image != null) {
					log.info("处理逻辑......");
				} 
			}

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值