From 0f9ecda1919beb1e8fbbca0f669ac86badf70806 Mon Sep 17 00:00:00 2001 From: Pu Zhibing <393733352@qq.com> Date: 星期四, 10 四月 2025 14:47:42 +0800 Subject: [PATCH] 优化推流和拉流功能及关闭逻辑 --- ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java | 103 +++++++++++++++++++++++++++------------------------ 1 files changed, 54 insertions(+), 49 deletions(-) diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java index 1ad357d..58728c7 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/util/JavaCVStreamUtil.java @@ -1,5 +1,7 @@ package com.ruoyi.system.util; +import cn.hutool.core.io.FileUtil; +import com.ruoyi.common.core.utils.StringUtils; import org.bytedeco.ffmpeg.global.avcodec; import org.bytedeco.ffmpeg.global.avutil; import org.bytedeco.javacv.*; @@ -17,6 +19,8 @@ private static Map<Integer, FFmpegFrameGrabber> grabberMap = new ConcurrentHashMap<>(); + private static Map<Integer, OpenCVFrameGrabber> grabberMap1 = new ConcurrentHashMap<>(); + private static Map<Integer, FFmpegFrameRecorder> frameRecorderMap = new ConcurrentHashMap<>(); private static Map<Integer, Boolean> statusMap = new ConcurrentHashMap<>(); @@ -27,14 +31,18 @@ * 视频拉流和推流 */ public static void push_flv(String inputUrl, String outputUrl, Integer deviceNumber){ -// OpenCVFrameGrabber grabber = null; - FFmpegFrameGrabber grabber = null; + OpenCVFrameGrabber grabber = null; +// FFmpegFrameGrabber grabber = null; FFmpegFrameRecorder recorder = null; try { //关闭上一个没有正确关闭的流 FFmpegFrameGrabber fFmpegFrameGrabber = grabberMap.get(deviceNumber); if(null != fFmpegFrameGrabber){ fFmpegFrameGrabber.close(); + } + OpenCVFrameGrabber openCVFrameGrabber = grabberMap1.get(deviceNumber); + if(null != openCVFrameGrabber){ + openCVFrameGrabber.close();; } FFmpegFrameRecorder fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); if(null != fFmpegFrameRecorder){ @@ -46,15 +54,16 @@ FFmpegLogCallback.set(); //视频抓帧 - grabber = new FFmpegFrameGrabber(inputUrl); - grabber.setOption("rtsp_transport", "tcp"); - // 正确设置超时时间 - grabber.setOption("timeout", "120000"); - grabber.start(); - grabberMap.put(deviceNumber, grabber); - -// grabber = new OpenCVFrameGrabber(0); +// grabber = new FFmpegFrameGrabber(inputUrl); +// grabber.setOption("rtsp_transport", "tcp"); +// // 正确设置超时时间 +// grabber.setOption("timeout", "120000"); // grabber.start(); +// grabberMap.put(deviceNumber, grabber); + + grabber = new OpenCVFrameGrabber(0); + grabber.start(); + grabberMap1.put(deviceNumber, grabber); //录制视频,推送到流媒体服务器(nginx) recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight()); @@ -69,33 +78,31 @@ recorder.setAudioOption("crf", "23"); //设置音频编码为AAC -// if (grabber.getAudioChannels() > 0) { + if (grabber.getAudioChannels() > 0) { recorder.setAudioChannels(grabber.getAudioChannels()); recorder.setAudioBitrate(grabber.getAudioBitrate()); recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); -// } + } recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //将解码后的帧记录到输出文件中 //recorder.start通常用于处理已经解码成图像的视频数据 recorder.start(); + frameRecorderMap.put(deviceNumber, recorder); + //设置状态为开始 + statusMap.put(deviceNumber, true); + Frame frame; while ((frame = grabber.grab()) != null) { recorder.record(frame); + //判断状态为停止,则结束此线程任务 + if(!statusMap.get(deviceNumber)){ + break; + } } } catch (FrameGrabber.Exception | FrameRecorder.Exception e) { e.printStackTrace(); }finally { - try { - statusMap.put(deviceNumber, false); - if(null != grabber){ - grabber.stop(); - } - if(null != recorder){ - recorder.stop(); - } - }catch (Exception e){ - e.printStackTrace(); - } + close(deviceNumber, null); } } @@ -103,7 +110,7 @@ /** * 视频拉流和推流 */ - public static void push_hls(String inputUrl, String outputUrl, Integer deviceNumber){ + public static void push_hls(String inputUrl, String outputUrl, Integer deviceNumber, String folderPath){ OpenCVFrameGrabber grabber = null; // FFmpegFrameGrabber grabber = null; FFmpegFrameRecorder recorder = null; @@ -113,6 +120,10 @@ FFmpegFrameGrabber fFmpegFrameGrabber = grabberMap.get(deviceNumber); if(null != fFmpegFrameGrabber){ fFmpegFrameGrabber.close(); + } + OpenCVFrameGrabber openCVFrameGrabber = grabberMap1.get(deviceNumber); + if(null != openCVFrameGrabber){ + openCVFrameGrabber.close();; } FFmpegFrameRecorder fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); if(null != fFmpegFrameRecorder){ @@ -133,6 +144,7 @@ grabber = new OpenCVFrameGrabber(0); grabber.start(); + grabberMap1.put(deviceNumber, grabber); //录制视频,推送到流媒体服务器(nginx) recorder = new FFmpegFrameRecorder(outputUrl, grabber.getImageWidth(), grabber.getImageHeight()); @@ -189,17 +201,7 @@ } catch (FrameGrabber.Exception | FrameRecorder.Exception e) { e.printStackTrace(); }finally { - try { - statusMap.put(deviceNumber, false); - if(null != grabber){ - grabber.stop(); - } - if(null != recorder){ - recorder.stop(); - } - }catch (Exception e){ - e.printStackTrace(); - } + close(deviceNumber, folderPath); } } @@ -208,35 +210,38 @@ * 关闭推流和拉流进程 * @param deviceNumber */ - public static void close(Integer deviceNumber){ + public static void close(Integer deviceNumber, String folderPath){ //设置状态为停止 + Boolean status = statusMap.get(deviceNumber); + if(null == status || !status){ + return; + } statusMap.put(deviceNumber, false); FFmpegFrameGrabber fFmpegFrameGrabber = null; + OpenCVFrameGrabber openCVFrameGrabber = null; FFmpegFrameRecorder fFmpegFrameRecorder = null; try { fFmpegFrameGrabber = grabberMap.get(deviceNumber); if(null != fFmpegFrameGrabber){ + fFmpegFrameGrabber.flush(); fFmpegFrameGrabber.close(); + } + openCVFrameGrabber = grabberMap1.get(deviceNumber); + if(null != openCVFrameGrabber){ + openCVFrameGrabber.flush(); + openCVFrameGrabber.close(); } fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); if(null != fFmpegFrameRecorder){ + fFmpegFrameRecorder.flush(); fFmpegFrameRecorder.close(); } }catch (Exception e){ e.printStackTrace(); - }finally { - try { - fFmpegFrameGrabber = grabberMap.get(deviceNumber); - if(null != fFmpegFrameGrabber){ - fFmpegFrameGrabber.close(); - } - fFmpegFrameRecorder = frameRecorderMap.get(deviceNumber); - if(null != fFmpegFrameRecorder){ - fFmpegFrameRecorder.close(); - } - }catch (Exception e){ - e.printStackTrace(); - } + } + //开始清除视频文件 + if(StringUtils.isNotEmpty(folderPath)){ + FileUtil.del(folderPath); } } } -- Gitblit v1.7.1