bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.45k stars 1.57k forks source link

I can't gracefully close ports opened by ffmpeg #2012

Open zhongshijie1995 opened 1 year ago

zhongshijie1995 commented 1 year ago

When I use this code, the video pull and recording can be done. But the launched UDP port is not closed unless I close the entire application. Is there anything unusual here?

        RecordSet.setIsRecording(recordReqId, true);
        executorService.execute(() -> {
            // 定义视频源
            FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(new ByteArrayInputStream(source.getBytes()), 0);
            grabber.setFormat("sdp");
            grabber.setOption("protocol_whitelist", "file,rtp,udp");
            // 定义输出源
            FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(target, 1280, 720, 1);
            try {
                log.info("录制进程开启...");
                // 打开视频源
                grabber.start();
                // 打开输出源
                recorder.start();
                // 取帧并录制
                Frame frame;
                while (RecordSet.getIsRecording(recordReqId)) {
                    frame = grabber.grabImage();
                    if (frame != null) {
                        recorder.record(frame);
                    }
                }
                // 停止视频源
                grabber.stop();
                // 停止输出源
                recorder.stop();
            } catch (Exception e) {
                e.printStackTrace();
                log.info("录制进程出现异常[{}]", e.toString());
            } finally {
                log.info("录制进程关闭开始...");
                try {
                    // 关闭视频源
                    grabber.release();
                    grabber.close();
                    // 关闭输出源
                    recorder.release();
                    recorder.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info("[重大错误]录制进程结束异常[{}]", e.toString());
                }
                // 回收端口
                RecordSet.freeUdpPortIsRecording(recordReqId);
                log.info("回收端口");
                // 回收录制状态字典
                RecordSet.freeIsRecording(recordReqId);
                log.info("回收录制状态字典");

                log.info("录制进程关闭完成!");
            }
        });
SDP:
v=0
o=- 0 0 IN IP4 0.0.0.0
c=IN IP4 0.0.0.0
t=0 0
m=video 20000 RTP/AVP 100
a=rtpmap:100 h264/90000
m=audio 20002 RTP/AVP 101
a=rtpmap:101 opus/48000/2
saudet commented 1 year ago

Sounds like a bug in FFmpeg? Could you try to ask upstream?

zhongshijie1995 commented 1 year ago

My understanding is that 'close' can shut down the 'ffmpeg' process, isn't it? @saudet