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